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: