GitHub - wolfSSL/wolfip: Lightweight TCP/IP stack with no dynamic memory allocations

4 min read Original article ↗

Description and project goals

wolfIP is a TCP/IP stack with no dynamic memory allocations, designed to be used in resource-constrained embedded systems.

Endpoint only mode is supported, which means that wolfip can be used to establish network connections but it does not route traffic between different network interfaces.

A single network interface can be associated with the device.

Features supported

  • BSD-like, non blocking socket API, with custom callbacks
  • No dynamic memory allocation
    • Fixed number of concurrent sockets
    • Pre-allocated buffers for packet processing in static memory

Protocols and RFCs

Layer Protocol Features RFC(s)
Data Link Ethernet II Frame encapsulation IEEE 802.3
Data Link ARP Address resolution, request/reply RFC 826
Network IPv4 Datagram delivery, TTL handling RFC 791
Network IPv4 Forwarding Multi-interface routing (optional) RFC 1812
Network ICMP Echo request/reply, TTL exceeded RFC 792
Network IPsec ESP Transport mode RFC 4303
Transport UDP Unicast datagrams, checksum RFC 768
Transport TCP Connection management, reliable delivery RFC 793, RFC 9293
Transport TCP Maximum Segment Size negotiation RFC 793
Transport TCP TCP Timestamps, RTT measurement, PAWS, Window Scaling RFC 7323
Transport TCP Retransmission timeout (RTO) computation RFC 6298, RFC 5681
Transport TCP TCP SACK RFC 2018, RFC 2883, RFC 6675
Transport TCP Congestion Control: Slow start, congestion avoidance RFC 5681
Transport TCP Fast Retransmit, triple duplicate ACK detection RFC 5681
Application DHCP Client only (DORA) RFC 2131
Application DNS A and PTR record queries (client) RFC 1035
Application HTTP/HTTPS Server with wolfSSL TLS support RFC 9110
VPN wolfGuard FIPS-compliant WireGuard (P-256, AES-256-GCM, SHA-256) Wolfguard

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).

Building with wolfGuard

wolfGuard requires wolfSSL with --enable-wolfguard:

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.

# 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

/* 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

The POSIX shim builds libwolfip.so, which can be injected in front of host tools so that calls to socket(2) and friends are redirected to the wolfIP stack and the TAP device (wtcp0). After running make:

sudo LD_PRELOAD=$PWD/libwolfip.so nc 10.10.10.2 80

The example above mirrors the existing nc-driven demos: any TCP sockets opened by the intercepted process are serviced by wolfIP instead of the host kernel.

Ping over the TAP device

ICMP datagram sockets can be validated the same way. With the TAP interface created automatically by the shim and the host endpoint configured in config.h (HOST_STACK_IP defaults to 10.10.10.1), run:

sudo LD_PRELOAD=$PWD/libwolfip.so ping -I wtcp0 -c5 10.10.10.1

The -I wtcp0 flag pins the test to the injected interface and -c5 generates five echo requests. Successful replies confirm the ICMP datagram socket support end-to-end through the tap device.

FreeRTOS Port

wolfIP now includes a dedicated FreeRTOS wrapper port at:

  • src/port/freeRTOS/bsd_socket.c
  • src/port/freeRTOS/bsd_socket.h

This port follows the same model as the POSIX wrapper:

  • One background task loops on wolfIP_poll()
  • Socket wrappers serialize stack access with a mutex
  • Blocking operations wait on callback-driven wakeups (instead of busy polling)

Copyright and License

wolfIP is licensed under the GPLv3 license. See the LICENSE file for details. Copyright (c) 2025 wolfSSL Inc.