summaryrefslogtreecommitdiffstats
path: root/src/wireguard.h
diff options
context:
space:
mode:
authorMatt Dunwoodie <ncon@mail.noconroy.net>2019-09-18 16:23:10 +0200
committerMatt Dunwoodie <ncon@mail.noconroy.net>2019-09-18 16:29:33 +0200
commit1943d676b71f6017a0fa62e50698599ac2f4bc00 (patch)
tree98f1d5e42ebd6135527edb044a88132368c95746 /src/wireguard.h
parentRename *_clean to *_reset (diff)
downloadwireguard-openbsd-1943d676b71f6017a0fa62e50698599ac2f4bc00.tar.xz
wireguard-openbsd-1943d676b71f6017a0fa62e50698599ac2f4bc00.zip
Add documentation to wireguard.h, TODOs to correct wireguard.c
Diffstat (limited to 'src/wireguard.h')
-rw-r--r--src/wireguard.h175
1 files changed, 170 insertions, 5 deletions
diff --git a/src/wireguard.h b/src/wireguard.h
index 057b44a4a34..efef1cefe2a 100644
--- a/src/wireguard.h
+++ b/src/wireguard.h
@@ -227,27 +227,146 @@ static char *wg_error_str[] = {
"invalid ID",
};
+/* wg_handshake_init:
+ * Will zero out all memory and setup lock on handshake.
+ *
+ * wg_handshake_reset:
+ * Will zero out all the individual handshake data such as ephemeral keys, and
+ * the internal Noise state. It will leave the static keys and counters as is.
+ * The state follows:
+ * WG_STATE_* -> WG_STATE_CLEAN
+ */
void wg_handshake_init(struct wg_handshake *);
-void wg_session_init(struct wg_session *);
void wg_handshake_reset(struct wg_handshake *);
+
+/* wg_session_init:
+ * Will zero out all memory and setup lock on session.
+ *
+ * wg_session_reset:
+ * Will zero out all the individual session data except the lock, ready for
+ * passing the session to wg_session_from_handshake. The state follows:
+ * WG_STATE_* -> WG_STATE_CLEAN
+ */
+void wg_session_init(struct wg_session *);
void wg_session_reset(struct wg_session *);
+/* wg_handshake_make_initiation:
+ * Given a clean wg_handshake and id, fill the wg_msg_initiation with a
+ * prepared packet.
+ * Error (else WG_OK):
+ * WG_STATE: wg_handshake is not WG_STATE_CLEAN.
+ * WG_HS_ATTEMPTS: wg_handshake has exceeded WG_REKEY_ATTEMT_COUNT.
+ * The state follows:
+ * WG_STATE_CLEAN -> WG_STATE_MADE_INITIATION
+ *
+ * wg_handshake_make_response:
+ * Given a wg_handshake that has received an initiation and id, fill the
+ * wg_msg_response with a prepared packet.
+ * Error (else WG_OK);
+ * WG_STATE: wg_handshake is not WG_STATE_RECV_INITIATION
+ * The state follows:
+ * WG_STATE_RECV_INITIATION -> WG_STATE_MADE_RESPONSE
+ *
+ * wg_handshake_make_cookie:
+ * wg_keypair: local keypair to tie cookie to.
+ * wg_cookie: cookie to encrypt
+ * uint32_t: sender id that will be placed in cookie.
+ * uint8_t[WG_MAG_SIZE]: mac of packet in response to
+ * wg_msg_cookie: packet to fill
+ */
enum wg_error wg_handshake_make_initiation(struct wg_handshake *, uint32_t, struct wg_msg_initiation *);
enum wg_error wg_handshake_make_response(struct wg_handshake *, uint32_t, struct wg_msg_response *);
enum wg_error wg_handshake_make_cookie(struct wg_keypair *, struct wg_cookie *, uint32_t, uint8_t [WG_MAC_SIZE], struct wg_msg_cookie *);
+/*
+ * wg_handshake_recv_initiation:
+ * Given a temporary wg_handshake that will be merged with an actual
+ * wg_handshake, decrypt the wg_msg_initiation with the wg_keypair and store
+ * the parameters in the temporary wg_handshake. the hs_spub (handshake static
+ * public key) will be set.
+ * Error (else WG_OK);
+ * WG_DECRYPT: could not decrypt static_pub or timestamp in packet.
+ * WG_MAC: invalid mac on packet.
+ * The state follows:
+ * * -> WG_STATE_RECV_INITIATION
+ *
+ * wg_handshake_recv_response:
+ * Given a wg_handshake that has made an initiation, process the incoming
+ * response packet. A temporary handshake is made so that the original is not
+ * tainted while processing the incoming packet.
+ * Error (else WG_OK);
+ * WG_STATE: wg_handshake is not WG_STATE_MADE_INITIATION.
+ * WG_ID: the receiver ID (local) doesn't match the stored ID in handshake.
+ * WG_DECRYPT: could not decrypt the response packet.
+ * WG_MAC: the packet mac was invalid.
+ * The state follows:
+ * WG_STATE_MADE_INITIATION -> WG_STATE_RECV_RESPONSE
+ *
+ * wg_handshake_recv_cookie:
+ * Given a wg_handshake that has made an initiation or response, ingest a
+ * cookie packet and if successful, save the cookie in the handshake. The
+ * cookie will automatically be used when calling the next make_initiation or
+ * make_response.
+ * Error (else WG_OK);
+ * WG_STATE: wg_handshake not in WG_STATE_MADE_INITIATION
+ * WG_STATE: wg_handshake not in WG_STATE_MADE_RESPONSE
+ * WG_ID: the receiver ID (local) doesn't match the stored ID in handshake.
+ * WG_DECRYPT: could not decrypt the cookie packet.
+ */
enum wg_error wg_handshake_recv_initiation(struct wg_handshake *, struct wg_keypair *, struct wg_msg_initiation *);
enum wg_error wg_handshake_recv_response(struct wg_handshake *, struct wg_msg_response *);
enum wg_error wg_handshake_recv_cookie(struct wg_handshake *, struct wg_msg_cookie *);
+/* wg_handshake_merge:
+ * Copy the src wg_handshake to the dst wg_handshake. The only purpose of this
+ * is to merge a temporary wg_handshake generated from an incoming
+ * wg_msg_initiation. It will clear the src handshake before returning.
+ * Error (else WG_OK);
+ * WG_STATE: wg_handshake (dst) is not WG_STATE_CLEAN.
+ * WG_STATE: wg_handshake (src) is not WG_STATE_RECV_INITIATION.
+ * WG_STATE: wg_handshake keys do not match.
+ * WG_TIMESTAMP: wg_handshake (dst) has a newer timestamp.
+ * The state follows:
+ * WG_STATE_CLEAN -> WG_STATE_RECV_INITIATION
+ */
+enum wg_error wg_handshake_merge(struct wg_handshake *, struct wg_handshake *);
+
+/* wg_handshake_initiation_valid_mac2:
+ * Validate mac2 (the IP binding MAC) in a wg_msg_initiation. The wg_cookie
+ * must be supplied. It will return WG_MAC if invalid mac or WG_OK if ok.
+ *
+ * wg_handshake_response_valid_mac2:
+ * Validate mac2 (the IP binding MAC) in a wg_msg_initiation. The wg_cookie
+ * must be supplied. It will return WG_MAC if invalid mac or WG_OK if ok.
+ *
+ * wg_handshake_initiation_ready:
+ * Check if minimum time has elapsed before sending new initiation. It will
+ * return WG_HS_RATE if the caller should wait, or WG_OK if the minimum time
+ * has elapsed.
+ *
+ * wg_handshake_reset_attempts:
+ * Reset the handshake attempt count to 0.
+ */
enum wg_error wg_handshake_initiation_valid_mac2(struct wg_cookie *, struct wg_msg_initiation *);
enum wg_error wg_handshake_response_valid_mac2(struct wg_cookie *, struct wg_msg_response *);
-enum wg_error wg_handshake_merge(struct wg_handshake *, struct wg_handshake *);
enum wg_error wg_handshake_initiation_ready(struct wg_handshake *);
void wg_handshake_reset_attempts(struct wg_handshake *);
+/* Get handshake parameters.
+ * wg_handshake_id:
+ * Return the local handshake ID.
+ *
+ * wg_handshake_shortkey:
+ * Return the first 4 bytes of the handshake remote static public key.
+ *
+ * wg_session_id:
+ * Return the local session ID.
+ */
uint32_t wg_handshake_id(struct wg_handshake *);
uint32_t wg_handshake_shortkey(struct wg_handshake *);
+uint32_t wg_session_id(struct wg_session *);
+
+/* Set handshake parameters */
void wg_handshake_setkeypair(struct wg_handshake *, struct wg_keypair *);
void wg_handshake_setkey(struct wg_handshake *, uint8_t[WG_KEY_SIZE]);
void wg_handshake_setshared(struct wg_handshake *, uint8_t[WG_KEY_SIZE]);
@@ -255,13 +374,59 @@ void wg_handshake_getkey(struct wg_handshake *, uint8_t[WG_KEY_SIZE]);
void wg_handshake_getshared(struct wg_handshake *, uint8_t[WG_KEY_SIZE]);
int wg_handshake_keycmp(struct wg_handshake *, struct wg_handshake *);
-uint32_t wg_session_id(struct wg_session *);
-enum wg_error wg_session_encrypt(struct wg_session *, struct wg_msg_transport *, size_t);
-enum wg_error wg_session_decrypt(struct wg_session *, struct wg_msg_transport *, size_t);
+/* wg_session_from_handshake:
+ * Populate wg_session based on wg_handshake. wg_handshake must be in either
+ * WG_STATE_RECV_RESPONSE or WG_STATE_MADE_RESPONSE. The handshake will be
+ * zeroed out before returning. The wg_session must be passed to
+ * wg_session_confirm before it can be used to encrypt/decrypt messages.
+ * Error (else WG_OK);
+ * WG_STATE: wg_handshake is not in state WG_STATE_RECV_RESPONSE.
+ * WG_STATE: wg_handshake is not in state WG_STATE_MADE_RESPONSE.
+ * WG_STATE: wg_session is not in state WG_STATE_CLEAN.
+ * The state follows (depending on wg_handshake):
+ * WG_STATE_CLEAN -> WG_STATE_RECV_RESPONSE
+ * WG_STATE_CLEAN -> WG_STATE_MADE_RESPONSE
+ *
+ * wg_session_confirm:
+ * Confirm a session is ready to be used.
+ * Error (else WG_OK);
+ * WG_STATE: wg_session is not in state WG_STATE_RECV_RESPONSE.
+ * WG_STATE: wg_session is not in state WG_STATE_MADE_RESPONSE.
+ * The state follows (depending on wg_handshake):
+ * WG_STATE_RECV_RESPONSE -> WG_STATE_INITIATOR
+ * WG_STATE_MADE_RESPONSE -> WG_STATE_RESPONDER
+ *
+ * wg_session_ready:
+ * Return weather wg_session_confirm has been called on wg_session. Return
+ * WG_STATE if not, and WG_OK if it has.
+ */
enum wg_error wg_session_from_handshake(struct wg_session *, struct wg_handshake *);
enum wg_error wg_session_confirm(struct wg_session *);
enum wg_error wg_session_ready(struct wg_session *);
+/* wg_session_encrypt:
+ * Encrypt a wg_msg_transport of size size_t (data len, not including header).
+ * Error (else WG_OK);
+ * WG_REJECT: wg_session is not allowed to encrypt, too old.
+ * WG_STATE: wg_session is not in state WG_STATE_INITIATOR.
+ * WG_STATE: wg_session is not in state WG_STATE_RESPONDER.
+ * WG_REKEY: wg_session successfully encrypted, but wants a new session.
+ *
+ * wg_session_decrypt:
+ * Decrypt a wg_msg_transport of size size_t (data len, not including header).
+ * Error (else WG_OK);
+ * WG_REJECT: wg_session is not allowed to decrypt, too old.
+ * WG_STATE: wg_session is not in state WG_STATE_INITIATOR.
+ * WG_STATE: wg_session is not in state WG_STATE_RESPONDER.
+ * WG_ID: wg_session ID doesn't match incoming packet ID.
+ * WG_DECRYPT: wg_session could not decrypt message (bad MAC).
+ * WG_REPLAY: wg_session detected replay of packet.
+ * WG_REKEY: wg_session successfully decrypted, but wants a new session.
+ */
+enum wg_error wg_session_encrypt(struct wg_session *, struct wg_msg_transport *, size_t);
+enum wg_error wg_session_decrypt(struct wg_session *, struct wg_msg_transport *, size_t);
+
+/* Minor helper functions */
void wg_keypair_from_bytes(struct wg_keypair *, const uint8_t [WG_KEY_SIZE]);
void wg_keypair_generate(struct wg_keypair *);
enum wg_pkt_type wg_pkt_type(uint8_t *, size_t);