Skip to content

Commit

Permalink
[WIP] 20% wireguard
Browse files Browse the repository at this point in the history
  • Loading branch information
radkesvat committed Jul 1, 2024
1 parent 6a4e55f commit e7107c5
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 10 deletions.
184 changes: 174 additions & 10 deletions tunnels/shared/wireguard/defs.h
Original file line number Diff line number Diff line change
@@ -1,22 +1,47 @@
#pragma once

/*
Most of the code is taken and renamed, from the awesome projects wireguard-lwip and lwip
Author of lwip: Adam Dunkels https://github.com/smartalock/wireguard-lwip
Author of wireguard-lwip: Daniel Hope https://github.com/lwip-tcpip/lwip
their license files are placed next to this file
*/

#include <stdbool.h>
#include <stdint.h>

struct ip4_addr {
uint32_t addr;
};
typedef struct ip4_addr ip4_addr_t;

enum wg_general_limits
{
// Peers are allocated statically inside the device structure to avoid malloc
kWgMaxPeers = 1,
kWgMaxSrcIPs = 2,
// Per device limit on accepting (valid) initiation requests - per peer
kMaxInitiationPerSecond = 2
};

enum wg_general_consts
{
kWgAuthLen = 16,
kWgHashLen = 32,
kWgPublicKeyLen = 32,
kWgSessionKeyLen = 32,
kWgPrivateKeyLen = 32,
kWgTai64Len = 12,
kWgCookieLen = 16,
kWgCookieNonceLen = 24,
kWgReKeyAfterMessages = (1ULL << 60),
kWgRejectAfterMessage = (0XFFFFFFFFFFFFFFFFULL - (1ULL << 13))
kWgAuthTagLen = 16,
kWgHashLen = 32,
kWgPublicKeyLen = 32,
kWgSessionKeyLen = 32,
kWgPrivateKeyLen = 32,
kWgTai64Len = 12,
kWgCookieLen = 16,
kWgCookieNonceLen = 24
};

// ISO C restricts enumerator values to range of 'int' (1152921504606846976) is too large
#define kWgReKeyAfterMessages (1ULL << 60) // NOLINT
#define kWgRejectAfterMessage (0XFFFFFFFFFFFFFFFFULL - (1ULL << 13)) // NOLINT

enum wg_timing_consts
{
kWgCookieSecretMaxDuration = 120,
Expand Down Expand Up @@ -66,3 +91,142 @@ typedef struct wireguard_handshake_s
uint8_t chaining_key[kWgHashLen];

} wireguard_handshake_t;

typedef struct wireguard_allowed_ip_s {
bool valid;
ip_addr_t ip;
ip_addr_t mask;
} wireguard_allowed_ip_t;

struct wireguard_peer
{
bool valid; // Is this peer initialised?
bool active; // Should we be actively trying to connect?

// This is the configured IP of the peer (endpoint)
ip_addr_t connect_ip;
uint16_t connect_port;
// This is the latest received IP/port
ip_addr_t ip;
uint16_t port;
// keep-alive interval in seconds, 0 is disable
uint16_t keepalive_interval;

struct wireguard_allowed_ip allowed_source_ips[kWgMaxSrcIPs];

uint8_t public_key[kWgPublicKeyLen];
uint8_t preshared_key[kWgSessionKeyLen];

// Precomputed DH(Sprivi,Spubr) with device private key, and peer public key
uint8_t public_key_dh[kWgPublicKeyLen];

// Session keypairs
struct wireguard_keypair curr_keypair;
struct wireguard_keypair prev_keypair;
struct wireguard_keypair next_keypair;

// 5.1 Silence is a Virtue: The responder keeps track of the greatest timestamp received per peer
uint8_t greatest_timestamp[kWgTai64Len];

// The active handshake that is happening
struct wireguard_handshake handshake;

// Decrypted cookie from the responder
uint32_t cookie_millis;
uint8_t cookie[kWgCookieLen];

// The latest mac1 we sent with initiation
bool handshake_mac1_valid;
uint8_t handshake_mac1[kWgCookieLen];

// Precomputed keys for use in mac validation
uint8_t label_cookie_key[kWgSessionKeyLen];
uint8_t label_mac1_key[kWgSessionKeyLen];

// The last time we received a valid initiation message
uint32_t last_initiation_rx;
// The last time we sent an initiation message to this peer
uint32_t last_initiation_tx;

// last_tx and last_rx of data packets
uint32_t last_tx;
uint32_t last_rx;

// We set this flag on RX/TX of packets if we think that we should initiate a new handshake
bool send_handshake;
};

struct wireguard_device
{
// Maybe have a "Device private" member to abstract these?
struct netif *netif;
struct udp_pcb *udp_pcb;

uint8_t public_key[kWgPublicKeyLen];
uint8_t private_key[kWgPrivateKeyLen];

uint8_t cookie_secret[kWgHashLen];
uint32_t cookie_secret_millis;

// Precalculated
uint8_t label_cookie_key[kWgSessionKeyLen];
uint8_t label_mac1_key[kWgSessionKeyLen];

// List of peers associated with this device
struct wireguard_peer peers[kWgMaxPeers];

bool valid;
};

#define MESSAGE_INVALID 0
#define MESSAGE_HANDSHAKE_INITIATION 1
#define MESSAGE_HANDSHAKE_RESPONSE 2
#define MESSAGE_COOKIE_REPLY 3
#define MESSAGE_TRANSPORT_DATA 4

// 5.4.2 First Message: Initiator to Responder
struct message_handshake_initiation
{
uint8_t type;
uint8_t reserved[3];
uint32_t sender;
uint8_t ephemeral[32];
uint8_t enc_static[32 + kWgAuthTagLen];
uint8_t enc_timestamp[kWgTai64Len + kWgAuthTagLen];
uint8_t mac1[kWgCookieLen];
uint8_t mac2[kWgCookieLen];
} __attribute__((__packed__));

// 5.4.3 Second Message: Responder to Initiator
struct message_handshake_response
{
uint8_t type;
uint8_t reserved[3];
uint32_t sender;
uint32_t receiver;
uint8_t ephemeral[32];
uint8_t enc_empty[0 + kWgAuthTagLen];
uint8_t mac1[kWgCookieLen];
uint8_t mac2[kWgCookieLen];
} __attribute__((__packed__));

// 5.4.7 Under Load: Cookie Reply Message
struct message_cookie_reply
{
uint8_t type;
uint8_t reserved[3];
uint32_t receiver;
uint8_t nonce[kWgCookieNonceLen];
uint8_t enc_cookie[kWgCookieLen + kWgAuthTagLen];
} __attribute__((__packed__));

// 5.4.6 Subsequent Messages: Transport Data Messages
struct message_transport_data
{
uint8_t type;
uint8_t reserved[3];
uint32_t receiver;
uint8_t counter[8];
// Followed by encrypted data
uint8_t enc_packet[];
} __attribute__((__packed__));
24 changes: 24 additions & 0 deletions tunnels/shared/wireguard/lwip-LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
26 changes: 26 additions & 0 deletions tunnels/shared/wireguard/wireguard-lwip-LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Copyright (c) 2021 Daniel Hope (www.floorsense.nz)
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
* Neither the name of "Floorsense Ltd", "Agile Workspace Ltd" nor the names of
its contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Author: Daniel Hope <[email protected]>

0 comments on commit e7107c5

Please sign in to comment.