Skip to content

File syn_wg.c

FileList > net > syn_wg.c

Go to the source code of this file

WireGuard client — Noise_IKpsk2 handshake + transport. More...

  • #include "../crypto/syn_blake2s.h"
  • #include "../crypto/syn_chacha20poly1305.h"
  • #include "../crypto/syn_x25519.h"
  • #include "../port/syn_port_socket.h"
  • #include "../port/syn_port_system.h"
  • #include "../util/syn_assert.h"
  • #include "../util/syn_metrics.h"
  • #include "../util/syn_random.h"
  • #include "syn_wg.h"
  • #include <string.h>

Public Static Attributes

Type Name
const uint8_t WG_LABEL_COOKIE[] SYN_UNUSED = "cookie--"
const uint8_t WG_CONSTRUCTION = /* multi line expression */
const uint8_t WG_IDENTIFIER = /* multi line expression */
const uint8_t WG_LABEL_MAC1 = "mac1----"

Public Functions

Type Name
void syn_wg_disconnect (SYN_WG * wg)
Disconnect the WireGuard tunnel and close socket.
SYN_Status syn_wg_get_stats (const SYN_WG * wg, SYN_WgStats * stats)
Retrieve WireGuard tunnel metrics and statistics.
void syn_wg_init (SYN_WG * wg, const SYN_WgConfig * config, SYN_SNTP * sntp, uint8_t * rx_buf, size_t rx_buf_size, uint8_t * tx_buf, size_t tx_buf_size)
Initialize the WireGuard client.
SYN_Status syn_wg_send (SYN_WG * wg, const uint8_t * ip_packet, size_t len)
Send an IP packet through the WireGuard tunnel.
SYN_PT_Status syn_wg_task (SYN_PT * pt, SYN_Task * task)
Cooperative protothread task — drives the WireGuard client.

Public Static Functions

Type Name
uint32_t load32_le (const uint8_t * p)
Load 32-bit little-endian word.
uint64_t load64_le (const uint8_t * p)
Load 64-bit little-endian word.
void store32_be (uint8_t * p, uint32_t v)
Store 32-bit big-endian word.
void store32_le (uint8_t * p, uint32_t v)
Store 32-bit little-endian word.
void store64_be (uint8_t * p, uint64_t v)
Store 64-bit big-endian word.
void store64_le (uint8_t * p, uint64_t v)
Store 64-bit little-endian word.
bool wg_consume_response (SYN_WG * wg, const uint8_t * msg, size_t len)
Parse and validate a handshake response, deriving session keys.
bool wg_decrypt_and_hash (uint8_t h, const uint8_t k, const uint8_t * ct, size_t ct_len, const uint8_t tag, uint8_t * plain)
Decrypt-and-hash: verify + decrypt, mix ciphertext+tag into hash.
void wg_encrypt_and_hash (uint8_t h, const uint8_t k, const uint8_t * plain, size_t plain_len, uint8_t * ct, uint8_t tag)
Encrypt-and-hash: encrypt plaintext, mix ciphertext+tag into hash.
bool wg_handle_transport (SYN_WG * wg, const uint8_t * msg, size_t len)
Decrypt and deliver an incoming WireGuard transport message.
void wg_hkdf2 (uint8_t out1, uint8_t out2, const uint8_t ck, const uint8_t * input, size_t input_len)
void wg_hkdf3 (uint8_t out1, uint8_t out2, uint8_t out3, const uint8_t ck, const uint8_t * input, size_t input_len)
void wg_mac1 (uint8_t mac, const uint8_t peer_pub, const uint8_t * msg, size_t msg_len)
Compute mac1 = keyed BLAKE2s(HASH("mac1----" || peer_pub), msg).
void wg_mix_hash (uint8_t h, const void * data, size_t len)
Mix hash: H = BLAKE2s(H || data).
void wg_mix_key (uint8_t ck, uint8_t k, const uint8_t * input, size_t len)
Mix key: (CK, k) = HKDF(CK, input).
bool wg_replay_check (SYN_WgSession * s, uint64_t counter)
Anti-replay check using a sliding window bitmap.
bool wg_send_initiation (SYN_WG * wg)
Build and send a Noise_IKpsk2 handshake initiation message.
void wg_send_keepalive (SYN_WG * wg)
Send an empty (keepalive) transport message.
void wg_tai64n (uint8_t out, const SYN_SNTP * sntp)
Write a 12-byte TAI64N timestamp from NTP time.

Detailed Description

Implements the WireGuard protocol per the whitepaper: https://www.wireguard.com/papers/wireguard.pdf

Noise protocol pattern: IKpsk2 Initiator (us) knows responder's static public key. PSK mixed in at handshake step 2.

Public Static Attributes Documentation

variable SYN_UNUSED

const uint8_t WG_LABEL_COOKIE [] SYN_UNUSED;

Cookie label


variable WG_CONSTRUCTION

const uint8_t WG_CONSTRUCTION[];

Noise construction string


variable WG_IDENTIFIER

const uint8_t WG_IDENTIFIER[];

Protocol identifier string


variable WG_LABEL_MAC1

const uint8_t WG_LABEL_MAC1[];

MAC1 label


Public Functions Documentation

function syn_wg_disconnect

Disconnect the WireGuard tunnel and close socket.

void syn_wg_disconnect (
    SYN_WG * wg
) 

Parameters:

  • wg Client context.

function syn_wg_get_stats

Retrieve WireGuard tunnel metrics and statistics.

SYN_Status syn_wg_get_stats (
    const SYN_WG * wg,
    SYN_WgStats * stats
) 

Parameters:

  • wg Client context.
  • stats [out] Output statistics structure.

Returns:

SYN_OK on success.


function syn_wg_init

Initialize the WireGuard client.

void syn_wg_init (
    SYN_WG * wg,
    const SYN_WgConfig * config,
    SYN_SNTP * sntp,
    uint8_t * rx_buf,
    size_t rx_buf_size,
    uint8_t * tx_buf,
    size_t tx_buf_size
) 

Derives the public key from the private key and prepares state. Does NOT open a socket or start a handshake — that happens when the protothread task runs.

Parameters:

  • wg Client context.
  • config Peer configuration (copied).
  • sntp SNTP time source (must be initialized, may not be synced yet).
  • rx_buf Receive buffer (at least SYN_WG_MTU + SYN_WG_TRANSPORT_OVERHEAD).
  • rx_buf_size Receive buffer capacity.
  • tx_buf Transmit buffer (same sizing).
  • tx_buf_size Transmit buffer capacity.

function syn_wg_send

Send an IP packet through the WireGuard tunnel.

SYN_Status syn_wg_send (
    SYN_WG * wg,
    const uint8_t * ip_packet,
    size_t len
) 

Encrypts the packet with the current session key and sends it as a WireGuard transport message.

Parameters:

  • wg Client context.
  • ip_packet Raw IP packet to send.
  • len Packet length.

Returns:

SYN_OK on success, SYN_ERROR if no session or send failed.


function syn_wg_task

Cooperative protothread task — drives the WireGuard client.

SYN_PT_Status syn_wg_task (
    SYN_PT * pt,
    SYN_Task * task
) 

Handles: NTP sync wait, handshake, incoming packet processing, keepalive, and rekeying. Pass the SYN_WG context via task->user_data.

Parameters:

  • pt Protothread.
  • task Task descriptor.

Returns:

PT status.


Public Static Functions Documentation

function load32_le

Load 32-bit little-endian word.

static inline uint32_t load32_le (
    const uint8_t * p
) 

Parameters:

  • p Source bytes.

Returns:

32-bit value.


function load64_le

Load 64-bit little-endian word.

static inline uint64_t load64_le (
    const uint8_t * p
) 

Parameters:

  • p Source bytes.

Returns:

64-bit value.


function store32_be

Store 32-bit big-endian word.

static inline void store32_be (
    uint8_t * p,
    uint32_t v
) 

Parameters:

  • p Destination bytes.
  • v Value to store.

function store32_le

Store 32-bit little-endian word.

static inline void store32_le (
    uint8_t * p,
    uint32_t v
) 

Parameters:

  • p Destination bytes.
  • v Value to store.

function store64_be

Store 64-bit big-endian word.

static inline void store64_be (
    uint8_t * p,
    uint64_t v
) 

Parameters:

  • p Destination bytes.
  • v Value to store.

function store64_le

Store 64-bit little-endian word.

static inline void store64_le (
    uint8_t * p,
    uint64_t v
) 

Parameters:

  • p Destination bytes.
  • v Value to store.

function wg_consume_response

Parse and validate a handshake response, deriving session keys.

static bool wg_consume_response (
    SYN_WG * wg,
    const uint8_t * msg,
    size_t len
) 

Parameters:

  • wg Client context.
  • msg Received message data.
  • len Received message length.

Returns:

true if response was valid and session established.


function wg_decrypt_and_hash

Decrypt-and-hash: verify + decrypt, mix ciphertext+tag into hash.

static bool wg_decrypt_and_hash (
    uint8_t h,
    const uint8_t k,
    const uint8_t * ct,
    size_t ct_len,
    const uint8_t tag,
    uint8_t * plain
) 

Parameters:

  • h Running hash (32 bytes).
  • k Decryption key (32 bytes).
  • ct Ciphertext input.
  • ct_len Ciphertext length.
  • tag MAC tag input (16 bytes).
  • plain Plaintext output.

Returns:

true if decryption and verification succeeded.


function wg_encrypt_and_hash

Encrypt-and-hash: encrypt plaintext, mix ciphertext+tag into hash.

static void wg_encrypt_and_hash (
    uint8_t h,
    const uint8_t k,
    const uint8_t * plain,
    size_t plain_len,
    uint8_t * ct,
    uint8_t tag
) 

Parameters:

  • h Running hash (32 bytes).
  • k Encryption key (32 bytes).
  • plain Plaintext input.
  • plain_len Plaintext length.
  • ct Ciphertext output.
  • tag MAC tag output (16 bytes).

function wg_handle_transport

Decrypt and deliver an incoming WireGuard transport message.

static bool wg_handle_transport (
    SYN_WG * wg,
    const uint8_t * msg,
    size_t len
) 

Parameters:

  • wg Client context.
  • msg Received message data.
  • len Received message length.

Returns:

true if message was valid and delivered.


function wg_hkdf2

static void wg_hkdf2 (
    uint8_t out1,
    uint8_t out2,
    const uint8_t ck,
    const uint8_t * input,
    size_t input_len
) 

HKDF-Extract + Expand producing 2 outputs.

Parameters:

  • out1 Output buffers (32 bytes each).
  • ck Chaining key (32 bytes).
  • input Input data.
  • input_len Length of input data.

function wg_hkdf3

static void wg_hkdf3 (
    uint8_t out1,
    uint8_t out2,
    uint8_t out3,
    const uint8_t ck,
    const uint8_t * input,
    size_t input_len
) 

HKDF-Extract + Expand producing 3 outputs.

Parameters:

  • out1 Output buffers (32 bytes each).
  • ck Chaining key (32 bytes).
  • input Input data.
  • input_len Length of input data.

function wg_mac1

Compute mac1 = keyed BLAKE2s(HASH("mac1----" || peer_pub), msg).

static void wg_mac1 (
    uint8_t mac,
    const uint8_t peer_pub,
    const uint8_t * msg,
    size_t msg_len
) 

Parameters:

  • mac Output MAC (16 bytes).
  • peer_pub Peer's public key.
  • msg Message data.
  • msg_len Length of message data.

function wg_mix_hash

Mix hash: H = BLAKE2s(H || data).

static void wg_mix_hash (
    uint8_t h,
    const void * data,
    size_t len
) 

Parameters:

  • h Running hash (32 bytes).
  • data Input data.
  • len Length of input data.

function wg_mix_key

Mix key: (CK, k) = HKDF(CK, input).

static void wg_mix_key (
    uint8_t ck,
    uint8_t k,
    const uint8_t * input,
    size_t len
) 

Parameters:

  • ck Running chaining key (32 bytes).
  • k Output key (32 bytes).
  • input Input data.
  • len Length of input data.

function wg_replay_check

Anti-replay check using a sliding window bitmap.

static bool wg_replay_check (
    SYN_WgSession * s,
    uint64_t counter
) 

Parameters:

  • s Active session.
  • counter Received counter value.

Returns:

true if counter is new and within window.


function wg_send_initiation

Build and send a Noise_IKpsk2 handshake initiation message.

static bool wg_send_initiation (
    SYN_WG * wg
) 

Parameters:

  • wg Client context.

Returns:

true if message was built and sent.


function wg_send_keepalive

Send an empty (keepalive) transport message.

static void wg_send_keepalive (
    SYN_WG * wg
) 

Parameters:

  • wg Client context.

function wg_tai64n

Write a 12-byte TAI64N timestamp from NTP time.

static void wg_tai64n (
    uint8_t out,
    const SYN_SNTP * sntp
) 

Parameters:

  • out Output buffer (12 bytes).
  • sntp NTP time source.


The documentation for this class was generated from the following file src/syntropic/net/syn_wg.c