summaryrefslogtreecommitdiffstats
path: root/src/wireguard.h
diff options
context:
space:
mode:
authorMatt Dunwoodie <ncon@mail.noconroy.net>2019-06-11 20:41:59 +1000
committerMatt Dunwoodie <ncon@mail.noconroy.net>2019-06-11 20:41:59 +1000
commit5445b875ea54aca46d45547f06c2910a60edf8bb (patch)
tree90943552a2bdc48e9c81db5d015fbd5f50efc588 /src/wireguard.h
parentRemove state from ifconfig interface (diff)
downloadwireguard-openbsd-5445b875ea54aca46d45547f06c2910a60edf8bb.tar.xz
wireguard-openbsd-5445b875ea54aca46d45547f06c2910a60edf8bb.zip
staging
Diffstat (limited to 'src/wireguard.h')
-rw-r--r--src/wireguard.h235
1 files changed, 113 insertions, 122 deletions
diff --git a/src/wireguard.h b/src/wireguard.h
index 700e836975e..d2af218b8ad 100644
--- a/src/wireguard.h
+++ b/src/wireguard.h
@@ -1,148 +1,139 @@
-#ifndef _WIREGUARD_H_
-#define _WIREGUARD_H_
+#ifndef _LIBWG_H_
+#define _LIBWG_H_
-#if _KERNEL
#include <sys/types.h>
-#include <sys/mbuf.h>
#include <sys/time.h>
-#else
-#include "compat.h"
-#endif
+#include <sys/rwlock.h>
#define WG_KEY_SIZE 32
#define WG_MAC_SIZE 16
#define WG_HASH_SIZE 32
#define WG_COOKIE_SIZE 16
-#define WG_COOKIE_RVAL_SIZE 16
-#define WG_COOKIE_IVAL_MAXSIZE 32
+#define WG_XNONCE_SIZE 24
+#define WG_MSG_PADDING_SIZE 16
+#define WG_COOKIE_RAND_VAL_SIZE 16
+#define WG_COOKIE_ID_VAL_MAXSIZE 32
#define WG_TIMESTAMP_SIZE 12
-/*
- * WG_ANTIREPLAY_INTEGER_BITS is the size of an element in the bitmap (in bits)
- * WG_ANTIREPLAY_BITMAP_BITS must be twice the size of WG_ANTIREPLAY_INTEGER_BITS. It
- * must also be a power of 2 (256, 1024, etc...)
- */
-#define WG_ANTIREPLAY_INTEGER_BITS (sizeof(u_int64_t) * 8)
-#define WG_ANTIREPLAY_BITMAP_BITS (1<<10) /* 1024 bitmap (960 usable) */
+#define WG_ARI_BITS (sizeof(uint64_t) * 8)
+#define WG_ARB_BITS (1<<10) /* 1024 bitmap (960 usable) */
+
+#define WG_ENCRYPTED_SIZE(n) ((n) + WG_MAC_SIZE)
+#define WG_PADDED_SIZE(n) ((WG_MSG_PADDING_SIZE - (n)) % WG_MSG_PADDING_SIZE)
+#define WG_ENCRYPTED_PADDED_SIZE(n) WG_ENCRYPTED_SIZE(WG_PADDED_SIZE(n))
+
+/* Constant for session */
+#define WG_REKEY_AFTER_MESSAGES (((uint64_t) 2<<48) - 1)
+#define WG_REJECT_AFTER_MESSAGES (((uint64_t) 2<<60) - 1)
+#define WG_REKEY_AFTER_TIME 120
+#define WG_REJECT_AFTER_TIME 180
+#define WG_REKEY_ATTEMPT_COUNT 20
+#define WG_REKEY_TIMEOUT 5
+#define WG_KEEPALIVE_TIMEOUT 10
+#define WG_BROKEN_TIMEOUT (WG_REKEY_TIMEOUT + WG_KEEPALIVE_TIMEOUT)
+#define WG_REKEY_AFTER_TIME_RECV (WG_REJECT_AFTER_TIME - WG_KEEPALIVE_TIMEOUT - WG_REKEY_TIMEOUT)
enum wg_role {
- WG_ROLE_UNKNOWN,
+ WG_ROLE_UNKNOWN = 0,
WG_ROLE_INITIATOR,
WG_ROLE_RESPONDER,
};
-enum wg_key_type {
- WG_KEY_LOCAL,
- WG_KEY_REMOTE,
- WG_KEY_SHARED,
+enum wg_pkt_type {
+ WG_PKT_UNKNOWN = 0,
+ WG_PKT_INITIATION,
+ WG_PKT_RESPONSE,
+ WG_PKT_COOKIE,
+ WG_PKT_TRANSPORT,
};
-enum wg_task {
- WG_TASK_REKEY,
- WG_TASK_KEEPALIVE,
- WG_TASK_BROKEN,
- WG_TASK_CLEANUP,
- WG_TASK_PKA,
- WG_TASK_NUM,
-};
-
-struct wg_peer {
- /* p_arg can be used as an arbitrary pointer */
- void *p_arg;
-
- /* the rest should not be touched, instead should be manipulated by
- * the functions provided below */
- struct wg_upcall *p_upcall;
-
- u_int8_t p_local_pubkey[WG_KEY_SIZE];
- u_int8_t p_local_privkey[WG_KEY_SIZE];
- u_int8_t p_remote_pubkey[WG_KEY_SIZE];
- u_int8_t p_psk [WG_KEY_SIZE];
-
+struct wg_state {
struct wg_handshake {
- enum wg_role role;
- u_int32_t local_id;
- u_int32_t remote_id;
- u_int8_t mac[WG_MAC_SIZE];
- u_int8_t hash [WG_HASH_SIZE];
- u_int8_t ck [WG_HASH_SIZE];
- u_int8_t k [WG_HASH_SIZE];
- u_int8_t local_epub[WG_KEY_SIZE];
- u_int8_t local_epriv[WG_KEY_SIZE];
- u_int8_t remote_epub[WG_KEY_SIZE];
- } p_hs;
+ enum wg_role hs_role;
+ uint32_t hs_local_id;
+ uint32_t hs_remote_id;
+ uint8_t hs_mac[WG_MAC_SIZE];
+ uint8_t hs_hash [WG_HASH_SIZE];
+ uint8_t hs_ck [WG_HASH_SIZE];
+ uint8_t hs_k [WG_HASH_SIZE];
+ uint8_t hs_local_epub[WG_KEY_SIZE];
+ uint8_t hs_local_epriv[WG_KEY_SIZE];
+ uint8_t hs_remote_epub[WG_KEY_SIZE];
+ } c_hs;
struct wg_session {
- struct timespec created;
+ enum wg_role s_role;
+ struct timespec s_created;
struct wg_antireplay {
- u_int64_t head;
- u_int64_t bitmap[WG_ANTIREPLAY_BITMAP_BITS / WG_ANTIREPLAY_INTEGER_BITS];
- } antireplay;
- u_int64_t sendcounter;
- u_int64_t recvcounter;
- u_int8_t sendkey[WG_KEY_SIZE];
- u_int8_t recvkey[WG_KEY_SIZE];
- u_int32_t local_id;
- u_int32_t remote_id;
- enum wg_role role;
- } p_curr_sess, p_prev_sess;
-
- bool p_wait_ack;
- u_int8_t p_init_retry_count;
- u_int16_t p_persistent_keepalive;
- struct timespec p_lastinit;
-
- struct wg_cookie_value {
- u_int8_t value [WG_COOKIE_SIZE];
- struct timespec time;
- } p_cookie;
+ uint64_t ar_head;
+ uint64_t ar_bitmap[WG_ARB_BITS / WG_ARI_BITS];
+ } s_ar;
+ uint64_t s_txcounter;
+ uint64_t s_rxcounter;
+ uint8_t s_txkey[WG_KEY_SIZE];
+ uint8_t s_rxkey[WG_KEY_SIZE];
+ uint32_t s_local_id;
+ uint32_t s_remote_id;
+ } c_sess, c_sess_old;
+
+ struct wg_cookie {
+ uint8_t c_value[WG_COOKIE_SIZE];
+ struct timespec c_time;
+ } c_cookie;
struct wg_timestamp {
- u_int8_t bytes[WG_TIMESTAMP_SIZE];
- } p_ts;
-
-
- struct mbuf_list p_tempq;
+ uint8_t ts_bytes[WG_TIMESTAMP_SIZE];
+ } c_ts;
};
-struct wg_cookie_param {
- u_int8_t c_rval[WG_COOKIE_RVAL_SIZE];
- u_int8_t c_ival[WG_COOKIE_IVAL_MAXSIZE];
- u_int8_t c_ilen;
-};
-
-extern void (*const wg_task_fn[WG_TASK_NUM])(struct wg_peer *, struct mbuf_list *);
-
-/* Upcall is a struct to store callbacks for wireguard */
-struct wg_upcall {
- void (*uc_register_id)(struct wg_peer *, u_int32_t, bool);
- void (*uc_run_task_in)(struct wg_peer *, enum wg_task, u_int16_t);
-
- void *uc_arg;
- u_int8_t *(*uc_getpubkey)(void *);
- u_int8_t *(*uc_getprivkey)(void *);
- bool (*uc_getcookie)(void *, struct mbuf *, struct wg_cookie_param *);
- struct wg_peer *(*uc_lookupkey)(void *, u_int8_t [WG_KEY_SIZE]);
- struct wg_peer *(*uc_lookupid)(void *, u_int32_t);
-};
-
-/* Create and destroy a peer, upcall must live at least as long as the peer */
-void wg_peer_init(struct wg_peer *, struct wg_upcall *, void *);
-void wg_peer_deinit(struct wg_peer *);
-void wg_peer_cleanup(struct wg_peer *);
-
-/* Get/Set functions */
-int wg_peer_set_key(struct wg_peer *, const enum wg_key_type, const u_int8_t [WG_KEY_SIZE]);
-void wg_peer_set_pka(struct wg_peer *, u_int16_t);
-void wg_peer_get_key(struct wg_peer *, const enum wg_key_type, u_int8_t [WG_KEY_SIZE]);
-void wg_peer_get_state(struct wg_peer *, struct timespec *, enum wg_role *);
-
-/* For when a transport packet needs to be sent, or a packet arrives */
-void wg_peer_tx(struct wg_peer *, struct mbuf *, struct mbuf_list *);
-struct wg_peer *wg_peer_rx(struct wg_upcall *, struct mbuf *, struct mbuf_list *, struct mbuf_list *);
-
-/* Misc functions */
-void wg_util_key_generate(u_int8_t pubkey[WG_KEY_SIZE], u_int8_t privkey[WG_KEY_SIZE]);
-void wg_util_key_privtopub(u_int8_t pubkey[WG_KEY_SIZE], const u_int8_t privkey[WG_KEY_SIZE]);
-
-#endif /* _WIREGUARD_H_ */
+struct wg_msg_unknown {
+ uint32_t type;
+} __packed;
+
+struct wg_msg_initiation {
+ uint32_t type;
+ uint32_t sender;
+ uint8_t ephemeral[WG_KEY_SIZE];
+ uint8_t static_pub[WG_ENCRYPTED_SIZE(WG_KEY_SIZE)];
+ uint8_t timestamp[WG_ENCRYPTED_SIZE(WG_TIMESTAMP_SIZE)];
+ uint8_t mac1 [WG_MAC_SIZE];
+ uint8_t mac2 [WG_MAC_SIZE];
+} __packed;
+
+struct wg_msg_response {
+ uint32_t type;
+ uint32_t sender;
+ uint32_t receiver;
+ uint8_t ephemeral[WG_KEY_SIZE];
+ uint8_t empty [WG_ENCRYPTED_SIZE(0)];
+ uint8_t mac1 [WG_MAC_SIZE];
+ uint8_t mac2 [WG_MAC_SIZE];
+} __packed;
+
+struct wg_msg_cookie {
+ uint32_t type;
+ uint32_t receiver;
+ uint8_t nonce [WG_XNONCE_SIZE];
+ uint8_t cookie[WG_ENCRYPTED_SIZE(WG_COOKIE_SIZE)];
+} __packed;
+
+struct wg_msg_transport {
+ uint32_t type;
+ uint32_t receiver;
+ uint64_t counter;
+ uint8_t data [];
+} __packed;
+
+void wg_conn_make_initiation(struct wg_conn *, struct wg_msg_initiation *);
+int wg_conn_make_response(struct wg_conn *, struct wg_msg_response *);
+int wg_conn_make_cookie(struct wg_conn *, struct wg_msg_cookie *);
+int wg_conn_encrypt(struct wg_conn *, struct wg_msg_transport *, size_t);
+
+int wg_conn_recv_initiation(struct wg_msg_initiation_helper *, struct wg_msg_initiation *);
+int wg_conn_recv_response(struct wg_conn *, struct wg_msg_response *);
+int wg_conn_recv_cookie(struct wg_conn *, struct wg_msg_cookie *);
+int wg_conn_decrypt(struct wg_conn *, struct wg_msg_transport *, size_t);
+
+int wg_conn_promote_handshake(struct wg_conn *);
+
+#endif /* _LIBWG_H_ */