WireGuard Implementation for ESP-IDF

Overview

esp_wireguard, WireGuard Implementation for ESP-IDF

This is an implementation of the WireGuard® for ESP-IDF, based on WireGuard Implementation for lwIP.

Build examples

Status

The code is alpha.

A single tunnel to a WireGuard peer has been working.

Supported ESP-IDF versions and targets

The following ESP-IDF versions are supported:

  • esp-idf master
  • esp-idf v4.2.x
  • esp-idf v4.3.x
  • ESP8266 RTOS SDK v3.4

The following targets are supported:

  • esp32
  • esp32s2
  • esp32c3
  • esp8266

Usage

In menuconfig under WireGuard, choose a TCP/IP adapter. The default is ESP-NETIF. SDKs older than esp-idf v4.1, including ESP8266 RTOS SDK v3.4 requires TCP/IP Adapter.

Both peers must have synced time. The library does not sync time.

A working network interface is required.

Create WireGuard configuration, wireguard_config_t. Use ESP_WIREGUARD_CONFIG_DEFAULT to initialize wireguard_config_t variable. Create wireguard_ctx_t. Pass the variables to esp_wireguard_init(). Then, call esp_wireguard_connect(). Call esp_wireguard_disconnect() to disconnect from the peer (and destroy the WireGuard interface).

#include <esp_wireguard.h>

esp_err_t err = ESP_FAIL;

wireguard_config_t wg_config = ESP_WIREGUARD_CONFIG_DEFAULT();

wg_config.private_key = CONFIG_WG_PRIVATE_KEY;
wg_config.listen_port = CONFIG_WG_LOCAL_PORT;
wg_config.public_key = CONFIG_WG_PEER_PUBLIC_KEY;
wg_config.allowed_ip = CONFIG_WG_LOCAL_IP_ADDRESS;
wg_config.allowed_ip_mask = CONFIG_WG_LOCAL_IP_NETMASK;
wg_config.endpoint = CONFIG_WG_PEER_ADDRESS;
wg_config.port = CONFIG_WG_PEER_PORT;

/* If the device is behind NAT or stateful firewall, set persistent_keepalive.
   persistent_keepalive is disabled by default */
// wg_config.persistent_keepalive = 10;

wireguard_ctx_t ctx = {0};
err = esp_wireguard_init(&wg_config, &ctx);
err = esp_wireguard_connect(ctx);

/* do something */

err = esp_wireguard_disconnect(&ctx);

See examples at examples.

IPv6 support

Enable CONFIG_LWIP_IPV6 under lwip component in menuconfig.

IPv6 support is alpha and probably broken. See also Known issues.

Known issues

The implementation uses LwIP as TCP/IP protocol stack.

IPv6 support is not tested. Dual stack (IPv4 and IPv6) is not supported (see Issue #5). The first address of endpoint is used to choose IPv4 or IPv6 as a transport. The chosen transport must be available and usable.

The library assumes the interface is WiFi interface. Ethernet is not supported.

Older esp-idf versions with TCP/IP Adapter, such as v4.1.x, should work, but there are others issues, not directly related to the library.

License

BSD 3-Clause "New" or "Revised" License (SPDX ID: BSD-3-Clause). See LICENSE for details.

Authors

Comments
  • Invalid handshake initiation after connectivity issue

    Invalid handshake initiation after connectivity issue

    Hello trombik, I'm facing this odd behavior: if the esp device looses its main network for whatever reason (reboot, link error, wifi change, etc), it cannot reconnect to the wireguard server. In the dmesg I see "Invalid handshake initiation from ww.ww.ww.ww:kkkkk" (either if the source IP is the same or not).

    In order to have the device connected again I need to remove the peer from server with wg set wg0 peer AAAABBBB....FFFF= remove and re-add it.

    It looks like a server-side bug but I don't have such behavior with other peers (all Linux peers).

    When the esp device looses the main connection I see the following in dmesg of the server:

    wireguard: wg0: Retrying handshake with peer 97 (xx.xx.xx.xx:yyyyy) because we stopped hearing back after 15 seconds
    wireguard: wg0: Sending handshake initiation to peer 97 (xx.xx.xx.xx:yyyyy)
    wireguard: wg0: Handshake for peer 97 (xx.xx.xx.xx:yyyyy) did not complete after 5 seconds, retrying (try 2)
    wireguard: wg0: Sending handshake initiation to peer 97 (xx.xx.xx.xx:yyyyy)
    wireguard: wg0: Handshake for peer 97 (xx.xx.xx.xx:yyyyy) did not complete after 5 seconds, retrying (try 3)
    wireguard: wg0: Sending handshake initiation to peer 97 (xx.xx.xx.xx:yyyyy)
    wireguard: wg0: Handshake for peer 97 (xx.xx.xx.xx:yyyyy) did not complete after 5 seconds, retrying (try 4)
    [...]
    

    When the esp device is online again and starts the handshake I see:

    wireguard: wg0: Retrying handshake with peer 97 (xx.xx.xx.xx:yyyyy) because we stopped hearing back after 15 seconds
    wireguard: wg0: Handshake for peer 97 (xx.xx.xx.xx:yyyyy) did not complete after 5 seconds, retrying (try 2)
    wireguard: wg0: Sending handshake initiation to peer 97 (xx.xx.xx.xx:yyyyy)
    wireguard: wg0: Handshake for peer 97 (xx.xx.xx.xx:yyyyy) did not complete after 5 seconds, retrying (try 4)
    wireguard: wg0: Invalid handshake initiation from ww.ww.ww.ww:kkkkk
    wireguard: wg0: Handshake for peer 97 (xx.xx.xx.xx:yyyyy) did not complete after 5 seconds, retrying (try 5)
    wireguard: wg0: Sending handshake initiation to peer 97 (xx.xx.xx.xx:yyyyy)
    wireguard: wg0: Retrying handshake with peer 97 (xx.xx.xx.xx:yyyyy) because we stopped hearing back after 15 seconds
    wireguard: wg0: Invalid handshake initiation from ww.ww.ww.ww:kkkkk
    wireguard: wg0: Handshake for peer 97 (xx.xx.xx.xx:yyyyy) did not complete after 5 seconds, retrying (try 2)
    wireguard: wg0: Sending handshake initiation to peer 97 (xx.xx.xx.xx:yyyyy)
    wireguard: wg0: Invalid handshake initiation from ww.ww.ww.ww:kkkkk
    [...]
    

    ad so on, being xx.xx.xx.xx and ww.ww.ww.ww the same IP or not.

    If you need more information or tests feel free to ask, I'll do my best to support you.

    opened by droscy 20
  • Cannot complete handshake if pre-shared key is in use

    Cannot complete handshake if pre-shared key is in use

    Hi trombik, maybe this is a known limitation, but I report it.

    If a pre-shared key is set (both in wireguard_config_t and in server conf file), the device can't complete the handshake.

    This is what I observe in server's dmesg

    wireguard: wg0: Receiving handshake initiation from peer 96 (xx.xx.xx.xx:yyyyy)
    wireguard: wg0: Sending handshake response to peer 96 (xx.xx.xx.xx:yyyyy)
    wireguard: wg0: Keypair 73332 created for peer 96
    [...]
    wireguard: wg0: Receiving handshake initiation from peer 96 (xx.xx.xx.xx:yyyyy)
    wireguard: wg0: Sending handshake response to peer 96 (xx.xx.xx.xx:yyyyy)
    wireguard: wg0: Keypair 73332 destroyed for peer 96
    wireguard: wg0: Keypair 73333 created for peer 96
    [...]
    wireguard: wg0: Receiving handshake initiation from peer 96 (xx.xx.xx.xx:yyyyy)
    wireguard: wg0: Sending handshake response to peer 96 (xx.xx.xx.xx:yyyyy)
    wireguard: wg0: Keypair 73333 destroyed for peer 96
    wireguard: wg0: Keypair 73334 created for peer 96
    [...]
    

    The same again ad again. It is repeated approximately every 3 seconds.

    If you need more (or different) information feel free to ask, I'll try to do whatever tests you will need.

    bug 
    opened by droscy 4
  • Change TAI64N timestamp source to gettimeofday

    Change TAI64N timestamp source to gettimeofday

    This pull request fixes the behaviour which prevents the ESP32 device from reconnecting after reset (as reported in #29) by supplying time from source which can be synchronized with a SNTP service or an external RTC device. As mentioned here, WireGuard implements timestamps as a countermeasure for replay attacks. Which means handshakes with timestamps lower than previously encountered will be discarded. And since the current implementation uses sys_now, the supplied time is being reset along with the device.

    opened by Pecius 2
  • Not able to install lib.

    Not able to install lib.

    Hi

    I cannot install the package in the latest Arduino IDE 2.X… Even when i try i an older version.

    Could it be that there is something wrong with the new package?

    Error: Request installZip failed with message: 13
    INTERNAL: Library install failed: library not valid
    
    opened by KoenHaemels 1
  • persistent keepalives should be off by default

    persistent keepalives should be off by default

    https://www.wireguard.com/quickstart/#nat-and-firewall-traversal-persistence

    This is called persistent keepalives. When this option is enabled, a keepalive packet is sent to the server endpoint once every interval seconds. A sensible interval that works with a wide variety of firewalls is 25 seconds. Setting it to 0 turns the feature off, which is the default, since most users will not need this, and it makes WireGuard slightly more chatty.

    opened by trombik 0
  • Crash on ESP8266-RTOS-SDK

    Crash on ESP8266-RTOS-SDK

    Steps to reproduce:

    1. Use this docker image. The command is similar to sudo docker run -it --rm -v (pwd):/project -w /project --device /dev/ttyUSB0 mbenabda/esp8266-rtos-sdk bash.
    2. Modify the example/demos to host an HTTP server (using the built-in httpd library)
    3. Wait for a client to load a page
    4. Close the HTTPD handle
    5. Try to close the wireguard context (crashes)

    Log:

    Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.
    Core 0 register dump:
    PC      : 0x40263503  PS      : 0x00000030  A0      : 0x4023621b  A1      : 0x3ffeb9d0  
    0x40263503: peer_lookup_by_allowed_ip at /project/examples/wol/components/esp_wireguard/src/wireguardif.c:74
    
    0x4023621b: wireguardif_output at /project/examples/wol/components/esp_wireguard/src/wireguardif.c:205
    
    A2      : 0x00000000  A3      : 0x3ffeb9d0  A4      : 0x00000000  A5      : 0x00000000  
    A6      : 0x00000000  A7      : 0x00000000  A8      : 0x000000b0  A9      : 0x000000b0  
    A10     : 0x0a00080a  A11     : 0x0000002f  A12     : 0x3ffea660  A13     : 0x3fff33ec  
    A14     : 0x00009058  A15     : 0x3fff4e6c  SAR     : 0x0000001d  EXCCAUSE: 0x0000001c  
    
    Backtrace: 0x40263503:0x3ffeb9d0 0x4023621b:0x3ffeb9d0 0x4024f120:0x3ffeb9f0 0x4024f180:0x3ffeba40 0x4024f1a8:0x3ffeba60 0x4024a61c:0x3ffeba80 0x4024b039:0x3ffebac0 0x40244809:0x3ffebb00 0x40244838:0x3ffebb40 0x40244928:0x3ffebb50 0x4024495f:0x3ffebb60 0x4024920e:0x3ffebb70 0x402495c4:0x3ffebb80 0x40235aa0:0x3ffebb90 0x4022231a:0x3ffebba0 0x40222368:0x3ffebbb0 0x402121eb:0x3ffebc00 
    0x40263503: peer_lookup_by_allowed_ip at /project/examples/wol/components/esp_wireguard/src/wireguardif.c:74
    
    0x4023621b: wireguardif_output at /project/examples/wol/components/esp_wireguard/src/wireguardif.c:205
    
    0x4024f120: ip4_output_if_opt_src at /opt/sdk/components/lwip/lwip/src/core/ipv4/ip4.c:1089
    
    0x4024f180: ip4_output_if_opt at /opt/sdk/components/lwip/lwip/src/core/ipv4/ip4.c:895
    
    0x4024f1a8: ip4_output_if at /opt/sdk/components/lwip/lwip/src/core/ipv4/ip4.c:868
    
    0x4024a61c: tcp_output_control_segment at /opt/sdk/components/lwip/lwip/src/core/tcp_out.c:1951
    
    0x4024b039: tcp_rst at /opt/sdk/components/lwip/lwip/src/core/tcp_out.c:2011
    
    0x40244809: tcp_abandon at /opt/sdk/components/lwip/lwip/src/core/tcp.c:621
    
    0x40244838: tcp_abort at /opt/sdk/components/lwip/lwip/src/core/tcp.c:641
    
    0x40244928: tcp_netif_ip_addr_changed_pcblist at /opt/sdk/components/lwip/lwip/src/core/tcp.c:2411
    
    0x4024495f: tcp_netif_ip_addr_changed at /opt/sdk/components/lwip/lwip/src/core/tcp.c:2430
    
    0x4024920e: netif_do_ip_addr_changed at /opt/sdk/components/lwip/lwip/src/core/netif.c:458
    
    0x402495c4: netif_remove at /opt/sdk/components/lwip/lwip/src/core/netif.c:779
    
    0x40235aa0: esp_wireguard_disconnect at /project/examples/wol/components/esp_wireguard/src/esp_wireguard.c:315 (discriminator 15)
    

    (Issue made per project authors suggestion https://github.com/trombik/esp_wireguard/issues/33#issuecomment-1367987977)

    opened by nikp123 0
  • crash wtih esp-idf 5.x, or master

    crash wtih esp-idf 5.x, or master

    I (5659) demo: Initializing WireGuard.
    I (5659) demo: Connecting to the peer.
    I (5659) esp_wireguard: allowed_ip: 192.168.4.58
    Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.
    
    Core  0 register dump:
    PC      : 0x400f8bd5  PS      : 0x00060630  A0      : 0x800f8ced  A1      : 0x3ffbaaf0  
    0x400f8bd5: esp_netif_internal_dhcpc_cb at /usr/home/trombik/github/trombik/esp-idf/components/esp_netif/lwip/esp_netif_lwip.c:1111
    
    A2      : 0x3ffb467c  A3      : 0x3ffbac88  A4      : 0x00000000  A5      : 0x3ffbacf0  
    A6      : 0x0000000c  A7      : 0xff000000  A8      : 0x3a04a8c0  A9      : 0x00000000  
    A10     : 0x00000004  A11     : 0x3f40d29c  A12     : 0x3f40d4a0  A13     : 0x00001625  
    A14     : 0x3f40d29c  A15     : 0x3f40ded8  SAR     : 0x00000004  EXCCAUSE: 0x0000001c  
    EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffffc  
    
    
    Backtrace: 0x400f8bd2:0x3ffbaaf0 0x400f8cea:0x3ffbab40 0x400e5ca3:0x3ffbab60 0x400e5d4e:0x3ffbab80 0x400e5e92:0x3ffbac00 0x400d7b34:0x3ffbac30 0x400d7dd4:0x3ffbacc0 0x400d76c6:0x3ffbacf0 0x400d78d8:0x3ffbad10 0x40154b3b:0x3ffbadb0 0x4008bca5:0x3ffbade0
    0x400f8bd2: esp_netif_internal_dhcpc_cb at /usr/home/trombik/github/trombik/esp-idf/components/esp_netif/lwip/esp_netif_lwip.c:1108
    
    0x400f8cea: netif_callback_fn at /usr/home/trombik/github/trombik/esp-idf/components/esp_netif/lwip/esp_netif_lwip.c:123
    
    0x400e5ca3: netif_invoke_ext_callback at /usr/home/trombik/github/trombik/esp-idf/components/lwip/lwip/src/core/netif.c:1819
    
    0x400e5d4e: netif_set_addr at /usr/home/trombik/github/trombik/esp-idf/components/lwip/lwip/src/core/netif.c:733
    
    0x400e5e92: netif_add at /usr/home/trombik/github/trombik/esp-idf/components/lwip/lwip/src/core/netif.c:376
    
    0x400d7b34: esp_wireguard_netif_create at /usr/home/trombik/github/trombik/esp_wireguard/examples/demo/components/esp_wireguard/src/esp_wireguard.c:180
    
    0x400d7dd4: esp_wireguard_connect at /usr/home/trombik/github/trombik/esp_wireguard/examples/demo/components/esp_wireguard/src/esp_wireguard.c:235
    
    0x400d76c6: wireguard_setup at /usr/home/trombik/github/trombik/esp_wireguard/examples/demo/main/main.c:79 (discriminator 13)
    
    0x400d78d8: app_main at /usr/home/trombik/github/trombik/esp_wireguard/examples/demo/main/main.c:381
    
    0x40154b3b: main_task at /usr/home/trombik/github/trombik/esp-idf/components/freertos/FreeRTOS-Kernel/portable/port_common.c:131 (discriminator 2)
    
    0x4008bca5: vPortTaskWrapper at /usr/home/trombik/github/trombik/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:151
    
    
    
    
    
    ELF file SHA256: f2a1169a2b5c9528
    
    Rebooting...
    
    opened by trombik 8
  • the driver does not support changes in DNS records

    the driver does not support changes in DNS records

    the original WireGuard implementation resolves DNS name of peer endpoint once at startup. it does not re-resolve the DNS name. the developer said "it's not a bug". a script, reresolve-dns, to "refresh" addresses is provided for Un*x machines. i believe this behavior is not part of the spec, but other implementations, including the upstream and OpenBSD's wg(4) for example, do the same. One implementation supports DNS resolution in its driver (DNS Updates to WireGuard Endpoints | Pro Custodibus).

    opened by trombik 0
Owner
Tomoyuki Sakurai
Founder of Makers Siem Reap. PGP finger print: 03EB 3D97 5E04 9B0C AB21 93A2 D693 42A9 EFBC 3577 https://github.com/trombik.gpg
Tomoyuki Sakurai
idf.py.exe, wrapper tool to invoke idf.py on Windows

IDF wrapper tool (idf.py.exe) This tools helps invoke idf.py in Windows CMD shell. In Windows CMD shell, python scripts can be executed directly (by t

Espressif Systems 3 Dec 13, 2021
An Arduino wrapper to @sdima1357's usb_soft_host esp-idf example

ESP32 USB Soft Host library for Arduino IDE This is mainly a wrapper around the excellent work of Dmitry Samsonov (@sdima1357) with esp32_usb_soft_hos

tobozo 151 Jan 3, 2023
GFX Demo for the ESP-IDF

Display Drivers and Demo for GFX This is a Demo of GFX With Several Display Drivers This is not GFX itself, but it includes it. GFX Documentation is b

honey the codewitch 67 Dec 4, 2022
ESP32 S2 C++ host library compatible with arduino, esp-idf.

Info I would like to announce USB host library for esp32 S2 compatible with arduino, esp-idf and PIO (when pio will be updated to most recent esp-idf)

null 17 Nov 15, 2022
To simplify the development of ESP32 in ESP-IDF, Easyio provides a complete driver library

Easyio 开源驱动库 Easyio 是一款适配于ESP-IDF框架的开源驱动库,以支持ESP32的简便开发。目的是简化乐鑫ESP-IDF开发框架的使用难度。(真要方便的话,有现成的Arduino和Platform可以用,不过实在迫于工作要求,有的开源东西不让用,同时便于对接FAE,于是就有了 E

null 212 Dec 30, 2022
使用ESP-IDF、ESP-ADF、LVGL等库,基于ESP32S2实现简单的网络收音机和FM收音机功能。

【电子森林项目】网络收音机/FM收音机 这个项目是报名《硬禾“暑期一起练”第3个平台 - 基于ESP32-S2模块的网络收音机和音频信号处理》所做的。 基本功能: 可以连接WiFi收听HLS协议的网络电台节目 收听空中的FM电台88MHz~108MHz OLED0.96寸显示 四个独立按键控制两种模

DaMi 17 Nov 2, 2022
LVGL8 for ESP-IDF

X-UI LVGL8 for ESP-IDF 移植自X-TRACK项目的页面栈框架,新增支持异步通信的订阅发布数据中心 特点 使用C语言重构,方便继承复用 核心文件 ui_page_manager.h、ui_page_manager.c 实现页面栈、订阅发布数据中心 完整页面生命周期 MVC架构 数

Zing 13 Aug 5, 2022
Additional components for ESP-IDF, maintained by Espressif

Espressif IDF Extra Components This repository aims to store ESP-IDF extra components which have been seperated and uploaded into IDF Component Manage

Espressif Systems 37 Jan 4, 2023
Add tensilica esp32 cpu and a board to qemu and dump the rom to learn more about esp-idf

qemu_esp32 Add tensilica esp32 cpu and a board to qemu and dump the rom to learn more about esp-idf ESP32 in QEMU. This documents how to add an esp32

null 358 Jan 8, 2023
This FreeRTOS example builds a simple Timer application for Linux using the ESP-IDF

Supported Targets Linux This FreeRTOS example builds a simple Timer application for Linux using the ESP-IDF. Build Source the IDF environment as usual

null 13 Apr 4, 2022
SX1276/77/78/79 Low Power Long Range Transceiver driver for esp-idf

esp-idf-sx127x SX1276/77/78/79 Low Power Long Range Transceiver driver for esp-idf. I based on this. Changes from the original Added support for ESP32

null 20 Jan 4, 2023
SX1262//68 Low Power Long Range Transceiver driver for esp-idf

esp-idf-sx126x SX1262//68 Low Power Long Range Transceiver driver for esp-idf. I ported from here. Ai-Thinker offers several LoRa modules. You can get

null 3 May 9, 2022
SI4432 ISM Transceiver driver for esp-idf

esp-idf-si4432 SI4432 ISM Transceiver driver for esp-idf. I refered this. Software requirements esp-idf v4.4 or later. This is because this version su

null 4 Dec 29, 2022
CC2500 Low-Cost Low-Power 2.4 GHz RF Transceiver driver for esp-idf

esp-idf-cc2500 CC2500 Low-Cost Low-Power 2.4 GHz RF Transceiver driver for esp-idf. I ported from this. 2.00mm pitch External Antena 1.27mm pitch PCB

null 3 May 29, 2022
Collection of additional Ethernet drivers for ESP-IDF

Collection of additional Ethernet drivers for ESP-IDF This repository aims to store additional Ethernet drivers which are not available directly in ES

Espressif Systems 6 Dec 21, 2022
ESP Insights is a remote diagnostics solution that allows users to remotely monitor the health of ESP devices in the field.

ESP Insights is a remote diagnostics solution that allows users to remotely monitor the health of ESP devices in the field.

Espressif Systems 46 Dec 26, 2022
ESP-32 CAM implementation of a Bird classifier using Arduino IDE

Bird-Classifier ESP-32 CAM implementation of a Bird classifier using Arduino IDE For the file server to run, you also need to have the ESP32 SD File M

null 3 Mar 28, 2022
bsdiff changed to remove bz2, the header and to allow streaming interfaces, to be used on the esp32 with idf as a component

bspatch for esp32 This project adds support for bspatch to the esp32 with some changes: no compression (bz2), no header and changed the interfaces to

Blockstream 11 Oct 24, 2022
A customized LGL Android mod menu, containing ESP only for PUBG Mobile 1.3.0 for Android

PUBG Mobile ESP Mod Menu A customized LGL mod menu, containing ESP only for PUBG Mobile 1.3.0 for Android. Everything are fixed so it works with both

null 42 Mar 19, 2022