Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions .github/workflows/wolfguard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: wolfGuard tests

on:
push:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
wolfguard_unit:
name: wolfGuard unit tests
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
include:
- name: "default"
target: "unit-wolfguard"
- name: "ASan"
target: "unit-wolfguard-asan"
- name: "UBSan"
target: "unit-wolfguard-ubsan"

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential autoconf automake libtool pkg-config check

- name: Clone and build wolfSSL from nightly-snapshot
run: |
git clone --depth=1 https://github.com/wolfssl/wolfssl --branch nightly-snapshot /tmp/wolfssl
cd /tmp/wolfssl
./autogen.sh
./configure
make -j$(nproc)
sudo make install
sudo ldconfig

- name: Build wolfGuard unit tests (${{ matrix.name }})
run: make ${{ matrix.target }}

- name: Run wolfGuard unit tests
timeout-minutes: 5
run: ./build/test/unit-wolfguard

wolfguard_loopback:
name: wolfGuard loopback tests
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
include:
- name: "default"
target: "test-wolfguard-loopback"
- name: "ASan"
target: "test-wolfguard-loopback-asan"
- name: "UBSan"
target: "test-wolfguard-loopback-ubsan"

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential autoconf automake libtool pkg-config check

- name: Clone and build wolfSSL from nightly-snapshot
run: |
git clone --depth=1 https://github.com/wolfssl/wolfssl --branch nightly-snapshot /tmp/wolfssl
cd /tmp/wolfssl
./autogen.sh
./configure
make -j$(nproc)
sudo make install
sudo ldconfig

- name: Build wolfGuard loopback test (${{ matrix.name }})
run: make ${{ matrix.target }}

- name: Run wolfGuard loopback test
timeout-minutes: 5
run: ./build/test/test-wolfguard-loopback

wolfguard_interop:
name: wolfGuard interop (kernel module)
runs-on: ubuntu-latest
timeout-minutes: 30
needs: [wolfguard_unit, wolfguard_loopback]

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Run wolfGuard interop test
timeout-minutes: 25
run: sudo ./tools/scripts/test-interop-wolfguard.sh
110 changes: 109 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,17 @@ leaksan:LDFLAGS+=-fsanitize=leak
ESP_CFLAGS = \
-DWOLFIP_ESP -DWOLFSSL_WOLFIP

# wolfGuard (FIPS WireGuard)
WOLFGUARD_CFLAGS = -DWOLFGUARD -Wno-cpp
WOLFGUARD_SRC := src/wolfguard/wolfguard.c \
src/wolfguard/wg_noise.c \
src/wolfguard/wg_crypto.c \
src/wolfguard/wg_cookie.c \
src/wolfguard/wg_allowedips.c \
src/wolfguard/wg_packet.c \
src/wolfguard/wg_timers.c
WOLFGUARD_OBJ := $(patsubst src/%.c,build/wolfguard/%.o,$(WOLFGUARD_SRC))

# Test

ifeq ($(CHECK_PKG_LIBS),)
Expand Down Expand Up @@ -453,8 +464,105 @@ install:
install libwolfip.so $(PREFIX)/lib
ldconfig

# wolfGuard object files
build/wolfguard/%.o: src/%.c
@mkdir -p `dirname $@` || true
@echo "[CC] $< (wolfguard)"
@$(CC) $(CFLAGS) $(WOLFGUARD_CFLAGS) -c $< -o $@

# wolfGuard unit tests
WG_UNIT_CHECK_CFLAGS := $(CHECK_PKG_CFLAGS)
ifeq ($(UNAME_S),Darwin)
ifneq ($(CHECK_PREFIX),)
WG_UNIT_CHECK_CFLAGS += -I$(CHECK_PREFIX)/include
endif
endif

unit-wolfguard: build/test/unit-wolfguard

build/test/unit-wolfguard: src/test/unit/unit_wolfguard.c
@mkdir -p build/test/
@echo "[CC] unit_wolfguard.c"
@$(CC) $(CFLAGS) $(WOLFGUARD_CFLAGS) $(WG_UNIT_CHECK_CFLAGS) \
-c src/test/unit/unit_wolfguard.c -o build/test/unit_wolfguard.o
@echo "[LD] $@"
@$(CC) build/test/unit_wolfguard.o -o $@ \
$(UNIT_LDFLAGS) $(LDFLAGS) $(UNIT_LIBS) -lwolfssl

clean-unit-wolfguard:
@rm -f build/test/unit-wolfguard build/test/unit_wolfguard.o

unit-wolfguard-asan: CFLAGS+=-fsanitize=address
unit-wolfguard-asan: LDFLAGS+=-fsanitize=address $(UNIT_LIBS)
unit-wolfguard-asan: clean-unit-wolfguard build/test/unit-wolfguard

unit-wolfguard-ubsan: CFLAGS+=-fsanitize=undefined -fno-sanitize-recover=all
unit-wolfguard-ubsan: LDFLAGS+=-fsanitize=undefined $(UNIT_LIBS)
unit-wolfguard-ubsan: clean-unit-wolfguard build/test/unit-wolfguard

# wolfGuard integration tests (loopback)
test-wolfguard-loopback: build/test/test-wolfguard-loopback

build/test/test-wolfguard-loopback: src/test/test_wolfguard_loopback.c
@mkdir -p build/test/
@echo "[CC] test_wolfguard_loopback.c"
@$(CC) $(CFLAGS) $(WOLFGUARD_CFLAGS) $(WG_UNIT_CHECK_CFLAGS) \
-c src/test/test_wolfguard_loopback.c -o build/test/test_wolfguard_loopback.o
@echo "[LD] $@"
@$(CC) build/test/test_wolfguard_loopback.o -o $@ \
$(UNIT_LDFLAGS) $(LDFLAGS) $(UNIT_LIBS) -lwolfssl

clean-test-wolfguard-loopback:
@rm -f build/test/test-wolfguard-loopback build/test/test_wolfguard_loopback.o

test-wolfguard-loopback-asan: CFLAGS+=-fsanitize=address
test-wolfguard-loopback-asan: LDFLAGS+=-fsanitize=address $(UNIT_LIBS)
test-wolfguard-loopback-asan: clean-test-wolfguard-loopback build/test/test-wolfguard-loopback

test-wolfguard-loopback-ubsan: CFLAGS+=-fsanitize=undefined -fno-sanitize-recover=all
test-wolfguard-loopback-ubsan: LDFLAGS+=-fsanitize=undefined $(UNIT_LIBS)
test-wolfguard-loopback-ubsan: clean-test-wolfguard-loopback build/test/test-wolfguard-loopback

# wolfGuard benchmark
bench-wolfguard: build/test/bench-wolfguard

build/test/bench-wolfguard: src/test/bench_wolfguard.c
@mkdir -p build/test/
@echo "[CC] bench_wolfguard.c"
@$(CC) $(CFLAGS) -O2 $(WOLFGUARD_CFLAGS) \
-c src/test/bench_wolfguard.c -o build/test/bench_wolfguard.o
@echo "[LD] $@"
@$(CC) build/test/bench_wolfguard.o -o $@ \
$(LDFLAGS) -lwolfssl

clean-bench-wolfguard:
@rm -f build/test/bench-wolfguard build/test/bench_wolfguard.o

# wolfGuard interop test (wolfIP <-> kernel wolfGuard via TUN)
test-wolfguard-interop: build/test/test-wolfguard-interop

build/test/test-wolfguard-interop: src/test/test_wolfguard_interop.c src/port/posix/linux_tun.c
@mkdir -p build/test/
@echo "[CC] test_wolfguard_interop.c"
@$(CC) $(CFLAGS) $(WOLFGUARD_CFLAGS) \
-c src/test/test_wolfguard_interop.c -o build/test/test_wolfguard_interop.o
@echo "[CC] linux_tun.c"
@$(CC) $(CFLAGS) $(WOLFGUARD_CFLAGS) \
-c src/port/posix/linux_tun.c -o build/test/linux_tun.o
@echo "[LD] $@"
@$(CC) build/test/test_wolfguard_interop.o build/test/linux_tun.o -o $@ \
$(LDFLAGS) -lwolfssl

clean-test-wolfguard-interop:
@rm -f build/test/test-wolfguard-interop build/test/test_wolfguard_interop.o build/test/linux_tun.o

.PHONY: clean all static cppcheck cov autocov unit-asan unit-ubsan unit-leaksan clean-unit \
unit-esp-asan unit-esp-ubsan unit-esp-leaksan clean-unit-esp
unit-esp-asan unit-esp-ubsan unit-esp-leaksan clean-unit-esp \
unit-wolfguard unit-wolfguard-asan unit-wolfguard-ubsan clean-unit-wolfguard \
test-wolfguard-loopback test-wolfguard-loopback-asan test-wolfguard-loopback-ubsan \
clean-test-wolfguard-loopback \
bench-wolfguard clean-bench-wolfguard \
test-wolfguard-interop clean-test-wolfguard-interop

cppcheck:
$(CPPCHECK) $(CPPCHECK_FLAGS) src/ 2>cppcheck_results.xml
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,65 @@ A single network interface can be associated with the device.
| **Application** | DHCP | Client only (DORA) | [RFC 2131](https://datatracker.ietf.org/doc/html/rfc2131) |
| **Application** | DNS | A and PTR record queries (client) | [RFC 1035](https://datatracker.ietf.org/doc/html/rfc1035) |
| **Application** | HTTP/HTTPS | Server with wolfSSL TLS support | [RFC 9110](https://datatracker.ietf.org/doc/html/rfc9110) |
| **VPN** | wolfGuard | FIPS-compliant WireGuard (P-256, AES-256-GCM, SHA-256) | [Wolfguard](https://www.github.com/wolfssl/wireguard) |

## wolfGuard (FIPS WireGuard)

wolfIP includes a native wolfGuard driver, which is a FIPS-compliant implementation
of the WireGuard VPN protocol that operates entirely within the wolfIP stack.
wolfGuard uses wolfSSL/wolfCrypt FIPS-certified cryptographic primitives:

| WireGuard Primitive | wolfGuard FIPS Replacement |
|---|---|
| Curve25519 | ECDH with SECP256R1 (P-256) |
| ChaCha20-Poly1305 | AES-256-GCM |
| BLAKE2s | SHA-256 |
| BLAKE2s-HMAC | HMAC-SHA-256 |

wolfGuard is NOT interoperable with standard WireGuard peers. It interoperates
only with other wolfGuard instances (including the
[wolfGuard kernel module](https://github.com/wolfssl/wolfguard)).

### Building with wolfGuard

wolfGuard requires wolfSSL with `--enable-wolfguard`:

```sh
make unit-wolfguard # unit tests
make test-wolfguard-loopback # loopback integration tests
make test-wolfguard-interop # interop test binary (used by the script below)
```

### Interop testing against the kernel wolfGuard module

The interop test validates bidirectional tunnel connectivity between
wolfIP and the Linux kernel wolfGuard module. It tests both handshake
directions (wolfIP as initiator and as responder) and verifies encrypted
data flows end-to-end.

```sh
# Requires root, kernel headers, and network access (to clone wolfSSL/wolfGuard)
sudo ./tools/scripts/test-interop-wolfguard.sh
```

The script builds wolfSSL and the wolfGuard kernel module from source, loads
them, generates fresh P-256 keys, and runs a two-phase interop test:

1. **wolfIP initiates** — wolfIP creates a handshake, sends a UDP probe
through the tunnel, and verifies the echo reply.
2. **Kernel initiates** — the kernel creates a fresh handshake to wolfIP,
sends data through the tunnel, and wolfIP verifies receipt.

### Compile-time configuration

```c
/* config.h */
#define WOLFGUARD 1 /* Enable wolfGuard support */
#define WOLFGUARD_MAX_PEERS 8 /* Max peers per device */
#define WOLFGUARD_MAX_ALLOWED_IPS 32 /* Max allowed-IP entries */
#define WOLFGUARD_STAGED_PACKETS 16 /* Packets queued during handshake */
#define WOLFGUARD_COUNTER_WINDOW 1024 /* Replay window size (bits) */
```

## Functional tests with `LD_PRELOAD`

Expand Down
Loading
Loading