From 39331d5c51e288dc86479a17a53949f47a6e52c8 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Tue, 1 Sep 2026 12:11:37 +1000 Subject: [PATCH] Configuration options: add --enable-enterprise Add an enterprise option that includes all items that would be required. Update CMake build to match autotools. Added enterprise option. Added CI loops for configuration options. Add document that maps the OpenSSL configuration options to wolfSSL's. Checked against various versions of OpenSSL. --- .github/configs/enterprise.json | 24 ++ .github/scripts/cmake-config-defines.sh | 58 ++++ .github/workflows/enterprise.yml | 235 ++++++++++++++++ CMakeLists.txt | 235 +++++++++++++++- cmake/functions.cmake | 105 ++++++++ cmake/options.h.in | 68 +++++ configure.ac | 116 ++++++++ doc/OPENSSL_OPTION_MAPPING.md | 344 ++++++++++++++++++++++++ doc/include.am | 3 +- 9 files changed, 1184 insertions(+), 4 deletions(-) create mode 100644 .github/configs/enterprise.json create mode 100755 .github/scripts/cmake-config-defines.sh create mode 100644 .github/workflows/enterprise.yml create mode 100644 doc/OPENSSL_OPTION_MAPPING.md diff --git a/.github/configs/enterprise.json b/.github/configs/enterprise.json new file mode 100644 index 00000000000..223e59ed007 --- /dev/null +++ b/.github/configs/enterprise.json @@ -0,0 +1,24 @@ +[ +{"name": "enterprise", + "comment": "The bundle as shipped: --enable-all, all quantum crypto, old TLS, secure renegotiation, HPKE, AES-CTS/GCM-SIV, acert, TSP, S/MIME, OPENSSL_COMPATIBLE_DEFAULTS and the system crypto-policy reader.", + "configure": ["--enable-enterprise"]}, +{"name": "enterprise-no-all-osp", + "comment": "Without the OSP bundles nothing else turns 3DES back on, so this is the only entry where the bundle's --disable-des3 takes effect.", + "configure": ["--enable-enterprise", "--disable-all-osp"]}, +{"name": "enterprise-no-oldtls", + "comment": "--disable-oldtls has to suppress the TLS 1.0 default the bundle would otherwise set, or TLS 1.0 pulls old TLS back on.", + "configure": ["--enable-enterprise", "--disable-oldtls"]}, +{"name": "enterprise-renegotiation-indication", + "comment": "Mutually exclusive with secure renegotiation; the bundle must not set both.", + "configure": ["--enable-enterprise", "--enable-renegotiation-indication"]}, +{"name": "enterprise-asn-original", + "comment": "Attribute certificates and TSP are only handled by the ASN.1 template code, so the bundle must leave both off here. Build only: --enable-all-quantum-crypto with --enable-asn=original fails PQ private-key decoding tests in make check independently of the enterprise bundle.", + "configure": ["--enable-enterprise", "--enable-asn=original"], + "check": false}, +{"name": "enterprise-no-openssl-compatible-defaults", + "comment": "Feature set without the OpenSSL run-time behaviour defaults.", + "configure": ["--enable-enterprise", + "--disable-openssl-compatible-defaults"]}, +{"name": "enterprise-smallstack", + "configure": ["--enable-enterprise", "--enable-smallstack"]} +] diff --git a/.github/scripts/cmake-config-defines.sh b/.github/scripts/cmake-config-defines.sh new file mode 100755 index 00000000000..90ce3d30eba --- /dev/null +++ b/.github/scripts/cmake-config-defines.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# Print the feature macros of a configured CMake build of wolfSSL, sorted, +# one per line. +# +# cmake-config-defines.sh lib BUILD_DIR -D flags the library compiles +# with +# cmake-config-defines.sh header BUILD_DIR #defines in wolfssl/options.h +# cmake-config-defines.sh names BUILD_DIR names of library defines that +# options.h does not export +# +# "lib" and "header" print whole definitions (name and value), so two build +# directories can be compared exactly. "names" is the check that every +# feature macro reaches applications: CMake applies WOLFSSL_DEFINITIONS to +# the library only, so a macro missing from cmake/options.h.in is silently +# absent from the generated header. Needs the Makefile generator (the +# default on Linux), which records the flags in flags.make. + +set -euo pipefail + +if [ $# -ne 2 ]; then + echo "usage: $0 lib|header|names BUILD_DIR" >&2 + exit 2 +fi +mode=$1 +dir=$2 + +# Build-only macros, not feature settings: they must not reach applications. +private='BUILDING_WOLFSSL|HAVE_CONFIG_H|WOLFSSL_DLL|wolfssl_EXPORTS' +private="$private|WOLFSSL_IGNORE_FILE_WARN" + +lib_defs() { + grep -h '^C_DEFINES' "$dir/CMakeFiles/wolfssl.dir/flags.make" | + tr ' ' '\n' | grep '^-D' | sed 's/^-D//' | LC_ALL=C sort -u +} + +header_defs() { + grep '^#define' "$dir/wolfssl/options.h" | sed 's/^#define //' | + LC_ALL=C sort -u +} + +case "$mode" in + lib) + lib_defs + ;; + header) + header_defs + ;; + names) + LC_ALL=C comm -23 \ + <(lib_defs | sed 's/=.*//' | LC_ALL=C sort -u) \ + <(header_defs | sed 's/[ =].*//' | LC_ALL=C sort -u) | + grep -v -x -E "$private" || true + ;; + *) + echo "unknown mode: $mode" >&2 + exit 2 + ;; +esac diff --git a/.github/workflows/enterprise.yml b/.github/workflows/enterprise.yml new file mode 100644 index 00000000000..e8a321a1556 --- /dev/null +++ b/.github/workflows/enterprise.yml @@ -0,0 +1,235 @@ +name: Enterprise Build Tests + +# START OF COMMON SECTION +on: + push: + branches: [ 'release/**' ] + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + branches: [ '*' ] + # Weekday-morning cron (10:00 UTC) seeds the master-scoped ccache that PR runs + # restore, by re-running --build-only (compile only, no tests) on the + # default branch. PR runs are read-only. + schedule: + - cron: '46 10 * * 1-5' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read +# END OF COMMON SECTION + +jobs: + # --enable-enterprise and the --disable-/--enable- overrides it has to + # yield to, through autotools. All configs build on one runner via + # .github/scripts/parallel-make-check.py (see os-check.yml for the full + # pattern): each config in its own out-of-tree ("VPATH") build directory + # off one checkout/autogen, checks on a pool of one-per-CPU worker + # threads, longest first. bubblewrap gives every test script its own + # network namespace so concurrent checks cannot collide on TCP/UDP ports + # (do not set AM_BWRAPPED here - that would disable it). + make_check: + name: make check + strategy: + fail-fast: false + matrix: + shard: [1, 2] + if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }} + runs-on: ubuntu-24.04 + # Generous for a cold ccache; warm reruns finish in a fraction. + timeout-minutes: 45 + steps: + - uses: actions/checkout@v5 + name: Checkout wolfSSL + + # tlslite-ng is consumed by scripts/multi-msg-record.test (run from + # `make check`); without it that test is SKIPped. + - uses: actions/setup-python@v6 + with: + python-version: '3.x' + - run: pip install tlslite-ng + + - name: Install dependencies + uses: ./.github/actions/install-apt-deps + with: + packages: autoconf automake libtool build-essential bubblewrap + ghcr-debs-tag: ubuntu-24.04-minimal + + # ccache via the cross-platform composite; the script passes the + # compiler to configure as CC="ccache gcc" (or a per-config "cc"). + - name: Set up ccache + uses: ./.github/actions/ccache-setup + with: + workflow-id: enterprise + config-hash: shard-${{ matrix.shard }} + max-size: 500M + # PRs read the cache the weekday seed writes; they never + # save, so PR runs add nothing to the Actions cache. + read-only: ${{ github.event_name == 'pull_request' }} + + # Ubuntu 24.04 can restrict unprivileged user namespaces via AppArmor, + # which would stop the test scripts from re-execing under + # bwrap --unshare-net (their port-isolation mechanism). + - name: Allow unprivileged user namespaces (for bwrap) + run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true + + # The config list lives in .github/configs/enterprise.json; add new + # configs there as new entries (a "comment" key is allowed for notes). + # "minutes" is the expected duration driving longest-first scheduling + # and shard balancing: take it from the Minutes column of a previous + # run's step summary (one whose ccache hit), or omit it for a new + # config (defaults to 1) and refresh later. + # --private-dir=certs gives every build dir its own certs/ copy: + # crl-gen-openssl.test writes generated CRLs under certs/crl/, which + # would race through the shared VPATH certs symlink. + - name: Build and make check this shard's configs (parallel, out-of-tree) + run: | + .github/scripts/parallel-make-check.py \ + ${{ github.event_name == 'schedule' && '--build-only' || '' }} \ + --shard "${{ matrix.shard }}/${{ strategy.job-total }}" \ + --cflags='-pedantic -Wdeclaration-after-statement -Wnull-dereference -Wno-overlength-strings -DTEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE' \ + --private-dir=certs \ + .github/configs/enterprise.json + + - name: ccache stats + if: always() + run: ccache -s || true + + - name: Upload logs on failure + if: failure() + uses: actions/upload-artifact@v6 + with: + retention-days: 7 + name: enterprise-logs-${{ matrix.shard }} + path: | + build-*/make-check.log + build-*/test-suite.log + build-*/config.log + if-no-files-found: ignore + + # -DWOLFSSL_ENTERPRISE=yes and the overrides it has to yield to, through + # CMake. The CMake bundle is a separate implementation of the configure.ac + # one (force_option()/default_option() cascade in CMakeLists.txt), so it + # gets its own build-and-ctest per variant rather than relying on the + # autotools job above. + cmake: + name: cmake (${{ matrix.name }}) + strategy: + fail-fast: false + matrix: + include: + - name: enterprise + options: '' + # TLS 1.0 pulls old TLS back on, so -DWOLFSSL_OLD_TLS=no has to + # suppress the bundle's TLS 1.0 default as well. + - name: no-old-tls + options: '-DWOLFSSL_OLD_TLS=no' + # Without the OSP bundles nothing turns 3DES back on, so the + # bundle's DES3 exclusion takes effect, and nothing else supplies + # the OPENSSL_COMPATIBLE_DEFAULTS companion defines. + - name: no-all-osp + options: '-DWOLFSSL_ALL_OSP=no' + # Mutually exclusive with secure renegotiation, which the bundle + # must then leave off. + - name: renegotiation-indication + options: '-DWOLFSSL_RENEGOTIATION_INDICATION=yes' + if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }} + runs-on: ubuntu-24.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v5 + name: Checkout wolfSSL + + - name: Install dependencies + uses: ./.github/actions/install-apt-deps + with: + packages: cmake build-essential + ghcr-debs-tag: ubuntu-24.04-full + + # ccache-setup puts its compiler symlinks first on PATH, so CMake's + # compiler detection picks up the ccache-wrapped gcc unchanged. + - name: Set up ccache + uses: ./.github/actions/ccache-setup + with: + workflow-id: enterprise-cmake + config-hash: ${{ matrix.name }} + max-size: 200M + read-only: ${{ github.event_name == 'pull_request' }} + + - name: Configure + run: | + cmake -B build -DWOLFSSL_ENTERPRISE=yes ${{ matrix.options }} + + # Applications only see what wolfssl/options.h defines: a bundle + # define without a cmake/options.h.in entry changes the library's + # structure layouts behind their back. + - name: Check options.h exports every library define + run: | + missing=$(.github/scripts/cmake-config-defines.sh names build) + if [ -n "$missing" ]; then + echo "::error::Not exported by cmake/options.h.in:" $missing + exit 1 + fi + + - name: Build + run: cmake --build build -j "$(nproc)" + + - name: Test + if: ${{ github.event_name != 'schedule' }} + working-directory: build + run: ctest -j "$(nproc)" --output-on-failure + + - name: ccache stats + if: always() + run: ccache -s || true + + # Re-running CMake in an existing build directory must give the same + # configuration as a fresh one: option values an earlier configure chose + # are recomputed (wolfssl_forget_auto_options()), while values the user + # set are kept. Configure only - nothing is built. + cmake_reconfigure: + name: cmake reconfigure + if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }} + runs-on: ubuntu-24.04 + timeout-minutes: 10 + steps: + - uses: actions/checkout@v5 + name: Checkout wolfSSL + + - name: Install dependencies + uses: ./.github/actions/install-apt-deps + with: + packages: cmake build-essential + ghcr-debs-tag: ubuntu-24.04-full + + # Each case configures with FIRST, re-runs in the same directory with + # SECOND, and compares the result with a fresh configure of EXPECTED + # (SECOND, unless a user value from FIRST is meant to carry over). + - name: Compare re-runs with fresh configures + run: | + defs=.github/scripts/cmake-config-defines.sh + fail=0 + check() { + local name=$1 first=$2 second=$3 expected=$4 + cmake -B "rerun-$name" $first > /dev/null + cmake -B "rerun-$name" $second > /dev/null + cmake -B "fresh-$name" $expected > /dev/null + for kind in lib header; do + if ! diff <($defs $kind "fresh-$name") \ + <($defs $kind "rerun-$name"); then + echo "::error::$name: re-run $kind defines differ" + fail=1 + fi + done + } + ent="-DWOLFSSL_ENTERPRISE=yes" + check enable "" "$ent" "$ent" + check disable "$ent" "-DWOLFSSL_ENTERPRISE=no" "" + check keep-user "$ent -DWOLFSSL_SMIME=no" "" \ + "$ent -DWOLFSSL_SMIME=no" + check add-user "$ent" "$ent -DWOLFSSL_SMIME=no" \ + "$ent -DWOLFSSL_SMIME=no" + check app-bundle "-DWOLFSSL_QUIC=yes" "-DWOLFSSL_QUIC=no" "" + exit $fail diff --git a/CMakeLists.txt b/CMakeLists.txt index f5386bb0a33..4cac3f5416e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,8 @@ set(PC_LIBS_PRIVATE "") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/") include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/functions.cmake) +# Recompute, rather than reuse, option values an earlier configure chose. +wolfssl_forget_auto_options() #################################################### # Compiler @@ -255,13 +257,206 @@ endif() # - Distro # - Linux Kernel Module # - Single precision math -# - Enable all -# - Enable all crypto # For reproducible build, gate out from the build anything that might # introduce semantically frivolous jitter, maximizing chance of # identical object files. +#################################################### +# Feature bundles (parity with configure.ac) +#################################################### +# WOLFSSL_ENTERPRISE, WOLFSSL_ALL, WOLFSSL_ALL_CRYPTO, +# WOLFSSL_ALL_QUANTUM_CRYPTO and WOLFSSL_ALL_OSP mirror the configure.ac +# options of the same names. +# +# Two ordering rules make this work, and both are why the section sits +# here rather than beside the features it turns on: +# +# * A bundle records its choices with force_option(), and add_option() +# consumes that record when the option is declared. So a bundle has +# to run ahead of every add_option() it targets -- ahead of the +# application bundles below, and ahead of the feature options. +# * The bundles cascade outermost first (enterprise -> all -> all-crypto +# / all-osp / all-quantum-crypto), and default_option() keeps the +# first choice recorded for any one option. An outer bundle's +# deliberate exclusion therefore survives an inner bundle's default, +# which is how the matching `test "$enable_x" = ""` guards behave in +# configure.ac. + +add_option(WOLFSSL_ENTERPRISE + "Enable maximum interoperability feature set, comparable to a default OpenSSL build (default: disabled)" + "no" "yes;no") + +if(WOLFSSL_ENTERPRISE) + default_option(WOLFSSL_ALL "yes") + default_option(WOLFSSL_ALL_QUANTUM_CRYPTO "yes") + + # RC2, 3DES and SAKKE are the deliberate departures from OpenSSL + # parity. Recorded before WOLFSSL_ALL_CRYPTO runs so they stand. + default_option(WOLFSSL_RC2 "no") + default_option(WOLFSSL_DES3 "no") + default_option(WOLFSSL_SAKKE "no") + + # OpenSSL still compiles TLS 1.0/1.1 in; it refuses them at run time + # through the security level, which wolfSSL has no equivalent of. + # TLS 1.0 pulls old TLS back on, so -DWOLFSSL_OLD_TLS=no has to + # suppress both of these to mean anything. + wolfssl_option_user_off(WOLFSSL_OLD_TLS _wolfssl_no_old_tls) + if(NOT _wolfssl_no_old_tls) + default_option(WOLFSSL_TLSV10 "yes") + endif() + default_option(WOLFSSL_OLD_TLS "yes") + + # configure.ac emits these next to the old-TLS version strings for the + # OpenSSL compatibility layer; they are consumed by applications, not by + # wolfSSL itself. + if(NOT _wolfssl_no_old_tls) + list(APPEND WOLFSSL_DEFINITIONS "-DSSL_TXT_TLSV1" "-DSSL_TXT_TLSV1_1") + endif() + + # RFC 5746 renegotiation. The two renegotiation options are mutually + # exclusive, so renegotiation indication wins when the user asks for it. + if(NOT WOLFSSL_RENEGOTIATION_INDICATION) + default_option(WOLFSSL_SECURE_RENEGOTIATION "yes") + endif() + default_option(WOLFSSL_KEYING_MATERIAL "yes") + default_option(WOLFSSL_HPKE "yes") + + # AES-CTS and AES-GCM-SIV are built on CBC and GCM; leave them off when + # the user has turned the base mode off. + wolfssl_option_user_off(WOLFSSL_AESCBC _wolfssl_no_aescbc) + if(NOT _wolfssl_no_aescbc) + default_option(WOLFSSL_AESCTS "yes") + endif() + wolfssl_option_user_off(WOLFSSL_AESGCM _wolfssl_no_aesgcm) + if(NOT _wolfssl_no_aesgcm) + default_option(WOLFSSL_AESGCMSIV "yes") + endif() + default_option(WOLFSSL_SMIME "yes") + default_option(WOLFSSL_TSP "yes") + + # No CMake option covers these yet; emit the macros directly, the way + # the application bundles below do for the same reason. + list(APPEND WOLFSSL_DEFINITIONS + "-DWOLFSSL_ACERT" + "-DWOLFSSL_ALLOW_LEGACY_SERVER_CONNECT" + "-DOPENSSL_COMPATIBLE_DEFAULTS") + + # The system-wide crypto-policy reader: the nearest thing wolfSSL has + # to OpenSSL's security level and openssl.cnf. Compiling it in only + # exposes the wolfSSL_crypto_policy_*() API and bakes in the default + # path -- nothing is read until the application asks for it. + if(NOT DEFINED WOLFSSL_SYS_CRYPTO_POLICY_FILE) + set(WOLFSSL_SYS_CRYPTO_POLICY_FILE + "/etc/crypto-policies/back-ends/wolfssl.config") + endif() + list(APPEND WOLFSSL_DEFINITIONS + "-DWOLFSSL_SYS_CRYPTO_POLICY" + "-DWOLFSSL_CRYPTO_POLICY_FILE=\"${WOLFSSL_SYS_CRYPTO_POLICY_FILE}\"") +endif() + +add_option(WOLFSSL_ALL + "Enable all wolfSSL features, except SSLv3 (default: disabled)" + "no" "yes;no") + +if(WOLFSSL_ALL) + default_option(WOLFSSL_ALL_CRYPTO "yes") + default_option(WOLFSSL_ALL_OSP "yes") + + # WOLFSSL_HPKE is not in configure.ac's --enable-all list: it arrives + # there because --enable-ech implies it. CMake's ECH has no such + # implication and hard-errors without it, so name it explicitly. + foreach(_o + WOLFSSL_HPKE + WOLFSSL_ALPN WOLFSSL_CRL_MONITOR WOLFSSL_DTLS WOLFSSL_DTLS13 + WOLFSSL_DTLS_CH_FRAG WOLFSSL_DTLS_MTU WOLFSSL_DTLS_CID WOLFSSL_EARLYDATA + WOLFSSL_ECH WOLFSSL_HRR_COOKIE WOLFSSL_MCAST WOLFSSL_OCSP + WOLFSSL_OCSPSTAPLING WOLFSSL_OCSPSTAPLING_V2 WOLFSSL_OPENSSLALL + WOLFSSL_OPENSSLEXTRA WOLFSSL_POSTAUTH WOLFSSL_QUIC WOLFSSL_SAVECERT + WOLFSSL_SAVESESSION WOLFSSL_SCEP WOLFSSL_SESSION_TICKET WOLFSSL_SNI + WOLFSSL_SRTP WOLFSSL_TLS13) + default_option(${_o} "yes") + endforeach() + + # TLS extensions and certificate handling that have no CMake option. + list(APPEND WOLFSSL_DEFINITIONS + "-DHAVE_TLS_EXTENSIONS" "-DHAVE_MAX_FRAGMENT" "-DHAVE_TRUNCATED_HMAC" + "-DHAVE_TRUSTED_CA" "-DHAVE_RPK" "-DHAVE_CRL_IO" "-DHAVE_IO_TIMEOUT" + "-DWOLFSSL_DER_LOAD" "-DKEEP_OUR_CERT" "-DKEEP_PEER_CERT" + "-DWOLFSSL_SUBJ_DIR_ATTR" "-DWOLFSSL_FPKI" "-DWOLFSSL_SUBJ_INFO_ACC" + "-DWOLFSSL_CERT_NAME_ALL" "-DWOLFSSL_VERBOSE_ERRORS" + "-DWOLFSSL_HAVE_CERT_SERVICE" "-DHAVE_OCSP_RESPONDER" + "-DWOLFSSL_TLS_OCSP_MULTI") + + # configure.ac derives this from session tickets under TLS 1.3; CMake's + # option is explicit, so name it. + default_option(WOLFSSL_TICKET_NONCE_MALLOC "yes") +endif() + +add_option(WOLFSSL_ALL_CRYPTO + "Enable all wolfCrypt algorithms except quantum-resistant asymmetric (default: disabled)" + "no" "yes;no") + +if(WOLFSSL_ALL_CRYPTO) + foreach(_o + WOLFSSL_AESCBC_LENGTH_CHECKS WOLFSSL_AESCCM WOLFSSL_AESCFB WOLFSSL_AESCTR + WOLFSSL_AESEAX WOLFSSL_AESECB WOLFSSL_AESGCM WOLFSSL_AESKEYWRAP + WOLFSSL_AESOFB WOLFSSL_AESSIV WOLFSSL_ANON WOLFSSL_ARC4 WOLFSSL_ATOMICUSER + WOLFSSL_BASE16 WOLFSSL_BASE64_ENCODE WOLFSSL_BLAKE2 WOLFSSL_BLAKE2S + WOLFSSL_CAMELLIA WOLFSSL_CERTEXT WOLFSSL_CERTGEN WOLFSSL_CERTREQ + WOLFSSL_CMAC WOLFSSL_CMAC_KDF WOLFSSL_CRL WOLFSSL_CRYPTOCB WOLFSSL_CSHAKE + WOLFSSL_CURVE25519 WOLFSSL_CURVE448 WOLFSSL_DH_DEFAULT_PARAMS WOLFSSL_DH + WOLFSSL_DES3 WOLFSSL_DSA WOLFSSL_ECCCUSTCURVES WOLFSSL_ECC_ENCRYPT + WOLFSSL_ECCSI WOLFSSL_ED25519 WOLFSSL_ED448 WOLFSSL_ENCKEYS WOLFSSL_FPECC + WOLFSSL_HASHFLAGS WOLFSSL_HKDF WOLFSSL_INDEF WOLFSSL_KEYGEN WOLFSSL_KMAC + WOLFSSL_MD2 WOLFSSL_MD4 WOLFSSL_MD5 WOLFSSL_PKCALLBACKS WOLFSSL_PKCS7 + WOLFSSL_PWDBASED WOLFSSL_RIPEMD WOLFSSL_RNG_BANK WOLFSSL_RSA_PSS + WOLFSSL_SAKKE WOLFSSL_SEP WOLFSSL_SESSIONCERTS WOLFSSL_SHA224 WOLFSSL_SHA3 + WOLFSSL_SHA512 WOLFSSL_SHAKE128 WOLFSSL_SHAKE256 WOLFSSL_SIPHASH WOLFSSL_SRP + WOLFSSL_SUPPORTED_CURVES WOLFSSL_TLSX WOLFSSL_X963KDF WOLFSSL_XCHACHA) + default_option(${_o} "yes") + endforeach() + + list(APPEND WOLFSSL_DEFINITIONS + "-DHAVE_AES_DECRYPT" "-DHAVE_AES_ECB" "-DWOLFSSL_ALT_NAMES" + "-DWOLFSSL_ASN_ALL" "-DWOLFSSL_DH_EXTRA" "-DWOLFSSL_HAVE_ISSUER_NAMES" + "-DWOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT" "-DWC_KDF_NIST_SP_800_56C" + "-DHAVE_ECC_CDH" "-DHAVE_ECC_KOBLITZ" "-DHAVE_ECC_SECPR2" + "-DHAVE_ECC_SECPR3" "-DHAVE_ECC_BRAINPOOL" "-DHAVE_FFDHE_2048" + "-DHAVE_FFDHE_3072" "-DHAVE_COMP_KEY" "-DHAVE_NULL_CIPHER" + "-DHAVE_SCRYPT" "-DWOLFSSL_AESGCM_STREAM" "-DWOLFSSL_AES_XTS" + "-DWOLFSSL_AESXTS_STREAM" "-DWC_SRTP_KDF") + # The Ed25519/Ed448 streaming-verify defines are emitted where those + # algorithms are resolved, so they only appear with the base algorithm. +endif() + +add_option(WOLFSSL_ALL_QUANTUM_CRYPTO + "Enable all quantum-resistant asymmetric algorithms (default: disabled)" + "no" "yes;no") + +if(WOLFSSL_ALL_QUANTUM_CRYPTO) + foreach(_o WOLFSSL_MLKEM WOLFSSL_MLDSA WOLFSSL_LMS WOLFSSL_XMSS WOLFSSL_SLHDSA) + default_option(${_o} "yes") + endforeach() +endif() + +add_option(WOLFSSL_ALL_OSP + "Enable all OSP meta feature sets (default: disabled)" + "no" "yes;no") + +if(WOLFSSL_ALL_OSP) + # WOLFSSL_STUNNEL is declared further down but has no block emitting its + # macro, unlike the other application bundles, so set it here. + list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_STUNNEL") + + foreach(_o + WOLFSSL_TAILSCALE WOLFSSL_WEBSERVER WOLFSSL_SMIME WOLFSSL_OPENSSH + WOLFSSL_LIGHTY WOLFSSL_NGINX WOLFSSL_OPENVPN WOLFSSL_ASIO + WOLFSSL_LIBWEBSOCKETS WOLFSSL_STUNNEL WOLFSSL_CURL) + default_option(${_o} "yes") + endforeach() +endif() + #################################################### # Application / integration support bundles (parity with configure.ac) #################################################### @@ -298,12 +493,16 @@ if(WOLFSSL_HAPROXY) list(APPEND WOLFSSL_DEFINITIONS "-DFP_MAX_BITS=16384" "-DHAVE_ALPN" "-DHAVE_ANON" "-DHAVE_COMP_KEY" "-DHAVE_CRL" "-DHAVE_EXT_CACHE" "-DHAVE_EX_DATA" "-DHAVE_MAX_FRAGMENT" "-DHAVE_OPENSSL_CMD" "-DHAVE_SECURE_RENEGOTIATION" "-DHAVE_SESSION_TICKET" "-DHAVE_TRUNCATED_HMAC" "-DHAVE_TRUSTED_CA" "-DKEEP_OUR_CERT" "-DKEEP_PEER_CERT" "-DNO_SESSION_CACHE_REF" "-DOPENSSL_ALL" "-DOPENSSL_COMPATIBLE_DEFAULTS" "-DOPENSSL_EXTRA" "-DRSA_MAX_SIZE=8192" "-DSESSION_CERTS" "-DSP_INT_BITS=8192" "-DWC_RSA_NO_PADDING" "-DWOLFSSL_ALLOW_SSLV3" "-DWOLFSSL_ALT_CERT_CHAINS" "-DWOLFSSL_ALWAYS_KEEP_SNI" "-DWOLFSSL_ALWAYS_VERIFY_CB" "-DWOLFSSL_CERT_GEN" "-DWOLFSSL_CERT_NAME_ALL" "-DWOLFSSL_CERT_REQ" "-DWOLFSSL_CHECK_ALERT_ON_ERR" "-DWOLFSSL_EITHER_SIDE" "-DWOLFSSL_ERROR_CODE_OPENSSL" "-DWOLFSSL_HAPROXY" "-DWOLFSSL_KEEP_RNG_SEED_FD_OPEN" "-DWOLFSSL_KEY_GEN" "-DWOLFSSL_PRIORITIZE_PSK" "-DWOLFSSL_SIGNER_DER_CERT" "-DWOLFSSL_TICKET_HAVE_ID" "-DWOLFSSL_TLS13_NO_PEEK_HANDSHAKE_DONE" "-DWOLFSSL_TRUST_PEER_CERT") endif() +# Note: no -DSINGLE_THREADED here. configure.ac's --enable-lighty does not +# set it, and defining it makes the whole library non-thread-safe rather +# than just the lighttpd integration -- which surfaced when WOLFSSL_ALL_OSP +# started enabling this bundle. add_option("WOLFSSL_LIGHTY" "Enable lighttpd/lighty support (default: disabled)" "no" "yes;no") if(WOLFSSL_LIGHTY) foreach(_o WOLFSSL_CRL WOLFSSL_MD5 WOLFSSL_OCSP WOLFSSL_OCSPSTAPLING WOLFSSL_OCSPSTAPLING_V2) force_option(${_o} "yes") endforeach() - list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_ALPN" "-DHAVE_CRL" "-DHAVE_EXT_CACHE" "-DHAVE_EX_DATA" "-DHAVE_LIGHTY" "-DHAVE_MAX_FRAGMENT" "-DHAVE_OPENSSL_CMD" "-DHAVE_SESSION_TICKET" "-DHAVE_TRUNCATED_HMAC" "-DHAVE_TRUSTED_CA" "-DHAVE_WOLFSSL_SSL_H=1" "-DKEEP_OUR_CERT" "-DKEEP_PEER_CERT" "-DOPENSSL_ALL" "-DOPENSSL_EXTRA" "-DOPENSSL_NO_COMP" "-DOPENSSL_NO_SSL2" "-DOPENSSL_NO_SSL3" "-DSESSION_CERTS" "-DSINGLE_THREADED" "-DWOLFSSL_ALWAYS_KEEP_SNI" "-DWOLFSSL_ALWAYS_VERIFY_CB" "-DWOLFSSL_CERT_GEN" "-DWOLFSSL_ENCRYPTED_KEYS" "-DWOLFSSL_KEY_GEN") + list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_ALPN" "-DHAVE_CRL" "-DHAVE_EXT_CACHE" "-DHAVE_EX_DATA" "-DHAVE_LIGHTY" "-DHAVE_MAX_FRAGMENT" "-DHAVE_OPENSSL_CMD" "-DHAVE_SESSION_TICKET" "-DHAVE_TRUNCATED_HMAC" "-DHAVE_TRUSTED_CA" "-DHAVE_WOLFSSL_SSL_H=1" "-DKEEP_OUR_CERT" "-DKEEP_PEER_CERT" "-DOPENSSL_ALL" "-DOPENSSL_EXTRA" "-DOPENSSL_NO_COMP" "-DOPENSSL_NO_SSL2" "-DOPENSSL_NO_SSL3" "-DSESSION_CERTS" "-DWOLFSSL_ALWAYS_KEEP_SNI" "-DWOLFSSL_ALWAYS_VERIFY_CB" "-DWOLFSSL_CERT_GEN" "-DWOLFSSL_ENCRYPTED_KEYS" "-DWOLFSSL_KEY_GEN") endif() add_option("WOLFSSL_WPAS" "Enable wpa_supplicant support (default: disabled)" "no" "yes;no") @@ -1878,6 +2077,12 @@ if(WOLFSSL_ED25519 AND NOT WOLFSSL_32BIT) set(WOLFSSL_FEMATH "yes") set(WOLFSSL_GEMATH "yes") list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_ED25519") + + # Part of WOLFSSL_ALL_CRYPTO. Only emitted here, once Ed25519 is known to + # be built, as settings.h rejects it without HAVE_ED25519. + if(WOLFSSL_ALL_CRYPTO) + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_ED25519_STREAMING_VERIFY") + endif() endif() # CURVE448 @@ -1921,6 +2126,12 @@ if(WOLFSSL_ED448 AND NOT WOLFSSL_32BIT) set(WOLFSSL_GE448 "yes") list(APPEND WOLFSSL_DEFINITIONS "-DHAVE_ED448") + # Part of WOLFSSL_ALL_CRYPTO. Only emitted here, once Ed448 is known to + # be built, as settings.h rejects it without HAVE_ED448. + if(WOLFSSL_ALL_CRYPTO) + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_ED448_STREAMING_VERIFY") + endif() + # EdDSA448 requires SHAKE256 which requires SHA-3 override_cache(WOLFSSL_SHAKE256 "yes") endif() @@ -2716,6 +2927,9 @@ else() if(WOLFSSL_LEAN_PSK OR WOLFSSL_LEAN_TLS) list(APPEND WOLFSSL_DEFINITIONS "-DNO_RC4") override_cache(WOLFSSL_ARC4 "no") + else() + # Deprecated algorithm handling, as configure.ac does for ARC4. + list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_ALLOW_RC4") endif() endif() @@ -4649,6 +4863,21 @@ foreach(_szmacro FP_MAX_BITS SP_INT_BITS RSA_MAX_SIZE MAX_ECC_BITS) endif() endforeach() +# OPENSSL_COMPATIBLE_DEFAULTS stands for a set of run-time behaviours, and +# configure.ac adds their defines wherever it is set: trusted peer certs, +# alternate chains, PSK priority and session cache reference semantics. +# Done here, after every bundle, so it does not depend on which one set it. +if("-DOPENSSL_COMPATIBLE_DEFAULTS" IN_LIST WOLFSSL_DEFINITIONS) + list(APPEND WOLFSSL_DEFINITIONS + "-DWOLFSSL_TRUST_PEER_CERT" + "-DNO_SESSION_CACHE_REF" + "-DWOLFSSL_TLS13_NO_PEEK_HANDSHAKE_DONE" + "-DWOLFSSL_ALT_CERT_CHAINS" + "-DWOLFSSL_PRIORITIZE_PSK" + "-DWOLFSSL_CHECK_ALERT_ON_ERR" + "-DWOLFSSL_TICKET_HAVE_ID") +endif() + # Drop exact-duplicate -D flags (e.g. a bundle and the source option it forces # both emitting the same feature define). list(REMOVE_DUPLICATES WOLFSSL_DEFINITIONS) diff --git a/cmake/functions.cmake b/cmake/functions.cmake index 144d82d9386..ece105b4e97 100644 --- a/cmake/functions.cmake +++ b/cmake/functions.cmake @@ -7,6 +7,49 @@ function(override_cache VAR VAL) " Please select value from \"${VAR_STRINGS}\"\n") endif() set_property(CACHE ${VAR} PROPERTY VALUE ${VAL}) + # A value the build chose stays a build choice: keep the record of it + # current so the next configure does not mistake it for the user's. + if(DEFINED CACHE{WOLFSSL_AUTO_${VAR}}) + set_property(CACHE WOLFSSL_AUTO_${VAR} PROPERTY VALUE "${VAL}") + endif() +endfunction() + +# Whether the user chose an option's current value, as opposed to it being +# a default or forced value that an earlier configure left in the cache. +# +# add_option() records the value the build itself put in the cache as +# WOLFSSL_AUTO_. A cached value still equal to that record was not +# changed by the user (-D or cmake-gui), so it is recomputed on every +# configure - which lets a bundle switched on in a re-run still supply its +# defaults. Only the cache entry is looked at: the user can only set that, +# while a normal variable of the same name is set by the build itself (an +# application bundle turning on what it needs). The one case this cannot +# see is the user passing -D with exactly the value the build had chosen; +# that is treated as unset. +function(wolfssl_option_user_set NAME RESULT) + set(_user FALSE) + if(DEFINED CACHE{${NAME}}) + set(_user TRUE) + if(DEFINED CACHE{WOLFSSL_AUTO_${NAME}}) + if("$CACHE{${NAME}}" STREQUAL "$CACHE{WOLFSSL_AUTO_${NAME}}") + set(_user FALSE) + endif() + endif() + endif() + set(${RESULT} ${_user} PARENT_SCOPE) +endfunction() + +# Whether the user explicitly turned an option off. Bundles use this to +# leave alone a feature whose prerequisite the user disabled. +function(wolfssl_option_user_off NAME RESULT) + wolfssl_option_user_set(${NAME} _user) + set(_off FALSE) + # Through a variable, so a value such as "small" counts as on. + set(_val "$CACHE{${NAME}}") + if(_user AND NOT _val) + set(_off TRUE) + endif() + set(${RESULT} ${_off} PARENT_SCOPE) endfunction() # Record that an option must be forced to a given value by a dependency (e.g. an @@ -22,6 +65,42 @@ function(force_option NAME VALUE) set_property(GLOBAL APPEND PROPERTY WOLFSSL_FORCE_PENDING "${NAME}") endfunction() +# Forget, at the start of a configure, every option value that the build +# chose on an earlier one (see wolfssl_option_user_set()), so the option is +# undefined until its add_option() runs - exactly as on a first configure. +# Without this, code that reads an option before its add_option() would see +# what the last configure left, e.g. a bundle that has since been turned +# off. Options the user set are kept and no longer tracked. +function(wolfssl_forget_auto_options) + get_cmake_property(_vars CACHE_VARIABLES) + foreach(_v ${_vars}) + if(_v MATCHES "^WOLFSSL_AUTO_(.+)$") + set(_n "${CMAKE_MATCH_1}") + if(DEFINED CACHE{${_n}} AND + ("$CACHE{${_n}}" STREQUAL "$CACHE{${_v}}")) + unset(${_n} CACHE) + else() + unset(${_v} CACHE) + endif() + endif() + endforeach() +endfunction() + +# Record a bundle's preferred value for an option, unless that option has +# already been settled -- either by the user (see wolfssl_option_user_set(); +# a value cached by an earlier configure does not count) or by an outer +# bundle that recorded a force first. This is the CMake counterpart of the +# `test "$enable_x" = "" &&` guard configure.ac uses in --enable-all and +# friends: a bundle supplies a default, it does not overrule a choice +# already made. +function(default_option NAME VALUE) + get_property(_already GLOBAL PROPERTY "WOLFSSL_FORCE_${NAME}" SET) + wolfssl_option_user_set(${NAME} _user) + if(NOT _user AND NOT _already) + force_option(${NAME} "${VALUE}") + endif() +endfunction() + # Warn about any force_option() whose target option was never declared with # add_option() (so the force never took effect). Call after all options are # defined and before generate_build_flags(). @@ -41,6 +120,10 @@ function(add_option NAME HELP_STRING DEFAULT VALUES) # Record the name for the options.h.in guard in CMakeLists.txt. set_property(GLOBAL APPEND PROPERTY WOLFSSL_DECLARED_OPTIONS "${NAME}") + # Decided before the cache entry is touched: whether the current value, + # if any, is the user's. + wolfssl_option_user_set(${NAME} _wolfssl_user) + if(VALUES STREQUAL "yes;no") # Set the default value for the option. set(${NAME} ${DEFAULT} CACHE BOOL ${HELP_STRING}) @@ -51,6 +134,17 @@ function(add_option NAME HELP_STRING DEFAULT VALUES) set_property(CACHE ${NAME} PROPERTY STRINGS ${VALUES}) endif() + if(_wolfssl_user) + # The user's value: stop tracking it as the build's. + unset(WOLFSSL_AUTO_${NAME} CACHE) + else() + # Not the user's: start again from the default, as on a first + # configure, instead of keeping whatever an earlier one cached. + set_property(CACHE ${NAME} PROPERTY VALUE "${DEFAULT}") + set(WOLFSSL_AUTO_${NAME} "${DEFAULT}" CACHE INTERNAL + "Value of ${NAME} chosen by the build, not the user") + endif() + # Apply any force_option(), after the cache entry exists so its type and # help survive, and before the reduction below. get_property(_wolfssl_forced GLOBAL PROPERTY "WOLFSSL_FORCE_${NAME}" SET) @@ -292,6 +386,9 @@ function(generate_build_flags) if(WOLFSSL_SRP OR WOLFSSL_USER_SETTINGS) set(BUILD_SRP "yes" PARENT_SCOPE) endif() + if(WOLFSSL_RNG_BANK OR WOLFSSL_USER_SETTINGS) + set(BUILD_RNG_BANK "yes" PARENT_SCOPE) + endif() set(USE_VALGRIND ${WOLFSSL_VALGRIND}) if(WOLFSSL_MD4 OR WOLFSSL_USER_SETTINGS) set(BUILD_MD4 "yes" PARENT_SCOPE) @@ -1251,6 +1348,14 @@ function(generate_lib_src_list LIB_SOURCES) list(APPEND LIB_SOURCES wolfcrypt/src/srp.c) endif() + # WOLFSSL_RNG_BANK defined WC_RNG_BANK_SUPPORT without ever adding + # the file that implements it, so the option only linked once + # something else pulled rng_bank.c in. Matches BUILD_RNG_BANK in + # wolfcrypt/src/include.am. + if(BUILD_RNG_BANK) + list(APPEND LIB_SOURCES wolfcrypt/src/rng_bank.c) + endif() + if(BUILD_AFALG) list(APPEND LIB_SOURCES wolfcrypt/src/port/af_alg/wc_afalg.c) endif() diff --git a/cmake/options.h.in b/cmake/options.h.in index 0ce90b79f61..b41b35578b3 100644 --- a/cmake/options.h.in +++ b/cmake/options.h.in @@ -913,6 +913,74 @@ extern "C" { #cmakedefine WOLFSSL_STATIC_RSA #undef WOLFSSL_WOLFSENTRY_HOOKS #cmakedefine WOLFSSL_WOLFSENTRY_HOOKS +/* Defines from the feature bundles (WOLFSSL_ALL, WOLFSSL_ALL_CRYPTO, + * WOLFSSL_ENTERPRISE) and the options they turn on. These change public + * structure layouts and APIs, so applications must see them as the library + * was built. */ +#undef HAVE_AES_DECRYPT +#cmakedefine HAVE_AES_DECRYPT +#undef HAVE_FFDHE_3072 +#cmakedefine HAVE_FFDHE_3072 +#undef HAVE_IO_TIMEOUT +#cmakedefine HAVE_IO_TIMEOUT +#undef HAVE_RPK +#cmakedefine HAVE_RPK +#undef HAVE_SCRYPT +#cmakedefine HAVE_SCRYPT +#undef SSL_TXT_TLSV1 +#cmakedefine SSL_TXT_TLSV1 +#undef SSL_TXT_TLSV1_1 +#cmakedefine SSL_TXT_TLSV1_1 +#undef WC_KDF_NIST_SP_800_56C +#cmakedefine WC_KDF_NIST_SP_800_56C +#undef WC_SRTP_KDF +#cmakedefine WC_SRTP_KDF +#undef WOLFCRYPT_HAVE_ECCSI +#cmakedefine WOLFCRYPT_HAVE_ECCSI +#undef WOLFCRYPT_HAVE_SAKKE +#cmakedefine WOLFCRYPT_HAVE_SAKKE +#undef WOLFSSL_ACERT +#cmakedefine WOLFSSL_ACERT +#undef WOLFSSL_AESGCM_SIV +#cmakedefine WOLFSSL_AESGCM_SIV +#undef WOLFSSL_AESXTS_STREAM +#cmakedefine WOLFSSL_AESXTS_STREAM +#undef WOLFSSL_AES_XTS +#cmakedefine WOLFSSL_AES_XTS +#undef WOLFSSL_ALLOW_LEGACY_SERVER_CONNECT +#cmakedefine WOLFSSL_ALLOW_LEGACY_SERVER_CONNECT +#undef WOLFSSL_ASN_ALL +#cmakedefine WOLFSSL_ASN_ALL +#undef WOLFSSL_CRYPTO_POLICY_FILE +#cmakedefine WOLFSSL_CRYPTO_POLICY_FILE @WOLFSSL_CRYPTO_POLICY_FILE@ +#undef WOLFSSL_DH_EXTRA +#cmakedefine WOLFSSL_DH_EXTRA +#undef WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT +#cmakedefine WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT +#undef WOLFSSL_ED25519_STREAMING_VERIFY +#cmakedefine WOLFSSL_ED25519_STREAMING_VERIFY +#undef WOLFSSL_ED448_STREAMING_VERIFY +#cmakedefine WOLFSSL_ED448_STREAMING_VERIFY +#undef WOLFSSL_FPKI +#cmakedefine WOLFSSL_FPKI +#undef WOLFSSL_HAVE_CERT_SERVICE +#cmakedefine WOLFSSL_HAVE_CERT_SERVICE +#undef WOLFSSL_HAVE_ISSUER_NAMES +#cmakedefine WOLFSSL_HAVE_ISSUER_NAMES +#undef WOLFSSL_SIPHASH +#cmakedefine WOLFSSL_SIPHASH +#undef WOLFSSL_SUBJ_DIR_ATTR +#cmakedefine WOLFSSL_SUBJ_DIR_ATTR +#undef WOLFSSL_SUBJ_INFO_ACC +#cmakedefine WOLFSSL_SUBJ_INFO_ACC +#undef WOLFSSL_SYS_CRYPTO_POLICY +#cmakedefine WOLFSSL_SYS_CRYPTO_POLICY +#undef WOLFSSL_TLS_OCSP_MULTI +#cmakedefine WOLFSSL_TLS_OCSP_MULTI +#undef WOLFSSL_TSP +#cmakedefine WOLFSSL_TSP +#undef WOLFSSL_VERBOSE_ERRORS +#cmakedefine WOLFSSL_VERBOSE_ERRORS #ifdef __cplusplus } diff --git a/configure.ac b/configure.ac index f488212c0bc..d94e3e9fa38 100644 --- a/configure.ac +++ b/configure.ac @@ -1397,6 +1397,121 @@ then fi +# Maximum-interoperability build: the feature set a deployment replacing +# OpenSSL is expected to find, i.e. everything in --enable-all plus the +# algorithms, protocol versions and behaviours that a default OpenSSL build +# still ships and --enable-all leaves out. Every setting below yields to an +# explicit --enable-/--disable- on the same command line. +AC_ARG_ENABLE([enterprise], + [AS_HELP_STRING([--enable-enterprise],[Enable maximum interoperability feature set, comparable to a default OpenSSL build (default: disabled)])], + [ ENABLED_ENTERPRISE=$enableval ], + [ ENABLED_ENTERPRISE=no ] + ) +if test "$ENABLED_ENTERPRISE" = "yes" +then + # Everything --enable-all brings in: --enable-all-crypto, + # --enable-all-osp, the TLS extensions and the OpenSSL compat layer. + test "$enable_all" = "" && enable_all=yes + + # OpenSSL 3.5 ships ML-KEM, ML-DSA and SLH-DSA in its default provider. + test "$enable_all_quantum_crypto" = "" && enable_all_quantum_crypto=yes + + # RC2 and 3DES are the deliberate exceptions to matching OpenSSL: it + # still carries both for compatibility - RC2 in the legacy provider, + # 3DES below the default security level - but an enterprise build has + # no reason to ship a 64-bit block cipher. These override the + # --enable-all-crypto defaults rather than following them. + # + # 3DES only actually goes away when --enable-all-osp is off: openssh, + # openvpn, wpas, krb, strongswan, stunnel, curl and friends set + # ENABLED_DES3 directly further down and win. The 3DES TLS cipher + # suites stay off either way, so no TLS connection negotiates 3DES. + test "$enable_rc2" = "" && enable_rc2=no + test "$enable_des3" = "" && enable_des3=no + + # SAKKE (RFC 6508) is identity-based key exchange for MIKEY-SAKKE. It + # has no OpenSSL counterpart and nothing an OpenSSL deployment talks to + # will offer it, so --enable-all-crypto's default is overridden here. + # Its companion EccSI (RFC 6507) is left on. + test "$enable_sakke" = "" && enable_sakke=no + + if test "$ENABLED_CRYPTONLY" != "yes" && \ + test "$KERNEL_MODE_DEFAULTS" != "yes" + then + # OpenSSL compiles TLS 1.0/1.1 in and refuses them at run time + # through the security level rather than at build time. SSL 3.0 + # stays out: OpenSSL needs an explicit enable-ssl3 for that too. + # --enable-harden-tls forbids both of these (RFC 9325). + if test "$ENABLED_FIPS" = "no" && test "x$ENABLED_HARDEN_TLS" = "xno" + then + # TLS 1.0 pulls old TLS back on, so --disable-oldtls has to + # suppress both of these to mean anything. + test "$enable_oldtls" != "no" && test "$enable_tlsv10" = "" && + enable_tlsv10=yes + test "$enable_oldtls" = "" && enable_oldtls=yes + # OpenSSL 3.x sets SSL_OP_LEGACY_SERVER_CONNECT by default. + test "$enable_legacy_server_connect" = "" && + enable_legacy_server_connect=yes + fi + + # RFC 5746 renegotiation, which OpenSSL performs by default. The + # two renegotiation options are mutually exclusive. + test "$enable_secure_renegotiation" = "" && + test "$enable_renegotiation_indication" != "yes" && + enable_secure_renegotiation=yes + + # SSL_export_keying_material(), RFC 5705. + test "$enable_keying_material" = "" && enable_keying_material=yes + + # HPKE, RFC 9180, as shipped by OpenSSL 3.2 and later. + test "$enable_hpke" = "" && enable_hpke=yes + fi + + if test "$ENABLED_FIPS" = "no" + then + # ShangMi (SM2/SM3/SM4) is deliberately left out even though + # OpenSSL has had it in the default provider since 3.0: the in-tree + # wolfssl/wolfcrypt/sm[234].h are stubs and the implementation comes + # from the separate wolfSSL/wolfsm repository. Add --enable-sm2 + # --enable-sm3 --enable-sm4-gcm once wolfsm is in place. + + # AES-CTS and AES-GCM-SIV were added to OpenSSL's default provider + # in 3.0 and 3.2. + test "$enable_aescts" = "" && test "$enable_aescbc" != "no" && + enable_aescts=yes + test "$enable_aesgcm_siv" = "" && test "$enable_aesgcm" != "no" && + enable_aesgcm_siv=yes + + # Attribute certificates, used by enterprise PKI deployments. Only + # the ASN.1 template parser decodes them. + test "$enable_acert" = "" && test "$ASN_IMPL" = "template" && + enable_acert=yes + + # "openssl ts". Only the ASN.1 template parser encodes TSP. + test "$enable_tsp" = "" && test "$ASN_IMPL" = "template" && + enable_tsp=yes + + # "openssl smime". Turning this on forces --enable-opensslall, + # which the restricted SP math build cannot supply. + test "$enable_smime" = "" && test "$ENABLED_SP_MATH" != "yes" && + test "$ASN_IMPL" != "no" && enable_smime=yes + fi + + # Match OpenSSL's run-time behaviour as well as its feature set: trusted + # peer certs, alternate chain building, PSK priority, session cache + # reference semantics. --disable-openssl-compatible-defaults undoes it. + AM_CFLAGS="$AM_CFLAGS -DOPENSSL_COMPATIBLE_DEFAULTS" + + # Compile in the system-wide crypto-policy reader, the nearest thing + # wolfSSL has to OpenSSL's security level and openssl.cnf. This only + # makes the wolfSSL_crypto_policy_*() API available and bakes in the + # default policy path; nothing is read until the application calls + # wolfSSL_crypto_policy_enable(), so a missing policy file is not an + # error. Override the path with --with-sys-crypto-policy=PATH. + test "$with_sys_crypto_policy" = "" && with_sys_crypto_policy=yes +fi + + # All features, except conflicting or experimental: AC_ARG_ENABLE([all], [AS_HELP_STRING([--enable-all],[Enable all wolfSSL features, except SSLv3 (default: disabled)])], @@ -14611,6 +14726,7 @@ echo " * OpenSSL Coexist: $ENABLED_OPENSSLCOEXIST" echo " * Old Names: $ENABLED_OLDNAMES" echo " * Max Strength Build: $ENABLED_MAXSTRENGTH" echo " * Distro Build: $ENABLED_DISTRO" +echo " * Enterprise Build: $ENABLED_ENTERPRISE" echo " * Reproducible Build: $ENABLED_REPRODUCIBLE_BUILD" echo " * Side-channel Hardening: $ENABLED_HARDEN" diff --git a/doc/OPENSSL_OPTION_MAPPING.md b/doc/OPENSSL_OPTION_MAPPING.md new file mode 100644 index 00000000000..fad4083bc79 --- /dev/null +++ b/doc/OPENSSL_OPTION_MAPPING.md @@ -0,0 +1,344 @@ +# OpenSSL to wolfSSL Build Option Mapping + +A reference for teams moving a build from OpenSSL to wolfSSL. It maps OpenSSL +`Configure` options and runtime knobs onto wolfSSL `./configure` options and +their CMake equivalents, and states plainly where there is no equivalent. + +Verified against OpenSSL 1.1.1w, 3.0.19, 3.1.8, 3.2.4, 3.3.7, 3.5.5, 3.5.8 and +the 4.0.0 release notes, and against wolfSSL 5.9.2. The OpenSSL releases differ +enough to matter, so rows that changed say which version they describe, and +"Availability by OpenSSL version" below gives the boundaries. + +**Which OpenSSL are you migrating from?** 3.5 is the current long-term-stable +release, supported until 8 April 2030. 4.0 (14 April 2026) is *not* LTS and is +supported only until 14 May 2027, so most long-lived deployments will still be +on 3.5. 4.0 removes SSLv3 and the whole ENGINE API, adds ECH, cSHAKE, the SNMP +and SRTP KDFs and RFC 8998 ShangMi TLS, and turns deprecated and explicit +elliptic curves off at compile time by default. + +## Read this first: the two builds mean different things by "enabled" + +OpenSSL and wolfSSL divide the same work between build time and run time in +opposite ways, and every table below is easier to read once that is clear. + +**OpenSSL decides at run time.** A default build compiles in nearly everything +and then narrows it through three runtime layers: + +- **Providers.** Algorithms live in `default`, `legacy`, `base` and `fips` + modules. Only `default` is loaded unless configured otherwise, so a legacy + algorithm is present in the binary but unusable until you ask for it. The + legacy provider is still present in 4.0; the ENGINE API it replaced is not. +- **Security level.** `@SECLEVEL=n` (default 1) refuses weak keys, protocol + versions and cipher suites without removing them. +- **`openssl.cnf`**, plus the distribution's system-wide crypto policy. + +**wolfSSL decides at build time.** Every feature is a preprocessor macro fixed +by `./configure` or CMake. There are no providers and no security level: if a +feature is compiled in, it is available, and if it is not, it does not exist. + +Two consequences worth planning around: + +1. Where OpenSSL ships something disarmed, wolfSSL must either compile it in + (and it is live) or leave it out. `--enable-enterprise` deliberately enables + TLS 1.0/1.1 for feature parity, and unlike OpenSSL they will be negotiated. + Restrict them at run time with a crypto policy, or drop them at build time + with `--disable-oldtls`. +2. The application must be built with the same macros as the library. Include + `` before any other wolfSSL header, or compile with + `-DWOLFSSL_USE_OPTIONS_H`. A mismatch changes struct layouts, compiles + cleanly, and corrupts memory at run time. + +## If you are coming from OpenSSL 1.1.1 + +1.1.1 predates the provider model entirely, and that changes the shape of the +migration more than any individual algorithm does. + +- **There is no provider split.** RC2, RC4, Blowfish, SEED, single DES, MD4 and + Whirlpool are usable straight out of a stock 1.1.1 build -- verified on + 1.1.1w. From 3.0 the same algorithms moved to the `legacy` provider and stop + working until it is loaded. So an application that quietly relied on RC4 or + MD4 breaks on the way to 3.x, before wolfSSL is even in the picture. +- **ENGINE is the only extension mechanism.** There are no providers to write, + and 4.0 removes ENGINE altogether, so an ENGINE-based integration has no + forward path on either side. wolfSSL's equivalent is crypto callbacks + (`--enable-cryptocb`) or PKCS#11. +- **`openssl list -mac-algorithms` and `-kdf-algorithms` do not exist**, so the + EVP_MAC and EVP_KDF tables below describe 3.0 and later only. +- **Missing relative to 3.x:** AES-SIV, AES-CBC-CTS and AES key wrap (3.0), + AES-GCM-SIV and Argon2 (3.2), ML-KEM, ML-DSA and SLH-DSA (3.5), ECH, cSHAKE + and the SNMP/SRTP KDFs (4.0). + +Everything else in this document applies unchanged: the wolfSSL side does not +vary with which OpenSSL you are leaving. + +## Availability by OpenSSL version + +Verified by running each release. "legacy" means present but not usable until +the legacy provider is loaded. + +| | 1.1.1w | 3.0 | 3.1 | 3.2 | 3.3 | 3.5 | 4.0 | +|---|---|---|---|---|---|---|---| +| Provider model | no | yes | yes | yes | yes | yes | yes | +| RC2, RC4, Blowfish, SEED, single DES | direct | legacy | legacy | legacy | legacy | legacy | legacy | +| MD4, Whirlpool, MDC2, MD2 | direct | legacy | legacy | legacy | legacy | legacy | legacy | +| RIPEMD-160 | direct | direct | direct | direct | direct | direct | direct | +| AES-SIV, AES-CBC-CTS, AES key wrap | no | yes | yes | yes | yes | yes | yes | +| AES-GCM-SIV, Argon2 | no | no | no | yes | yes | yes | yes | +| EVP_MAC: CMAC, GMAC, KMAC, Poly1305, SipHash | n/a | yes | yes | yes | yes | yes | yes | +| EVP_KDF: HKDF, KBKDF, KRB5, SSH, SSKDF, X9.42, X9.63, scrypt | n/a | yes | yes | yes | yes | yes | yes | +| ML-KEM, ML-DSA, SLH-DSA | no | no | no | no | no | yes | yes | +| LMS (verification only) | no | no | no | no | no | no | 3.6+ | +| ECH, cSHAKE, SNMP KDF, SRTP KDF | no | no | no | no | no | no | yes | +| SSLv3 | build option, off | off | off | off | off | off | **removed** | +| ENGINE API | yes | deprecated | deprecated | deprecated | deprecated | deprecated | **removed** | +| 3DES and RC4 TLS cipher suites | no | no | no | no | no | no | no | + +No stock build tested offered a 3DES or RC4 TLS cipher suite, even at +`@SECLEVEL=0` -- including 1.1.1w. They require `enable-weak-ssl-ciphers` at +build time, so treat their absence as the norm and check your own build if you +believe otherwise. + +## Start here + +| Goal | Autotools | CMake | +|---|---|---| +| Closest match to a default OpenSSL build | `--enable-enterprise` | `-DWOLFSSL_ENTERPRISE=yes` | +| Every wolfSSL feature that can coexist | `--enable-all` | `-DWOLFSSL_ALL=yes` | +| All wolfCrypt algorithms, no TLS extras | `--enable-all-crypto` | `-DWOLFSSL_ALL_CRYPTO=yes` | +| Post-quantum asymmetric algorithms | `--enable-all-quantum-crypto` | `-DWOLFSSL_ALL_QUANTUM_CRYPTO=yes` | +| OpenSSL compatibility API only | `--enable-opensslall` | `-DWOLFSSL_OPENSSLALL=yes` | +| Link beside a real libcrypto | `--enable-opensslcoexist` | `-DWOLFSSL_OPENSSL_COEXIST=yes` | + +`--enable-enterprise` is the recommended starting point. It is `--enable-all` +plus the protocol versions, algorithms and behaviours a default OpenSSL build +still ships, minus a short list of deliberate exclusions (see +"Where enterprise departs from OpenSSL"). Any explicit `--enable-`/`--disable-` +on the same command line overrides it, so treat it as a baseline to trim. + +## Protocol versions + +| OpenSSL | wolfSSL autotools | CMake | +|---|---|---| +| SSL 3.0 — 3.5: `enable-ssl3`, off by default. **Removed outright in 4.0**, along with the SSLv2 ClientHello | `--enable-sslv3` | `-DWOLFSSL_SSLV3=yes` | +| TLS 1.0 (`no-tls1`) | `--enable-tlsv10` | `-DWOLFSSL_TLSV10=yes` | +| TLS 1.1 (`no-tls1_1`) | `--enable-oldtls` | `-DWOLFSSL_OLD_TLS=yes` | +| TLS 1.2 (`no-tls1_2`) | on by default; `--disable-tlsv12` | `-DWOLFSSL_TLSV12=no` | +| TLS 1.3 (`no-tls1_3`) | on by default; `--disable-tls13` | `-DWOLFSSL_TLS13=no` | +| DTLS 1.0/1.2 (`no-dtls`) | `--enable-dtls` | `-DWOLFSSL_DTLS=yes` | +| DTLS 1.3 — *not in OpenSSL* | `--enable-dtls13` | `-DWOLFSSL_DTLS13=yes` | +| QUIC | `--enable-quic` | `-DWOLFSSL_QUIC=yes` | +| SCTP (`enable-sctp`) | `--enable-sctp` | — | +| SRTP (`no-srtp`) | `--enable-srtp` | `-DWOLFSSL_SRTP=yes` | +| Negotiated FFDHE in TLS 1.2, RFC 7919 — *4.0 only* | on with `--enable-dh` (FFDHE 2048/3072 groups) | `-DWOLFSSL_DH=yes` | + +wolfSSL builds TLS 1.2 and 1.3 by default and everything older must be asked +for; OpenSSL is the reverse. + +## Ciphers and digests + +| OpenSSL | Provider | wolfSSL autotools | CMake | +|---|---|---|---| +| AES-CBC/CTR/OFB/CFB/ECB | default | on by default; `--enable-aesctr`, `--enable-aesofb`, `--enable-aescfb`, `--enable-aesecb` | `-DWOLFSSL_AESCTR=yes` … | +| AES-GCM / CCM | default | `--enable-aesgcm` (default on), `--enable-aesccm` | `-DWOLFSSL_AESGCM=yes`, `-DWOLFSSL_AESCCM=yes` | +| AES-XTS | default | `--enable-aesxts` | — | +| AES-SIV — *3.0+* | default | `--enable-aessiv` | `-DWOLFSSL_AESSIV=yes` | +| AES-GCM-SIV — *3.2+* | default | `--enable-aesgcm-siv` | `-DWOLFSSL_AESGCMSIV=yes` | +| AES-CTS — *3.0+* | default | `--enable-aescts` | `-DWOLFSSL_AESCTS=yes` | +| AES-OCB | default | **no equivalent** | — | +| AES key wrap — *3.0+* | default | `--enable-aeskeywrap` | `-DWOLFSSL_AESKEYWRAP=yes` | +| ChaCha20-Poly1305 | default | on by default | `-DWOLFSSL_CHACHA=yes` | +| Camellia | default | `--enable-camellia` | `-DWOLFSSL_CAMELLIA=yes` | +| ARIA | default | `--enable-aria` — **requires the external MagicCrypto SDK** | `-DWOLFSSL_ARIA=yes` | +| SM4 | default | `--enable-sm4-{ecb,cbc,ctr,gcm,ccm}` — **requires [wolfsm](https://github.com/wolfSSL/wolfsm)** | `-DWOLFSSL_SM4_*=yes` | +| TLS 1.3 SM suites `TLS_SM4_GCM_SM3`, `TLS_SM4_CCM_SM3`, RFC 8998 — *4.0 only* | default | `--enable-sm2 --enable-sm3 --enable-sm4-gcm` — **requires wolfsm** | — | +| 3DES (`no-des`) | default | `--enable-des3` | `-DWOLFSSL_DES3=yes` | +| 3DES TLS cipher suites — need `enable-weak-ssl-ciphers` at build time; stock 3.5 and 4.0 builds offer none at any security level | — | `--enable-des3-tls-suites` | `-DWOLFSSL_DES3_TLS_SUITES=yes` | +| RC4 (`no-rc4`) | legacy | `--enable-arc4` | `-DWOLFSSL_ARC4=yes` | +| RC2 (`no-rc2`) | legacy | `--enable-rc2` | `-DWOLFSSL_RC2=yes` | +| NULL cipher | default | `--enable-nullcipher` | — | +| Blowfish, CAST5, IDEA, SEED, DESX, single DES | legacy | **no equivalent** (single DES exists inside wolfCrypt's 3DES module but is not exposed as a build option) | — | +| RC5 | legacy, and needs `enable-rc5` | **no equivalent** | — | +| SHA-1, SHA-2 | default | on by default | — | +| SHA-3, SHAKE | default | `--enable-sha3`, `--enable-shake128/256` | `-DWOLFSSL_SHA3=yes` … | +| MD5 / MD4 (`no-md4`) | default / legacy | `--enable-md5`, `--enable-md4` | `-DWOLFSSL_MD5=yes`, `-DWOLFSSL_MD4=yes` | +| MD2 | legacy, and needs `enable-md2` | `--enable-md2` | `-DWOLFSSL_MD2=yes` | +| RIPEMD-160 (`no-rmd160`) | default **and** legacy — usable without loading legacy, unlike the other legacy digests | `--enable-ripemd` | `-DWOLFSSL_RIPEMD=yes` | +| BLAKE2b / BLAKE2s (`no-blake2`) | default | `--enable-blake2b`, `--enable-blake2s` | `-DWOLFSSL_BLAKE2=yes`, `-DWOLFSSL_BLAKE2S=yes` | +| SM3 | default | `--enable-sm3` — **requires wolfsm** | `-DWOLFSSL_SM3=yes` | +| cSHAKE, SP 800-185 — *4.0 only* | default | `--enable-cshake` | `-DWOLFSSL_CSHAKE=yes` | +| Whirlpool, MDC2 | legacy | **no equivalent** | — | + +## MACs and KDFs + +| OpenSSL | wolfSSL autotools | CMake | +|---|---|---| +| HMAC | on by default | — | +| CMAC | `--enable-cmac` | `-DWOLFSSL_CMAC=yes` | +| GMAC | comes with `--enable-aesgcm` | — | +| KMAC | `--enable-kmac` | `-DWOLFSSL_KMAC=yes` | +| Poly1305 | on by default | `-DWOLFSSL_POLY1305=yes` | +| SipHash (`no-siphash`) | `--enable-siphash` | `-DWOLFSSL_SIPHASH=yes` | +| HKDF | `--enable-hkdf` | `-DWOLFSSL_HKDF=yes` | +| TLS1-PRF / TLS13-KDF | built in with the protocol | — | +| PBKDF2 | `--enable-pwdbased` | `-DWOLFSSL_PWDBASED=yes` | +| scrypt (`no-scrypt`) | `--enable-scrypt` | — | +| KBKDF, SP 800-108 | **no equivalent** (`--enable-cmac-kdf` covers the CMAC variant only) | — | +| KRB5KDF | **no equivalent** | — | +| PKCS12KDF | comes with `--enable-pkcs12` | `-DWOLFSSL_PKCS12=yes` | +| Argon2 (`no-argon2`) — *3.2+* | **not yet in wolfCrypt**; the implementation exists on an unmerged branch | — | +| X9.63 KDF | `--enable-x963kdf` | `-DWOLFSSL_X963KDF=yes` | +| X9.42 KDF | **no equivalent** | — | +| SSKDF (SP 800-56C) | comes with `--enable-all-crypto` | — | +| SSHKDF | `--enable-ssh` | — | +| SRTP-KDF — *4.0 only* | `--enable-srtp-kdf` | — | +| SNMP KDF — *4.0 only* | **no equivalent** | — | + +## Public key + +| OpenSSL | wolfSSL autotools | CMake | +|---|---|---| +| RSA, RSA-OAEP | on by default; `--enable-oaep` | `-DWOLFSSL_OAEP=yes` | +| RSA-PSS | `--enable-rsapss` | `-DWOLFSSL_RSA_PSS=yes` | +| DH (`no-dh`) | `--enable-dh` | `-DWOLFSSL_DH=yes` | +| DSA (`no-dsa`) | `--enable-dsa` | `-DWOLFSSL_DSA=yes` | +| ECDSA / ECDH (`no-ec`) | on by default | `-DWOLFSSL_ECC=yes` | +| Brainpool, Koblitz, secp*r2/r3 | `--enable-ecccustcurves`, `--enable-brainpool` | `-DWOLFSSL_ECCCUSTCURVES=yes` | +| RFC 8422 deprecated TLS curves — *4.0 disables these at compile time by default* | governed by `--enable-ecccustcurves` and the curve options above | — | +| Explicit (non-named) EC curve parameters — *4.0 disables these by default* | `--enable-ecccustcurves` | `-DWOLFSSL_ECCCUSTCURVES=yes` | +| Binary/`ec2m` curves (`no-ec2m`) | **no equivalent** | — | +| X25519 / Ed25519 | `--enable-curve25519`, `--enable-ed25519` | `-DWOLFSSL_CURVE25519=yes`, `-DWOLFSSL_ED25519=yes` | +| X448 / Ed448 | `--enable-curve448`, `--enable-ed448` | `-DWOLFSSL_CURVE448=yes`, `-DWOLFSSL_ED448=yes` | +| SM2 (4.0 adds `sm2sig_sm3`, `curveSM2` and `curveSM2MLKEM768`, RFC 8998) | `--enable-sm2` — **requires wolfsm** | `-DWOLFSSL_SM2=yes` | +| ML-KEM — *3.5+* | `--enable-mlkem` | `-DWOLFSSL_MLKEM=yes` | +| ML-DSA — *3.5+*; 4.0 adds the `ML-DSA-MU` digest | `--enable-mldsa` | `-DWOLFSSL_MLDSA=yes` | +| SLH-DSA — *3.5+* | `--enable-slhdsa` | `-DWOLFSSL_SLHDSA=yes` | +| LMS — absent from 3.5; verification only from 3.6, reaching `openssl pkeyutl` in 4.0 | `--enable-lms`, sign **and** verify | `-DWOLFSSL_LMS=yes` | +| XMSS — *not in OpenSSL* | `--enable-xmss` | `-DWOLFSSL_XMSS=yes` | + +## TLS features and PKI + +| OpenSSL | wolfSSL autotools | CMake | +|---|---|---| +| SNI, ALPN | `--enable-sni`, `--enable-alpn` | `-DWOLFSSL_SNI=yes`, `-DWOLFSSL_ALPN=yes` | +| Session tickets | `--enable-session-ticket` | `-DWOLFSSL_SESSION_TICKET=yes` | +| Early data / 0-RTT | `--enable-earlydata` | `-DWOLFSSL_EARLYDATA=yes` | +| Secure renegotiation | `--enable-secure-renegotiation` | `-DWOLFSSL_SECURE_RENEGOTIATION=yes` | +| `SSL_OP_LEGACY_SERVER_CONNECT` (on by default) | `--enable-legacy-server-connect` | — | +| `SSL_export_keying_material` | `--enable-keying-material` | `-DWOLFSSL_KEYING_MATERIAL=yes` | +| `SSL_CTX_set_keylog_callback` | `--enable-keylog-export` | `-DWOLFSSL_KEYLOG_EXPORT=yes` | +| PSK (`no-psk`) | `--enable-psk` | — | +| SRP (`no-srp`) | `--enable-srp` | `-DWOLFSSL_SRP=yes` | +| OCSP (`no-ocsp`) | `--enable-ocsp` | `-DWOLFSSL_OCSP=yes` | +| OCSP stapling | `--enable-ocspstapling`, `--enable-ocspstapling2` | `-DWOLFSSL_OCSPSTAPLING=yes` | +| CRL | `--enable-crl` | `-DWOLFSSL_CRL=yes` | +| CMS / PKCS#7 (`no-cms`) | `--enable-pkcs7` | `-DWOLFSSL_PKCS7=yes` | +| S/MIME | `--enable-smime` | `-DWOLFSSL_SMIME=yes` | +| Timestamping, `openssl ts` (`no-ts`) | `--enable-tsp` | `-DWOLFSSL_TSP=yes` | +| PKCS#12 | `--enable-pkcs12` (default on) | `-DWOLFSSL_PKCS12=yes` | +| PKCS#8 | `--enable-pkcs8` (default on) | `-DWOLFSSL_PKCS8=yes` | +| Certificate Transparency (`no-ct`) | **no equivalent** | — | +| DANE/TLSA (`no-dane`) | **no equivalent** | — | +| CMP / CRMF, RFC 4210 | **no equivalent** (`--enable-scep` covers a different enrolment protocol) | — | +| Attribute certificates — *not in OpenSSL* | `--enable-acert` | — | +| Encrypted Client Hello — not in 3.5; **added in 4.0** (RFC 9849) | `--enable-ech` | `-DWOLFSSL_ECH=yes` | +| Compression (`no-comp`, zlib) | `--with-libz` | `-DWOLFSSL_LIBZ=yes` | +| Per-thread error queue | `--enable-error-queue-per-thread` (auto-detected) | `-DWOLFSSL_ERROR_QUEUE_PER_THREAD=yes` | +| System CA store | `--enable-sys-ca-certs` (default on) | `-DWOLFSSL_SYS_CA_CERTS=yes` | + +## Runtime behaviour, not build options + +These are the OpenSSL knobs with no `./configure` counterpart, because wolfSSL +places the same control somewhere else. + +| OpenSSL | wolfSSL | +|---|---| +| Providers (`default`, `legacy`, `fips`) | No equivalent. Compile in what you need; `--enable-fips=` selects a licensed FIPS module. | +| `@SECLEVEL=n` | No direct equivalent. Nearest is the system crypto policy below. | +| `openssl.cnf`, `/etc/crypto-policies` | `--with-sys-crypto-policy[=PATH]` reads `/etc/crypto-policies/back-ends/wolfssl.config`; sample policies in `examples/crypto_policies/`. Compiling it in only exposes `wolfSSL_crypto_policy_enable()`; nothing is read until the application calls it. Enabled by `--enable-enterprise`. | +| ENGINE API — **removed entirely in 4.0**; `no-engine` and `OPENSSL_NO_ENGINE` are now unconditional | Crypto callbacks (`--enable-cryptocb`, `wc_CryptoCb_RegisterDevice`) or PKCS#11 (`--enable-pkcs11`). To keep OpenSSL's API and swap the crypto underneath, [wolfProvider](https://github.com/wolfSSL/wolfProvider) works with 3.x and 4.0; [wolfEngine](https://github.com/wolfSSL/wolfEngine) is an ENGINE and therefore **cannot be used with OpenSSL 4.0**. | +| The `openssl` command | Not shipped. See [wolfCLU](https://github.com/wolfSSL/wolfCLU). | +| `no-threads` | `--enable-singlethreaded` | +| `no-stdio` / `no-filenames` | `--disable-filesystem` | +| `no-shared` | `--disable-shared` | +| `enable-fips` | `--enable-fips=`. Certified versions need a licensed bundle from wolfSSL; `ready` and `dev` work with the free FIPS Ready download. No FIPS variant configures from a plain git checkout. | +| `no-deprecated`, `--api=` | No equivalent; wolfSSL's compatibility surface is chosen by `--enable-opensslextra` vs `--enable-opensslall`. | +| Custom `EVP_CIPHER` / `EVP_MD` / `EVP_PKEY` methods — **removed in 4.0** | Crypto callbacks (`--enable-cryptocb`) are the supported extension point. | + +## Where `--enable-enterprise` departs from OpenSSL + +Three deliberate exclusions, all overridable: + +- **RC2** is not compiled in. OpenSSL ships it, but in the `legacy` provider, + which is not loaded by default — `openssl enc -rc2` fails on a stock build. + Leaving it out is closer to OpenSSL's effective behaviour than including it. +- **3DES cipher suites** are off (`NO_DES3_TLS_SUITES`), matching OpenSSL 3.5, + which no longer compiles them in at any security level. The 3DES *algorithm* + stays available, as it does in OpenSSL's default provider. +- **SAKKE** (RFC 6508) is off. It has no OpenSSL counterpart and nothing an + OpenSSL deployment talks to will offer it. + +RC4, MD2, MD4, MD5 and the NULL cipher remain enabled, because OpenSSL also +ships them and several application compatibility profiles require them. + +## Application compatibility profiles + +wolfSSL ships flag sets matching what specific projects need, which is usually +faster than deriving the option list by hand: + +``` +--enable-curl --enable-nginx --enable-haproxy --enable-openssh +--enable-openvpn --enable-stunnel --enable-libssh2 --enable-lighty +--enable-wpas --enable-net-snmp --enable-openldap --enable-krb +``` + +`--enable-all-osp` (`-DWOLFSSL_ALL_OSP=yes`) enables all of them at once and is +included in `--enable-all`. + +## Checking what you got + +```sh +./configure --enable-enterprise && make +grep '#define' wolfssl/options.h # every macro the build settled on +./wolfcrypt/test/testwolfcrypt # algorithm self-tests +make check # full suite +``` + +`./configure --help` lists every option; `configure.ac` is the source of truth +for the macros each one sets. + +Two caveats when comparing builds: + +- `wolfssl/options.h` is generated per build. Never commit it, and never mix one + build's copy with another's objects. +- The CMake build generates its `options.h` from a fixed template, so it records + fewer macros than the autotools one even when the compiled result matches. + Compare CMake builds using the compiler flags, not `options.h`. + +## How these tables were checked + +The legacy provider is unchanged in 4.0 and still carries MD2, MD4, MDC2, +Whirlpool, RIPEMD-160, Blowfish, CAST, DES, DESX, IDEA, RC2, RC4, RC5 and SEED +-- present in the binary, inert until the provider is loaded. + +Every OpenSSL release named at the top was run and probed, not read about: +1.1.1w, 3.0.19, 3.1.8, 3.2.4, 3.3.7 and 3.5.8 in containers, 3.5.5 on the host. +The probes were `openssl list` (`-cipher-algorithms`, `-digest-algorithms`, +`-mac-algorithms`, `-kdf-algorithms`, `-signature-algorithms`, `-kem-algorithms`, +`-tls-groups`, `-providers`), `openssl ciphers -v 'ALL:@SECLEVEL=0'`, and +functional checks -- `openssl enc`, `dgst` and `genpkey` per algorithm -- since +listing an algorithm and being able to use it are different questions once +providers exist. 4.0 rows come from the 4.0.0 release notes and its shipped +`OSSL_PROVIDER-legacy` page, as no 4.0 build was available to run. + +Re-run those probes against your own build before relying on a row. Several +entries are build-time choices a distribution can change -- `enable-ssl3`, +`enable-weak-ssl-ciphers`, `no-idea` and `no-cast` most of all. Debian's 1.1.1w, +for instance, ships RC2, RC4, Blowfish and SEED but not CAST5 or IDEA. + +## Further reading + +- `INSTALL` — platform-by-platform build notes +- `examples/configs/user_settings_openssl_compat.h` — the same feature set for + IDE, RTOS and bare-metal builds with no configure step +- wolfSSL manual — +- Porting help and commercial licensing — support@wolfssl.com diff --git a/doc/include.am b/doc/include.am index 182e9aff59c..01fe271fba8 100644 --- a/doc/include.am +++ b/doc/include.am @@ -8,7 +8,8 @@ dist_doc_DATA+= doc/README.txt \ doc/SBOM.md \ doc/CRA.md \ doc/ASM_AND_MATH_DEFINES.md \ - doc/ALGORITHM_DEFINES.md + doc/ALGORITHM_DEFINES.md \ + doc/OPENSSL_OPTION_MAPPING.md dox-pdf: