diff --git a/.config.ci b/.config.ci index bac9785..346a7e9 100644 --- a/.config.ci +++ b/.config.ci @@ -10,3 +10,6 @@ CONFIG_PACKAGE_matter-netman-openssl=m CONFIG_PACKAGE_mdnsresponder=m CONFIG_PACKAGE_openthread-br=m CONFIG_PACKAGE_openthread-rcp-nrf52840-mdk=m +CONFIG_PACKAGE_wpad-mbedtls=m +CONFIG_PACKAGE_wpad-openssl=m +CONFIG_PACKAGE_wpad-wolfssl=m diff --git a/.containers/hostapd-hwsim-runner/Dockerfile b/.containers/hostapd-hwsim-runner/Dockerfile new file mode 100644 index 0000000..6961f6c --- /dev/null +++ b/.containers/hostapd-hwsim-runner/Dockerfile @@ -0,0 +1,55 @@ +FROM --platform=linux/amd64 debian:trixie-slim + +# The tests need mac80211_hwsim, which is not available for the kernel of a +# GitHub Actions runner, so qemu-run executes them in a nested VM built around +# the generic Debian kernel. +ENV DEBIAN_FRONTEND=noninteractive +RUN set -eux; \ + apt-get update; \ + apt-get install -y --no-install-recommends \ + # hostap build + build-essential git pkg-config \ + autoconf automake libtool \ + binutils-dev libiberty-dev \ + libnl-3-dev libnl-genl-3-dev libnl-route-3-dev \ + libmbedtls-dev libssl-dev \ + libdbus-1-dev libsqlite3-dev libpcap-dev libxml2-dev libcurl4-openssl-dev \ + # test runtime + python3 python3-pip \ + iproute2 iw bridge-utils net-tools \ + kmod procps psmisc openssl wireless-regdb \ + faketime ca-certificates \ + qemu-system-x86 virtiofsd; \ + # Download and unpack the kernel image directly; this avoids pulling in + # it's runtime dependencies (linux-base, systemd, udev, ...) and also + # avoids running any post-install hooks like initramfs generation. + kpkg="$(apt-cache depends linux-image-amd64 | grep Depends | grep -o 'linux-image-.*')"; \ + cd /var/cache; apt-get download "$kpkg"; dpkg-deb -x linux-image-*.deb /; \ + kver="$(ls /lib/modules)"; depmod "$kver"; \ + cd /boot; ln -s "vmlinuz-$kver" vmlinuz-qemu; \ + # Clean up + rm -rf /var/cache/linux-image-*.deb /var/lib/apt/lists/* + +COPY qemu-run /usr/local/bin/qemu-run + +# The Debian wolfssl package does not enable all the options hostapd requires. +# Build from source enabling everything hostapd's crypto_wolfssl.c / DPP / EAP +# code references: --enable-all is the feature umbrella (PKCS7, cert gen/req, +# HPKE, ...) and --enable-wpas adds the wpa_supplicant-specific bits that +# --enable-all does not (notably HAVE_SECRET_CALLBACK, HAVE_KEYING_MATERIAL). +RUN cd /usr/local/src \ + && git clone --depth 1 --single-branch --branch v5.9.2-stable https://github.com/wolfSSL/wolfssl \ + && cd wolfssl \ + && ./autogen.sh && ./configure --enable-all --enable-wpas --enable-hpke \ + && make -j"$(nproc)" && make install && ldconfig \ + && cd / && rm -rf /usr/local/src/wolfssl + +# Test-framework Python deps (the packaged versions are known-problematic, so use pip; +# Debian marks the base env externally-managed, hence --break-system-packages). +RUN pip3 install --no-cache-dir --break-system-packages pycryptodome pyrad + +# hwsim tests launch hostapd/wpa_supplicant etc. via sudo unconditionally, +# which strips LD_PRELOAD and breaks using faketime to work around expired +# test certificates. Use a sudo stub similar to tests/hwsim/vm/inside.sh. +RUN printf '%s\n' '#!/bin/sh' 'exec "$@"' >/usr/local/bin/sudo \ + && chmod +x /usr/local/bin/sudo diff --git a/.containers/hostapd-hwsim-runner/qemu-run b/.containers/hostapd-hwsim-runner/qemu-run new file mode 100755 index 0000000..8596ebd --- /dev/null +++ b/.containers/hostapd-hwsim-runner/qemu-run @@ -0,0 +1,124 @@ +#!/bin/bash +# +# Run a command inside a qemu VM that shares the host's file system. +# +# The arguments are a command and its arguments, not a shell command string; +# word boundaries are preserved as they would be by sudo or docker run, rather +# than being re-split by a shell as they are by ssh. +# If no arguments are given, a shell script is read from stdin instead. This +# convenient when shell syntax is required, especially combined with << or <<<, +# e.g. qemu-run <<<'test -e /dev/shm && echo yes' +# The exit status of the command is propagated as the exit status of qemu-run. + +set -eu + +VM_MEMORY="${VM_MEMORY:-2048}" +VM_CPUS="${VM_CPUS:-$(nproc)}" + +# Deliberately not under /tmp, which the tests use for their own purposes. +JOB="$(mktemp -d -p /var/tmp)" + +# virtiofsd normally exits by itself once qemu disconnects, so the kill only +# matters when we bail out before or during the qemu run. It has to tolerate the +# process already being gone: under set -e a failure here would both skip the +# rest of the cleanup and override the exit status we are trying to propagate. +cleanup() { + [[ -z "${VFSD:-}" ]] || kill "$VFSD" 2>/dev/null || true + rm -rf -- "$JOB" +} +trap cleanup EXIT + +# Assemble the VM's init script +{ + # /run has to be a local file system, because the hostapd and wpa_supplicant + # control interfaces create unix sockets there. /dev has to be devtmpfs + # rather than the container's shared /dev, because mac80211_hwsim needs its + # own rfkill device nodes -- which in turn means /dev/shm and /dev/pts have + # to be mounted by hand, as devtmpfs provides neither. faketime needs the + # former: it passes the clock offset to child processes through a POSIX + # shared memory object. + printf '%s\n' \ + '#!/bin/bash' \ + 'mount -t devtmpfs devtmpfs /dev' \ + 'exec /dev/console 2>&1' \ + 'mkdir -p /dev/shm /dev/pts' \ + 'mount -t tmpfs -o mode=1777,nosuid,nodev tmpfs /dev/shm' \ + 'mount -t devpts -o gid=5,mode=620,ptmxmode=666 devpts /dev/pts' \ + 'mount -t proc proc /proc' \ + 'mount -t sysfs sysfs /sys' \ + 'mount -t debugfs debugfs /sys/kernel/debug' \ + 'mount -t tmpfs tmpfs /run' \ + 'ip link set lo up # some tests talk to 127.0.0.1' \ + 'export USER=root LOGNAME=root HOME=/root' \ + 'export debian_chroot=qemu' \ + 'echo 1 >/proc/sys/kernel/sysrq' + # Propagate a few values from the host + printf 'hostname %q\n' "$(hostname)" + printf 'export TERM=%q\n' "${TERM:-dumb}" # for an interactive shell + printf 'cd %q\n' "$PWD" + # Delimit the command's output from the kernel's boot/shutdown chatter. + printf 'echo === >&2\n' + # Transmit the exit status, then stop the VM using Sysrq. The sleep keeps + # init alive until it takes effect, since the kernel panics if pid 1 exits. + printf 'trap %q EXIT\n' \ + 'rc=$?; echo "$rc" >'"$JOB"'/rc; echo === >&2; echo o >/proc/sysrq-trigger; sleep 60' + # Emit the job body, in a subshell so that an exec in the job replaces that + # rather than init, which would discard the trap above. Bash resets the trap + # to its default in the subshell, so it stays owned by init alone. The no-op + # keeps the subshell valid even if the job turns out to be empty. + printf '( :\n' + if (( $# )); then + printf ' %q' "$@" + else + cat + fi + printf '\n)\n' +} >"$JOB/init" +chmod 0755 "$JOB/init" + +# --sandbox=none because the default sandbox needs privileges the container does +# not have, and would hide any volumes mounted into it. --announce-submounts +# keeps inode numbers distinct across the several mounts that / spans. +/usr/libexec/virtiofsd \ + --socket-path="$JOB/vfs.sock" --shared-dir=/ \ + --sandbox=none --seccomp=none --rlimit-nofile 0 \ + --announce-submounts --cache=auto \ + --log-level warn & +VFSD=$! +while kill -0 "$VFSD" 2>/dev/null && [[ ! -e "$JOB/vfs.sock" ]]; do sleep 0.05; done +if [[ ! -e "$JOB/vfs.sock" ]]; then + echo "qemu-run: virtiofsd failed to start" >&2 + exit 1 +fi + +# KVM is available on GitHub-hosted runners, but fall back to emulation so that +# this also works elsewhere (much slower, and the tests are timing sensitive). +if [[ -w /dev/kvm ]]; then + ACCEL=kvm CPU=host +else + echo "qemu-run: /dev/kvm not available, falling back to emulation" >&2 + ACCEL=tcg CPU=max +fi + +# memory-backend=mem gives virtiofsd a shareable view of the guest's memory, as +# vhost-user requires. No initrd is needed because the Debian kernel has +# fuse/virtiofs and the virtio transports built in, and can mount a non-block +# root filesystem by itself. -net none and -vga none drop devices the VM has no +# use for, including the network card whose option ROM the BIOS would otherwise +# probe for a boot image; sercon-port stops SeaBIOS writing its banner (and a +# terminal reset) to the serial console, which it does because there is no VGA. +qemu-system-x86_64 \ + -machine "accel=$ACCEL,memory-backend=mem" -cpu "$CPU" \ + -smp "$VM_CPUS" -m "$VM_MEMORY" \ + -nographic -monitor none -no-reboot -net none -vga none \ + -fw_cfg name=etc/sercon-port,string=0 \ + -object memory-backend-memfd,id=mem,size="${VM_MEMORY}M",share=on \ + -chardev socket,id=vfs,path="$JOB/vfs.sock" \ + -device vhost-user-fs-pci,queue-size=1024,chardev=vfs,tag=rootfs \ + -object rng-random,filename=/dev/urandom,id=rng0 \ + -device virtio-rng-pci,rng=rng0 \ + -kernel /boot/vmlinuz-qemu \ + -append "quiet console=ttyS0 root=rootfs rootfstype=virtiofs rw mitigations=off panic=-1 init=$JOB/init" + +read -r 2>/dev/null <"$JOB/rc" || echo "qemu-run: failed to read job exit status" >&2 +exit "${REPLY:-127}" diff --git a/.github/actions/openwrt-version/action.yaml b/.github/actions/openwrt-version/action.yaml new file mode 100644 index 0000000..39b30bb --- /dev/null +++ b/.github/actions/openwrt-version/action.yaml @@ -0,0 +1,20 @@ +name: openwrt version +description: Determines OPENWRT_VERSION from an override input or the Dockerfile + +inputs: + openwrt-version-override: + description: OpenWrt version number override + required: false + default: "" + +runs: + using: composite + steps: + - name: Determine the OpenWrt version + shell: bash + run: | + if [[ -n "${{ inputs.openwrt-version-override }}" ]]; then + echo "OPENWRT_VERSION=${{ inputs.openwrt-version-override }}" + else + grep '^ARG OPENWRT_VERSION=' .containers/matter-openwrt-build/Dockerfile | cut -c 5- + fi | tee -a "$GITHUB_ENV" diff --git a/.github/workflows/build-hostapd-hwsim-runner.yaml b/.github/workflows/build-hostapd-hwsim-runner.yaml new file mode 100644 index 0000000..66cb665 --- /dev/null +++ b/.github/workflows/build-hostapd-hwsim-runner.yaml @@ -0,0 +1,36 @@ +name: build hostapd-hwsim-runner container + +on: + pull_request: + paths: + - .containers/hostapd-hwsim-runner/** + - .github/workflows/build-hostapd-hwsim-runner.yaml + push: + paths: + - .containers/hostapd-hwsim-runner/** + - .github/workflows/build-hostapd-hwsim-runner.yaml + workflow_dispatch: + +permissions: + packages: write + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build and push + uses: elgohr/Publish-Docker-Github-Action@v5 + with: + name: project-chip/hostapd-hwsim-runner + context: .containers/hostapd-hwsim-runner + registry: ghcr.io + tags: "latest,${{ github.sha }}" + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + no_push: ${{ github.repository_owner != 'project-chip' || github.event_name == 'pull_request' || github.event.ref != 'refs/heads/main' }} diff --git a/.github/workflows/build-matter-openwrt-build.yaml b/.github/workflows/build-matter-openwrt-build.yaml index 21388e8..3e6a3d5 100644 --- a/.github/workflows/build-matter-openwrt-build.yaml +++ b/.github/workflows/build-matter-openwrt-build.yaml @@ -28,16 +28,10 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - - name: Prepare meta-data - id: prepare - shell: bash - run: | - # Determine OPENWRT_VERSION from override input or Dockerfile - if [[ -n "${{ inputs.openwrt-version-override }}" ]]; then - echo "OPENWRT_VERSION=${{ inputs.openwrt-version-override }}" - else - grep '^ARG OPENWRT_VERSION=' .containers/matter-openwrt-build/Dockerfile | cut -c 5- - fi | tee -a "$GITHUB_ENV" + - name: Determine OpenWrt version + uses: ./.github/actions/openwrt-version + with: + openwrt-version-override: ${{ inputs.openwrt-version-override }} - name: Build and push uses: elgohr/Publish-Docker-Github-Action@v5 diff --git a/.github/workflows/build-packages.yaml b/.github/workflows/build-packages.yaml index e80b55b..4df065c 100644 --- a/.github/workflows/build-packages.yaml +++ b/.github/workflows/build-packages.yaml @@ -3,6 +3,11 @@ name: build matter packages on: pull_request: push: + workflow_dispatch: + inputs: + openwrt-version-override: + type: string + description: OpenWrt version number override jobs: build: @@ -11,6 +16,11 @@ jobs: - name: Checkout uses: actions/checkout@v6 + - name: Determine OpenWrt version + uses: ./.github/actions/openwrt-version + with: + openwrt-version-override: ${{ inputs.openwrt-version-override }} + - name: Prepare log directory run: | mkdir -p ${{ runner.temp }}/logs @@ -22,11 +32,11 @@ jobs: - name: Build uses: addnab/docker-run-action@v3 with: - image: ghcr.io/project-chip/matter-openwrt-build:25.12.5 + image: ghcr.io/project-chip/matter-openwrt-build:${{ env.OPENWRT_VERSION }} options: --volume ${{ github.workspace }}:/workspace --volume ${{ runner.temp }}/logs:/builder/logs shell: bash run: | - set -x + set -eux echo "src-link --force matter /workspace" >>feeds.conf ./scripts/feeds update matter ./scripts/feeds install -a -p matter diff --git a/.github/workflows/hostapd-hwsim-tests.yaml b/.github/workflows/hostapd-hwsim-tests.yaml new file mode 100644 index 0000000..4faa5e4 --- /dev/null +++ b/.github/workflows/hostapd-hwsim-tests.yaml @@ -0,0 +1,108 @@ +name: hostapd hwsim tests + +on: + pull_request: + paths: + - .containers/matter-openwrt-build/Dockerfile # OPENWRT_VERSION + - .github/workflows/hostapd-hwsim-tests.yaml + - include/overlay* + - overlay/hostapd/** + push: + workflow_dispatch: + inputs: + openwrt-version-override: + type: string + description: OpenWrt version number override + runner-version-override: + type: string + description: hwsim runner version override + +jobs: + prepare-source: + # Prepare a patched hostapd source tree via the OpenWrt SDK and package it. + # This ensures the code that is tested matches what is built on OpenWrt. + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Determine OpenWrt version + uses: ./.github/actions/openwrt-version + with: + openwrt-version-override: ${{ inputs.openwrt-version-override }} + + - name: Prepare output directory + run: chmod a+w ${{ runner.temp }} + + # As in build-packages.yaml, only this step runs in the container, because + # the buildbot user owning the SDK does not match the runner's user. + - name: Prepare hostapd source + uses: addnab/docker-run-action@v3 + with: + image: ghcr.io/project-chip/matter-openwrt-build:${{ env.OPENWRT_VERSION }} + options: --volume ${{ github.workspace }}:/workspace --volume ${{ runner.temp }}:/out + shell: bash + run: | + set -eux; shopt -s nullglob + echo "src-link --force matter /workspace" >>feeds.conf + ./scripts/feeds update matter + ./scripts/feeds install -a -p matter + # Select any single hostapd variant, source prep is uniform across variants. + printf '%s\n' CONFIG_ALL=n CONFIG_PACKAGE_wpad=y >.config + make defconfig + make package/hostapd/prepare V=s + src=(build_dir/target-*/hostapd-*/hostapd-*) + test "${#src[@]}" -gt 0 + tar -C "$(dirname "${src[0]}")" -czf /out/hostapd-src.tar.gz "$(basename "${src[0]}")" + + - name: Upload hostapd source + uses: actions/upload-artifact@v7 + with: + path: ${{ runner.temp }}/hostapd-src.tar.gz + archive: false + retention-days: 1 + + build-and-test: + # Build hostapd/wpa_supplicant from the prepared source tree and run hwsim + # tests under qemu. Running under qemu is necessary because hosted GitHub + # runners do not have the mac80211_hwsim module available. + needs: prepare-source + runs-on: ubuntu-latest + container: + image: ghcr.io/project-chip/hostapd-hwsim-runner:${{ inputs.runner-version-override || 'latest' }} + options: --device /dev/kvm # enable KVM acceleration in qemu + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + tls: [openssl, mbedtls, wolfssl] + steps: + - name: Download hostapd source + uses: actions/download-artifact@v8 + with: + name: hostapd-src.tar.gz + path: ${{ runner.temp }} + + - name: Build and test + timeout-minutes: 20 + run: | + set -eux + tar -xf "$RUNNER_TEMP/hostapd-src.tar.gz" --strip-components=1 + cd tests/hwsim + ./build.sh --force-config=${{ matrix.tls }} + # Run tests under qemu (for mac80211_hwsim) and with faketime (to work + # around the expired pre-generated certificates used by some tests). + qemu-run faketime 2026-01-01 ./run-all.sh 'ap_eap_tls_cert_pin*' + + - name: Prepare test logs + if: always() + run: rm -f tests/hwsim/logs/current # symlink, would duplicate files in the zip + + - name: Upload test logs + if: always() + uses: actions/upload-artifact@v7 + with: + name: hwsim-logs-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.tls }} + path: tests/hwsim/logs + if-no-files-found: warn + retention-days: 14 diff --git a/overlay/hostapd/patches/o002-ucode-ubus-compile-guards.patch b/overlay/hostapd/patches/o002-ucode-ubus-compile-guards.patch new file mode 100644 index 0000000..aa677b8 --- /dev/null +++ b/overlay/hostapd/patches/o002-ucode-ubus-compile-guards.patch @@ -0,0 +1,103 @@ +From 6ad474677a58fa7122c253905beb270c8b9093e7 Mon Sep 17 00:00:00 2001 +From: Karsten Sperling +Date: Wed, 22 Jul 2026 21:37:40 +1200 +Subject: [PATCH] Add missing ucode / ubus compile guards + +This makes it possible to build standalone binaries for hwsim testing +that don't have runtime dependencies on ucode or ubus. + +Also fix the guards for some symbols that were narrowed incorrectly by +252-disable_ctrl_iface_mib.patch, those functions should not be +conditional on CONFIG_CTRL_IFACE_MIB. +--- + hostapd/Makefile | 9 +++++++++ + hostapd/main.c | 4 +++- + wpa_supplicant/Makefile | 3 +++ + wpa_supplicant/ap.c | 4 ++++ + 4 files changed, 19 insertions(+), 1 deletion(-) + +diff --git a/hostapd/Makefile b/hostapd/Makefile +index 28ed8e16c..c277d070a 100644 +--- a/hostapd/Makefile ++++ b/hostapd/Makefile +@@ -63,9 +63,15 @@ endif + OBJS += main.o + OBJS += config_file.o + ++# The standalone RADIUS frontend depends on libubox (which is only pulled in ++# via NEED_ULOOP if CONFIG_UBUS or CONFIG_UCODE is enabled), and does not have ++# its own .config option. Enable it if CONFIG_UBUS || CONFIG_UCODE. ++ifneq ($(CONFIG_UBUS)$(CONFIG_UCODE),) + ifdef CONFIG_RADIUS_SERVER ++CFLAGS += -DRADIUS_SERVER_STANDALONE + OBJS += radius.o + endif ++endif + + OBJS += ../src/ap/hostapd.o + OBJS += ../src/ap/wpa_auth_glue.o +@@ -183,6 +189,9 @@ CFLAGS += -DUCODE_SUPPORT + OBJS += ../src/utils/ucode.o + OBJS += ../src/ap/ucode.o + NEED_ULOOP:=y ++else ++# Work around unguarded includes in src/utils/ucode.h ++CFLAGS += -D__HOSTAPD_UTILS_UCODE_H + endif + + ifdef NEED_ULOOP +diff --git a/hostapd/main.c b/hostapd/main.c +index c59c949cc..809db3879 100644 +--- a/hostapd/main.c ++++ b/hostapd/main.c +@@ -40,7 +40,9 @@ struct hapd_global { + + static struct hapd_global global; + ++#ifdef RADIUS_SERVER_STANDALONE + extern int radius_main(int argc, char **argv); ++#endif + + #ifndef CONFIG_NO_HOSTAPD_LOGGER + static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module, +@@ -839,7 +841,7 @@ int main(int argc, char *argv[]) + if (os_program_init()) + return -1; + +-#ifdef RADIUS_SERVER ++#ifdef RADIUS_SERVER_STANDALONE + if (strstr(argv[0], "radius")) + return radius_main(argc, argv); + #endif +diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile +index 0abb12292..8c5a3b8f3 100644 +--- a/wpa_supplicant/Makefile ++++ b/wpa_supplicant/Makefile +@@ -197,6 +197,9 @@ OBJS += ../src/utils/ucode.o + OBJS += ../src/utils/uloop.o + OBJS += ucode.o + LIBS += -lubox ++else ++# Work around unguarded includes in src/utils/ucode.h ++CFLAGS += -D__HOSTAPD_UTILS_UCODE_H + endif + + ifdef CONFIG_CODE_COVERAGE +diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c +index ed96e0781..7716c8857 100644 +--- a/wpa_supplicant/ap.c ++++ b/wpa_supplicant/ap.c +@@ -1661,6 +1661,10 @@ int ap_ctrl_iface_bss_tm_req(struct wpa_supplicant *wpa_s, const char *buf) + + #endif /* CONFIG_WNM_AP */ + ++#endif /* CONFIG_CTRL_IFACE && CONFIG_CTRL_IFACE_MIB */ ++ ++ ++#ifdef CONFIG_CTRL_IFACE + + int ap_ctrl_iface_acl_add_mac(struct wpa_supplicant *wpa_s, + enum macaddr_acl acl_type, +-- +2.50.1 (Apple Git-155) + diff --git a/overlay/hostapd/patches/o003-test-dpp-compile-guard.patch b/overlay/hostapd/patches/o003-test-dpp-compile-guard.patch new file mode 100644 index 0000000..dded223 --- /dev/null +++ b/overlay/hostapd/patches/o003-test-dpp-compile-guard.patch @@ -0,0 +1,33 @@ +From 71412396becf86cdd4bd910f48a0bdebbe3f3ee5 Mon Sep 17 00:00:00 2001 +From: Karsten Sperling +Date: Fri, 14 Aug 2026 11:16:56 +1200 +Subject: [PATCH] tests: Guard crypto_ec_get_generator() with CONFIG_DPP + +The function is only used from DPP code, and its implementation in the +wolfSSL backend is guarded behind that define. Guard the call in +crypto_module_tests.c as well to avoid a linker error. + +Signed-off-by: Karsten Sperling +--- + src/crypto/crypto_module_tests.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/crypto/crypto_module_tests.c b/src/crypto/crypto_module_tests.c +index 07c36d850..da2670e96 100644 +--- a/src/crypto/crypto_module_tests.c ++++ b/src/crypto/crypto_module_tests.c +@@ -2509,7 +2509,10 @@ static int test_ecc(void) + || crypto_ec_get_order(e) == NULL + || crypto_ec_get_a(e) == NULL + || crypto_ec_get_b(e) == NULL +- || crypto_ec_get_generator(e) == NULL) { ++#ifdef CONFIG_DPP ++ || crypto_ec_get_generator(e) == NULL ++#endif ++ ) { + break; + } + #ifdef CONFIG_DPP +-- +2.50.1 (Apple Git-155) + diff --git a/overlay/hostapd/patches/o110-tests-force-tls-config.patch b/overlay/hostapd/patches/o110-tests-force-tls-config.patch new file mode 100644 index 0000000..5697fde --- /dev/null +++ b/overlay/hostapd/patches/o110-tests-force-tls-config.patch @@ -0,0 +1,211 @@ +From 29e568ffb993798d9436003dc6c11f8c1985170e Mon Sep 17 00:00:00 2001 +From: Karsten Sperling +Date: Thu, 23 Jul 2026 13:31:14 +1200 +Subject: [PATCH] tests: Allow build.sh --force-config to override CONFIG_TLS + +E.g. `build.sh --force-config=wolfssl` will re-install the example +configs but prepends CONFIG_TLS=wolfssl. The example configs have been +modified to not set CONFIG_TLS directly anymore; the Makefiles already +carry the openssl default. + +Different backends can be specified for hostapd and wpa_supplicant by +separating them with "/", e.g. `build.sh --force-config=wolfssl/openssl` +will build hostapd with wolfSSL and wpa_supplicant with OpenSSL. + +The --force-config argument can also be passed to run-all.sh, and will +be forwarded to build.sh. + +Also disable DPP in the example configs when using wolfSSL, since the +necessary hpke_* functions are not implemented in that backend. + +Signed-off-by: Karsten Sperling +--- + tests/hwsim/build.sh | 49 +++++++++++++++++++---- + tests/hwsim/example-hostapd.config | 5 ++- + tests/hwsim/example-wpa_supplicant.config | 5 ++- + tests/hwsim/run-all.sh | 15 ++++++- + 4 files changed, 64 insertions(+), 10 deletions(-) + +diff --git a/tests/hwsim/build.sh b/tests/hwsim/build.sh +index cb4700166..170581373 100755 +--- a/tests/hwsim/build.sh ++++ b/tests/hwsim/build.sh +@@ -6,12 +6,33 @@ cd $(dirname $0) + + usage() + { +- echo "$0 [-c | --codecov] [-f | --force-config]" ++ echo "$0 [-c | --codecov] [-f | --force-config[=|/]]" + exit 1 + } + ++# Re-derive $2 (hostapd/.config or wpa_supplicant/.config) from $1 ++# (the example config), optionally overriding CONFIG_TLS to $3 ++sync_config() ++{ ++ example="$1" ++ config="$2" ++ tls="$3" ++ ++ tmp="$(mktemp)" ++ { ++ [ -n "$tls" ] && echo "CONFIG_TLS=$tls" ++ cat "$example" ++ } >"$tmp" ++ ++ if [ ! -e "$config" ] || ! cmp "$tmp" "$config" >/dev/null 2>&1; then ++ cp "$tmp" "$config" ++ fi ++ rm -f "$tmp" ++} ++ + use_lcov=0 + force_config=0 ++force_tls="" + while [ "$1" != "" ]; do + case $1 in + -c | --codecov ) shift +@@ -20,12 +41,30 @@ while [ "$1" != "" ]; do + ;; + -f | --force-config ) shift + force_config=1 ++ force_tls="" + echo "$0: force copy config specified" + ;; ++ --force-config=* ) ++ force_config=1 ++ force_tls=${1#--force-config=} ++ shift ++ echo "$0: force copy config specified (TLS backend: $force_tls)" ++ ;; + * ) usage + esac + done + ++case $force_tls in ++ */*) ++ ap_tls=${force_tls%%/*} ++ sup_tls=${force_tls#*/} ++ ;; ++ * ) ++ ap_tls=$force_tls ++ sup_tls=$force_tls ++ ;; ++esac ++ + JOBS=`nproc` + if [ -z "$ABC" ]; then + JOBS=8 +@@ -46,9 +85,7 @@ make QUIET=1 CONFIG_NO_BROWSER=1 + echo "Building hostapd" + cd ../../hostapd + if [ ! -e .config -o $force_config -eq 1 ]; then +- if ! cmp ../tests/hwsim/example-hostapd.config .config >/dev/null 2>&1 ; then +- cp ../tests/hwsim/example-hostapd.config .config +- fi ++ sync_config ../tests/hwsim/example-hostapd.config .config "$ap_tls" + fi + + if [ $use_lcov -eq 1 ]; then +@@ -64,9 +101,7 @@ make QUIET=1 -j$JOBS hostapd hostapd_cli hlr_auc_gw + echo "Building wpa_supplicant" + cd ../wpa_supplicant + if [ ! -e .config -o $force_config -eq 1 ]; then +- if ! cmp ../tests/hwsim/example-wpa_supplicant.config .config >/dev/null 2>&1 ; then +- cp ../tests/hwsim/example-wpa_supplicant.config .config +- fi ++ sync_config ../tests/hwsim/example-wpa_supplicant.config .config "$sup_tls" + fi + + if [ $use_lcov -eq 1 ]; then +diff --git a/tests/hwsim/example-hostapd.config b/tests/hwsim/example-hostapd.config +index 20561a410..a2b526a27 100644 +--- a/tests/hwsim/example-hostapd.config ++++ b/tests/hwsim/example-hostapd.config +@@ -8,7 +8,7 @@ CONFIG_RSN_PREAUTH=y + #CONFIG_TLS=internal + #CONFIG_INTERNAL_LIBTOMMATH=y + #CONFIG_INTERNAL_LIBTOMMATH_FAST=y +-CONFIG_TLS=openssl ++#CONFIG_TLS=openssl + + CONFIG_EAP=y + CONFIG_ERP=y +@@ -113,9 +113,12 @@ CONFIG_TAXONOMY=y + CONFIG_FILS=y + CONFIG_FILS_SK_PFS=y + CONFIG_OWE=y ++# HPKE (used by DPP) is not implemented for the wolfssl TLS backend. ++ifneq ($(CONFIG_TLS), wolfssl) + CONFIG_DPP=y + CONFIG_DPP2=y + CONFIG_DPP3=y ++endif + CONFIG_WEP=y + CONFIG_PASN=y + CONFIG_AIRTIME_POLICY=y +diff --git a/tests/hwsim/example-wpa_supplicant.config b/tests/hwsim/example-wpa_supplicant.config +index 9606ce7eb..31bd6c739 100644 +--- a/tests/hwsim/example-wpa_supplicant.config ++++ b/tests/hwsim/example-wpa_supplicant.config +@@ -1,6 +1,6 @@ + #CC=ccache gcc + +-CONFIG_TLS=openssl ++#CONFIG_TLS=openssl + #CONFIG_TLS=wolfssl + #CONFIG_TLS=mbedtls + #CONFIG_TLS=internal +@@ -156,9 +156,12 @@ CONFIG_FILS=y + CONFIG_FILS_SK_PFS=y + CONFIG_PMKSA_CACHE_EXTERNAL=y + CONFIG_OWE=y ++# HPKE (used by DPP) is not implemented for the wolfssl TLS backend. ++ifneq ($(CONFIG_TLS), wolfssl) + CONFIG_DPP=y + CONFIG_DPP2=y + CONFIG_DPP3=y ++endif + CONFIG_WEP=y + CONFIG_PASN=y + CONFIG_NAN_USD=y +diff --git a/tests/hwsim/run-all.sh b/tests/hwsim/run-all.sh +index 507488041..8a6154ef0 100755 +--- a/tests/hwsim/run-all.sh ++++ b/tests/hwsim/run-all.sh +@@ -34,6 +34,7 @@ usage() + { + echo "$0 [-v | --valgrind | valgrind] [-t | --trace | trace]" + echo "\t[-n | --channels ] [-B | --build]" ++ echo "\t[--force-config[=|/]]" + echo "\t[-c | --codecov ] [run-tests.py parameters]" + exit 1 + } +@@ -69,11 +70,23 @@ while [ "$1" != "" ]; do + echo "$0: build before running tests" + BUILD=build + ;; ++ --force-config) # don't handle "-f", would shadow run-tests.py option ++ shift ++ echo "$0: build before running tests (force copy config)" ++ BUILD=build ++ BUILD_ARGS="$BUILD_ARGS -f" ++ ;; ++ --force-config=*) ++ echo "$0: build before running tests (force copy config, TLS backend: ${1#--force-config=})" ++ BUILD=build ++ BUILD_ARGS="$BUILD_ARGS $1" ++ shift ++ ;; + -c | --codecov) + shift + echo "$0: using code coverage" + CODECOV=lcov +- BUILD_ARGS=-c ++ BUILD_ARGS="$BUILD_ARGS -c" + ;; + -h | --help) + usage +-- +2.50.1 (Apple Git-155) +