Skip to content

Commit fe87d4e

Browse files
committed
Add wolfGuard: native FIPS WireGuard driver for wolfIP
Core implementation (src/wolfguard/): - wg_crypto.c: FIPS crypto abstraction with PRIVATE_KEY_UNLOCK/LOCK for wolfSSL FIPS v6 compatibility - wg_noise.c: Noise_IKpsk2 handshake (create/consume initiation and response, session key derivation) - wg_cookie.c: mac1/mac2 validation, cookie reply for DoS protection - wg_packet.c: transport data encrypt/decrypt with replay counter - wg_timers.c: rekey, keepalive, retransmit, key zeroing state machine - wg_allowedips.c: flat-table longest-prefix-match for peer routing - wolfguard.c: device init, wg0 virtual interface, UDP outer transport, poll loop integration via wolfIP_recv_ex() Wire format matches kernel wolfGuard: - 32-byte MACs (full SHA-256 HMAC, not truncated to 16) - 16-byte AES-GCM IVs (AES_IV_SIZE, matching kernel ZeroNonce) - TAI64N timestamps with 0x400000000000000a epoch offset - 65-byte uncompressed P-256 public keys Tests: - unit_wolfguard.c: 38 unit tests covering crypto, noise handshake, cookies, allowed-IPs, replay counter, packet processing, timers - test_wolfguard_loopback.c: 3 integration tests (roundtrip, session lifecycle with rekey/reconnect, DoS cookie mechanism) - test_wolfguard_interop.c: bidirectional interop against the kernel wolfGuard module via TUN, tests both wolfIP-initiated and kernel-initiated handshakes with fresh key material Build & CI: - Makefile: wolfguard targets with ASan/UBSan variants - tools/scripts/test-interop-wolfguard.sh: end-to-end interop harness (builds wolfSSL + kernel module, loads modules, generates keys, runs two-phase bidirectional test) - .github/workflows/wolfguard.yml: CI for unit, loopback, and interop
1 parent c2db895 commit fe87d4e

18 files changed

Lines changed: 7734 additions & 1 deletion

.github/workflows/wolfguard.yml

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
name: wolfGuard tests
2+
3+
on:
4+
push:
5+
branches: [ 'master', 'main', 'release/**' ]
6+
pull_request:
7+
branches: [ '*' ]
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
wolfguard_unit:
15+
name: wolfGuard unit tests
16+
runs-on: ubuntu-latest
17+
timeout-minutes: 10
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
include:
22+
- name: "default"
23+
target: "unit-wolfguard"
24+
- name: "ASan"
25+
target: "unit-wolfguard-asan"
26+
- name: "UBSan"
27+
target: "unit-wolfguard-ubsan"
28+
29+
steps:
30+
- uses: actions/checkout@v4
31+
with:
32+
submodules: true
33+
34+
- name: Install dependencies
35+
run: |
36+
sudo apt-get update
37+
sudo apt-get install -y build-essential autoconf automake libtool pkg-config check
38+
39+
- name: Clone and build wolfSSL from nightly-snapshot
40+
run: |
41+
git clone --depth=1 https://github.com/wolfssl/wolfssl --branch nightly-snapshot /tmp/wolfssl
42+
cd /tmp/wolfssl
43+
./autogen.sh
44+
./configure
45+
make -j$(nproc)
46+
sudo make install
47+
sudo ldconfig
48+
49+
- name: Build wolfGuard unit tests (${{ matrix.name }})
50+
run: make ${{ matrix.target }}
51+
52+
- name: Run wolfGuard unit tests
53+
timeout-minutes: 5
54+
run: ./build/test/unit-wolfguard
55+
56+
wolfguard_loopback:
57+
name: wolfGuard loopback tests
58+
runs-on: ubuntu-latest
59+
timeout-minutes: 10
60+
strategy:
61+
fail-fast: false
62+
matrix:
63+
include:
64+
- name: "default"
65+
target: "test-wolfguard-loopback"
66+
- name: "ASan"
67+
target: "test-wolfguard-loopback-asan"
68+
- name: "UBSan"
69+
target: "test-wolfguard-loopback-ubsan"
70+
71+
steps:
72+
- uses: actions/checkout@v4
73+
with:
74+
submodules: true
75+
76+
- name: Install dependencies
77+
run: |
78+
sudo apt-get update
79+
sudo apt-get install -y build-essential autoconf automake libtool pkg-config check
80+
81+
- name: Clone and build wolfSSL from nightly-snapshot
82+
run: |
83+
git clone --depth=1 https://github.com/wolfssl/wolfssl --branch nightly-snapshot /tmp/wolfssl
84+
cd /tmp/wolfssl
85+
./autogen.sh
86+
./configure
87+
make -j$(nproc)
88+
sudo make install
89+
sudo ldconfig
90+
91+
- name: Build wolfGuard loopback test (${{ matrix.name }})
92+
run: make ${{ matrix.target }}
93+
94+
- name: Run wolfGuard loopback test
95+
timeout-minutes: 5
96+
run: ./build/test/test-wolfguard-loopback
97+
98+
wolfguard_interop:
99+
name: wolfGuard interop (kernel module)
100+
runs-on: ubuntu-latest
101+
timeout-minutes: 30
102+
needs: [wolfguard_unit, wolfguard_loopback]
103+
104+
steps:
105+
- uses: actions/checkout@v4
106+
with:
107+
submodules: true
108+
109+
- name: Run wolfGuard interop test
110+
timeout-minutes: 25
111+
run: sudo ./tools/scripts/test-interop-wolfguard.sh

Makefile

Lines changed: 109 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,17 @@ leaksan:LDFLAGS+=-fsanitize=leak
202202
ESP_CFLAGS = \
203203
-DWOLFIP_ESP -DWOLFSSL_WOLFIP
204204

205+
# wolfGuard (FIPS WireGuard)
206+
WOLFGUARD_CFLAGS = -DWOLFGUARD -Wno-cpp
207+
WOLFGUARD_SRC := src/wolfguard/wolfguard.c \
208+
src/wolfguard/wg_noise.c \
209+
src/wolfguard/wg_crypto.c \
210+
src/wolfguard/wg_cookie.c \
211+
src/wolfguard/wg_allowedips.c \
212+
src/wolfguard/wg_packet.c \
213+
src/wolfguard/wg_timers.c
214+
WOLFGUARD_OBJ := $(patsubst src/%.c,build/wolfguard/%.o,$(WOLFGUARD_SRC))
215+
205216
# Test
206217

207218
ifeq ($(CHECK_PKG_LIBS),)
@@ -453,8 +464,105 @@ install:
453464
install libwolfip.so $(PREFIX)/lib
454465
ldconfig
455466

467+
# wolfGuard object files
468+
build/wolfguard/%.o: src/%.c
469+
@mkdir -p `dirname $@` || true
470+
@echo "[CC] $< (wolfguard)"
471+
@$(CC) $(CFLAGS) $(WOLFGUARD_CFLAGS) -c $< -o $@
472+
473+
# wolfGuard unit tests
474+
WG_UNIT_CHECK_CFLAGS := $(CHECK_PKG_CFLAGS)
475+
ifeq ($(UNAME_S),Darwin)
476+
ifneq ($(CHECK_PREFIX),)
477+
WG_UNIT_CHECK_CFLAGS += -I$(CHECK_PREFIX)/include
478+
endif
479+
endif
480+
481+
unit-wolfguard: build/test/unit-wolfguard
482+
483+
build/test/unit-wolfguard: src/test/unit/unit_wolfguard.c
484+
@mkdir -p build/test/
485+
@echo "[CC] unit_wolfguard.c"
486+
@$(CC) $(CFLAGS) $(WOLFGUARD_CFLAGS) $(WG_UNIT_CHECK_CFLAGS) \
487+
-c src/test/unit/unit_wolfguard.c -o build/test/unit_wolfguard.o
488+
@echo "[LD] $@"
489+
@$(CC) build/test/unit_wolfguard.o -o $@ \
490+
$(UNIT_LDFLAGS) $(LDFLAGS) $(UNIT_LIBS) -lwolfssl
491+
492+
clean-unit-wolfguard:
493+
@rm -f build/test/unit-wolfguard build/test/unit_wolfguard.o
494+
495+
unit-wolfguard-asan: CFLAGS+=-fsanitize=address
496+
unit-wolfguard-asan: LDFLAGS+=-fsanitize=address $(UNIT_LIBS)
497+
unit-wolfguard-asan: clean-unit-wolfguard build/test/unit-wolfguard
498+
499+
unit-wolfguard-ubsan: CFLAGS+=-fsanitize=undefined -fno-sanitize-recover=all
500+
unit-wolfguard-ubsan: LDFLAGS+=-fsanitize=undefined $(UNIT_LIBS)
501+
unit-wolfguard-ubsan: clean-unit-wolfguard build/test/unit-wolfguard
502+
503+
# wolfGuard integration tests (loopback)
504+
test-wolfguard-loopback: build/test/test-wolfguard-loopback
505+
506+
build/test/test-wolfguard-loopback: src/test/test_wolfguard_loopback.c
507+
@mkdir -p build/test/
508+
@echo "[CC] test_wolfguard_loopback.c"
509+
@$(CC) $(CFLAGS) $(WOLFGUARD_CFLAGS) $(WG_UNIT_CHECK_CFLAGS) \
510+
-c src/test/test_wolfguard_loopback.c -o build/test/test_wolfguard_loopback.o
511+
@echo "[LD] $@"
512+
@$(CC) build/test/test_wolfguard_loopback.o -o $@ \
513+
$(UNIT_LDFLAGS) $(LDFLAGS) $(UNIT_LIBS) -lwolfssl
514+
515+
clean-test-wolfguard-loopback:
516+
@rm -f build/test/test-wolfguard-loopback build/test/test_wolfguard_loopback.o
517+
518+
test-wolfguard-loopback-asan: CFLAGS+=-fsanitize=address
519+
test-wolfguard-loopback-asan: LDFLAGS+=-fsanitize=address $(UNIT_LIBS)
520+
test-wolfguard-loopback-asan: clean-test-wolfguard-loopback build/test/test-wolfguard-loopback
521+
522+
test-wolfguard-loopback-ubsan: CFLAGS+=-fsanitize=undefined -fno-sanitize-recover=all
523+
test-wolfguard-loopback-ubsan: LDFLAGS+=-fsanitize=undefined $(UNIT_LIBS)
524+
test-wolfguard-loopback-ubsan: clean-test-wolfguard-loopback build/test/test-wolfguard-loopback
525+
526+
# wolfGuard benchmark
527+
bench-wolfguard: build/test/bench-wolfguard
528+
529+
build/test/bench-wolfguard: src/test/bench_wolfguard.c
530+
@mkdir -p build/test/
531+
@echo "[CC] bench_wolfguard.c"
532+
@$(CC) $(CFLAGS) -O2 $(WOLFGUARD_CFLAGS) \
533+
-c src/test/bench_wolfguard.c -o build/test/bench_wolfguard.o
534+
@echo "[LD] $@"
535+
@$(CC) build/test/bench_wolfguard.o -o $@ \
536+
$(LDFLAGS) -lwolfssl
537+
538+
clean-bench-wolfguard:
539+
@rm -f build/test/bench-wolfguard build/test/bench_wolfguard.o
540+
541+
# wolfGuard interop test (wolfIP <-> kernel wolfGuard via TUN)
542+
test-wolfguard-interop: build/test/test-wolfguard-interop
543+
544+
build/test/test-wolfguard-interop: src/test/test_wolfguard_interop.c src/port/posix/linux_tun.c
545+
@mkdir -p build/test/
546+
@echo "[CC] test_wolfguard_interop.c"
547+
@$(CC) $(CFLAGS) $(WOLFGUARD_CFLAGS) \
548+
-c src/test/test_wolfguard_interop.c -o build/test/test_wolfguard_interop.o
549+
@echo "[CC] linux_tun.c"
550+
@$(CC) $(CFLAGS) $(WOLFGUARD_CFLAGS) \
551+
-c src/port/posix/linux_tun.c -o build/test/linux_tun.o
552+
@echo "[LD] $@"
553+
@$(CC) build/test/test_wolfguard_interop.o build/test/linux_tun.o -o $@ \
554+
$(LDFLAGS) -lwolfssl
555+
556+
clean-test-wolfguard-interop:
557+
@rm -f build/test/test-wolfguard-interop build/test/test_wolfguard_interop.o build/test/linux_tun.o
558+
456559
.PHONY: clean all static cppcheck cov autocov unit-asan unit-ubsan unit-leaksan clean-unit \
457-
unit-esp-asan unit-esp-ubsan unit-esp-leaksan clean-unit-esp
560+
unit-esp-asan unit-esp-ubsan unit-esp-leaksan clean-unit-esp \
561+
unit-wolfguard unit-wolfguard-asan unit-wolfguard-ubsan clean-unit-wolfguard \
562+
test-wolfguard-loopback test-wolfguard-loopback-asan test-wolfguard-loopback-ubsan \
563+
clean-test-wolfguard-loopback \
564+
bench-wolfguard clean-bench-wolfguard \
565+
test-wolfguard-interop clean-test-wolfguard-interop
458566

459567
cppcheck:
460568
$(CPPCHECK) $(CPPCHECK_FLAGS) src/ 2>cppcheck_results.xml

README.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,65 @@ A single network interface can be associated with the device.
3939
| **Application** | DHCP | Client only (DORA) | [RFC 2131](https://datatracker.ietf.org/doc/html/rfc2131) |
4040
| **Application** | DNS | A and PTR record queries (client) | [RFC 1035](https://datatracker.ietf.org/doc/html/rfc1035) |
4141
| **Application** | HTTP/HTTPS | Server with wolfSSL TLS support | [RFC 9110](https://datatracker.ietf.org/doc/html/rfc9110) |
42+
| **VPN** | wolfGuard | FIPS-compliant WireGuard (P-256, AES-256-GCM, SHA-256) | [Wolfguard](https://www.github.com/wolfssl/wireguard) |
4243

44+
## wolfGuard (FIPS WireGuard)
45+
46+
wolfIP includes a native wolfGuard driver, which is a FIPS-compliant implementation
47+
of the WireGuard VPN protocol that operates entirely within the wolfIP stack.
48+
wolfGuard uses wolfSSL/wolfCrypt FIPS-certified cryptographic primitives:
49+
50+
| WireGuard Primitive | wolfGuard FIPS Replacement |
51+
|---|---|
52+
| Curve25519 | ECDH with SECP256R1 (P-256) |
53+
| ChaCha20-Poly1305 | AES-256-GCM |
54+
| BLAKE2s | SHA-256 |
55+
| BLAKE2s-HMAC | HMAC-SHA-256 |
56+
57+
wolfGuard is NOT interoperable with standard WireGuard peers. It interoperates
58+
only with other wolfGuard instances (including the
59+
[wolfGuard kernel module](https://github.com/wolfssl/wolfguard)).
60+
61+
### Building with wolfGuard
62+
63+
wolfGuard requires wolfSSL with `--enable-wolfguard`:
64+
65+
```sh
66+
make unit-wolfguard # unit tests
67+
make test-wolfguard-loopback # loopback integration tests
68+
make test-wolfguard-interop # interop test binary (used by the script below)
69+
```
70+
71+
### Interop testing against the kernel wolfGuard module
72+
73+
The interop test validates bidirectional tunnel connectivity between
74+
wolfIP and the Linux kernel wolfGuard module. It tests both handshake
75+
directions (wolfIP as initiator and as responder) and verifies encrypted
76+
data flows end-to-end.
77+
78+
```sh
79+
# Requires root, kernel headers, and network access (to clone wolfSSL/wolfGuard)
80+
sudo ./tools/scripts/test-interop-wolfguard.sh
81+
```
82+
83+
The script builds wolfSSL and the wolfGuard kernel module from source, loads
84+
them, generates fresh P-256 keys, and runs a two-phase interop test:
85+
86+
1. **wolfIP initiates** — wolfIP creates a handshake, sends a UDP probe
87+
through the tunnel, and verifies the echo reply.
88+
2. **Kernel initiates** — the kernel creates a fresh handshake to wolfIP,
89+
sends data through the tunnel, and wolfIP verifies receipt.
90+
91+
### Compile-time configuration
92+
93+
```c
94+
/* config.h */
95+
#define WOLFGUARD 1 /* Enable wolfGuard support */
96+
#define WOLFGUARD_MAX_PEERS 8 /* Max peers per device */
97+
#define WOLFGUARD_MAX_ALLOWED_IPS 32 /* Max allowed-IP entries */
98+
#define WOLFGUARD_STAGED_PACKETS 16 /* Packets queued during handshake */
99+
#define WOLFGUARD_COUNTER_WINDOW 1024 /* Replay window size (bits) */
100+
```
43101

44102
## Functional tests with `LD_PRELOAD`
45103

0 commit comments

Comments
 (0)