WireGuard: how the protocol behind FortiSafe's tunnel works
FortiSafe team ·
WireGuard is the protocol that creates the encrypted tunnel between your device and the VPN server. FortiSafe chose it for verifiable reasons: the code is small enough to audit, the cryptography is current, researchers have formally verified the protocol's security, and it has been part of the Linux kernel since 2020. Below is how it works inside.
Why we chose WireGuard
- Small codebase: according to the technical paper by its author, Jason A. Donenfeld, the Linux implementation is under 4,000 lines, which makes it easier to audit and verify.
- Current cryptography: Curve25519, ChaCha20-Poly1305, BLAKE2s and HKDF, detailed in the table below.
- Formally verified security: the protocol has security proofs built with tools such as Tamarin and CryptoVerif, and the Curve25519 it uses comes from verified implementations.
- Inside the Linux kernel: WireGuard officially shipped in Linux 5.6, released on 29 March 2020.
- Simple to run: each side is identified by a short public key, in the style of OpenSSH, and the protocol creates and renews sessions on its own.
- The author's stated goal is to replace IPsec for most use cases, as well as solutions such as OpenVPN, while being more secure, faster and easier to use.
Cryptokey routing
WireGuard's core principle is to tie each peer's public key to the IP addresses it may use inside the tunnel. The technical paper calls this cryptokey routing.
When sending a packet, the interface looks up which key matches the destination IP and encrypts the packet for that key. When receiving, it decrypts the packet and checks that the source IP inside it is one of those allowed for the key that encrypted it. If not, the packet is dropped.
In practice, knowing where a packet came from inside the tunnel is the same as knowing which key encrypted it.
The handshake: one round trip
- WireGuard uses the Noise_IK pattern from the Noise Protocol Framework, and everything travels over UDP.
- First message, from the initiator: a temporary (ephemeral) public key, the initiator's static public key, encrypted, and an encrypted TAI64N timestamp that prevents a recorded message from being replayed.
- Second message, from the responder: its ephemeral key and an encrypted proof that both sides reached the same state.
- Both sides derive the session keys with HKDF. The responder only starts sending data after it receives the first packet encrypted with the new session, which confirms the keys.
- Adding up the fields described in the protocol, the initiation message is 148 bytes and the response is 92.
- Key exchange properties listed on the official page: perfect forward secrecy, identity hiding, protection against replayed messages and against key-compromise impersonation.
WireGuard's cryptography
| Component | What it does | Specification |
|---|---|---|
| Curve25519 | Diffie-Hellman key exchange (ECDH) between peers | 32-byte keys |
| ChaCha20-Poly1305 | Encrypts and authenticates every packet | AEAD construction from RFC 7539 |
| XChaCha20-Poly1305 | Encrypts the cookie used for load protection | Random 24-byte nonce |
| BLAKE2s | Hashing and keyed hashing (MAC) | RFC 7693 |
| HKDF | Derives the session keys | RFC 5869 |
| SipHash24 | Keys for internal hashtables | — |
| Noise_IKpsk2 | Handshake structure | Noise Protocol Framework |
Keys that keep changing
A new session is created roughly every 2 minutes, driven by timers rather than by the user. Anyone who obtains one session's keys can't decrypt earlier sessions.
If no new session is created within three times the maximum session age, 9 minutes, the ephemeral and session keys are wiped from memory.
The protocol's timers
| Constant | Value | What it does |
|---|---|---|
| Rekey-After-Time | 120 seconds | Session age after which the initiator asks for a new session |
| Reject-After-Time | 180 seconds | A session older than this can't send or receive data |
| Rekey-Attempt-Time | 90 seconds | How long a new handshake is retried before giving up |
| Rekey-Timeout | 5 seconds | Minimum interval between two handshake initiation messages |
| Keepalive-Timeout | 10 seconds | A peer that received data and has nothing to send back sends an empty packet after this time |
| Rekey-After-Messages | 2⁶⁰ messages | Number of packets after which a new session is requested |
| Reject-After-Messages | 2⁶⁴ − 2¹³ − 1 messages | Packet limit for a session |
Silence and protection under load
WireGuard doesn't reply to messages that don't authenticate. Anyone scanning the internet without the server's public key gets no response at all.
Every handshake message carries an authentication code, mac1, computed with the server's public key. Under load, the server can reply with a cookie instead of processing the handshake: the cookie is bound to the requester's IP, comes from a secret that changes every two minutes and travels encrypted with XChaCha20-Poly1305.
The initiator resends its message with a second code, mac2, made with that cookie. This proves it controls that IP before the server spends processing time on the key exchange.
Switching networks without dropping
Each peer remembers the address of the most recent correctly authenticated packet and replies to it. If your phone moves from Wi-Fi to 4G, the server starts replying to the new address as soon as it receives the first valid packet.
Because sessions are created and renewed by timers, there's no connection to open or close: the interface is ready, and the protocol handles the rest.
Formally verified security
- Tamarin, symbolic verification by Jason Donenfeld and Kevin Milner: correctness, strong key agreement and authenticity, key-compromise impersonation resistance, unknown key-share attack resistance, key secrecy, forward secrecy, session uniqueness and identity hiding.
- CryptoVerif, a computational proof by Benjamin Lipp that also covers data packets: message secrecy, forward secrecy, mutual authentication and replay resistance of the first message, among others.
- eCK model, a computational proof by Benjamin Dowling and Kenneth G. Paterson, on an equivalent variant of the protocol.
- ProVerif, through the Noise Explorer project by Nadim Kobeissi and Karthikeyan Bhargavan, on the Noise IK pattern.
- Curve25519 from verified implementations: HACL* for 64-bit and Fiat-Crypto for 32-bit.
From paper to the Linux kernel
WireGuard was presented in a paper at NDSS 2017, the Network and Distributed System Security Symposium. The latest revision of the technical paper is dated 1 June 2020.
Linux 5.6, released on 29 March 2020, brought WireGuard into the kernel. The official site offers apps for Linux, Windows, macOS, iOS and Android.
It's the protocol FortiSafe uses.
Sources
Pages checked on 14 September 2026.
- WireGuard — protocol and cryptography — Cryptographic primitives, handshake, key exchange properties and message fields; the byte sizes were added up by the FortiSafe team.
- WireGuard — technical paper by Jason A. Donenfeld — Cryptokey routing, roaming, cookies, timers and code size; revision of 1 June 2020.
- WireGuard — formal verification — Proofs in Tamarin, CryptoVerif, eCK and ProVerif, and verified Curve25519 implementations.
- Kernel Newbies — Linux 5.6 — Released on 29 March 2020, with WireGuard in the kernel.
- WireGuard — official site — Systems with an official app.