summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2014-05-28 04:52:58 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2014-05-28 04:52:58 +0200
commitd5da100c55d80391d2e941a41c0e0dccf2a6e33e (patch)
tree1aca67556ed8ea1e2f9fa2a73ebf1a84e8cd34a7
parentd859894f7a88e07e7beae8dc355278cfd6c185e2 (diff)
downloadfastd-d5da100c55d80391d2e941a41c0e0dccf2a6e33e.tar
fastd-d5da100c55d80391d2e941a41c0e0dccf2a6e33e.zip
Still more documentation
-rw-r--r--src/async.c2
-rw-r--r--src/async.h2
-rw-r--r--src/buffer.h2
-rw-r--r--src/capabilities.c7
-rw-r--r--src/compat.h2
-rw-r--r--src/crypto.h23
-rw-r--r--src/dlist.h6
-rw-r--r--src/fastd.h2
-rw-r--r--src/handshake.c25
-rw-r--r--src/handshake.h2
-rw-r--r--src/log.h2
-rw-r--r--src/method.h2
-rw-r--r--src/methods/common.c9
-rw-r--r--src/methods/common.h53
-rw-r--r--src/peer.c2
-rw-r--r--src/peer.h2
-rw-r--r--src/poll.c2
-rw-r--r--src/poll.h2
-rw-r--r--src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c12
-rw-r--r--src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h60
-rw-r--r--src/protocols/ec25519_fhmqvc/handshake.h36
-rw-r--r--src/random.c6
-rw-r--r--src/receive.c16
-rw-r--r--src/resolve.c2
-rw-r--r--src/send.c15
-rw-r--r--src/sha256.c2
-rw-r--r--src/sha256.h2
-rw-r--r--src/shell.c2
-rw-r--r--src/shell.h2
-rw-r--r--src/tuntap.c6
-rw-r--r--src/types.h2
-rw-r--r--src/vector.c2
-rw-r--r--src/vector.h6
33 files changed, 257 insertions, 61 deletions
diff --git a/src/async.c b/src/async.c
index fb1af41..fa93cd0 100644
--- a/src/async.c
+++ b/src/async.c
@@ -24,7 +24,7 @@
*/
/**
- \file src/async.c
+ \file
Asynchronous notifications
*/
diff --git a/src/async.h b/src/async.h
index 4622c3c..e3298d4 100644
--- a/src/async.h
+++ b/src/async.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/async.h
+ \file
Asynchronous notifications
*/
diff --git a/src/buffer.h b/src/buffer.h
index afd18d5..5b2e16a 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/buffer.h
+ \file
Buffer management
*/
diff --git a/src/capabilities.c b/src/capabilities.c
index 8a7e823..9da3fd4 100644
--- a/src/capabilities.c
+++ b/src/capabilities.c
@@ -23,6 +23,12 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ Handling of POSIX capabilities
+*/
+
#include "fastd.h"
@@ -31,6 +37,7 @@
#include <sys/capability.h>
+/** Tries to acquire a capability */
static void try_cap(cap_value_t cap) {
char *name = cap_to_name(cap);
if (!name)
diff --git a/src/compat.h b/src/compat.h
index 25e6be5..af7264d 100644
--- a/src/compat.h
+++ b/src/compat.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/compat.h
+ \file
Portablity definitions
*/
diff --git a/src/crypto.h b/src/crypto.h
index fbb77ec..8f94fae 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/crypto.h
+ \file
Cyptographic algorithm API and utilities
*/
@@ -38,29 +38,41 @@
#include <string.h>
+/** Contains information about a cipher algorithm */
struct fastd_cipher_info {
- size_t key_length;
- size_t iv_length;
+ size_t key_length; /**< The key length used by the cipher */
+ size_t iv_length; /**< The initialization vector length used by the cipher */
};
+/** A stream cipher implementation */
struct fastd_cipher {
+ /**< Checks if the algorithm is available on the platform used. If NULL, the algorithm is always available. */
bool (*available)(void);
+ /** Initializes a cipher context with the given key */
fastd_cipher_state_t* (*init)(const uint8_t *key);
+ /** Encrypts or decrypts data */
bool (*crypt)(const fastd_cipher_state_t *state, fastd_block128_t *out, const fastd_block128_t *in, size_t len, const uint8_t *iv);
+ /** Frees a cipher context */
void (*free)(fastd_cipher_state_t *state);
};
+/** Contains information about a message authentication code algorithm */
struct fastd_mac_info {
- size_t key_length;
+ size_t key_length; /**< The key length used by the MAC */
};
+/** A MAC implementation */
struct fastd_mac {
+ /**< Checks if the algorithm is available on the platform used. If NULL, the algorithm is always available. */
bool (*available)(void);
+ /** Initializes a MAC context with the given key */
fastd_mac_state_t* (*init)(const uint8_t *key);
+ /** Computes the MAC of data blocks */
bool (*hash)(const fastd_mac_state_t *state, fastd_block128_t *out, const fastd_block128_t *in, size_t n_blocks);
+ /** Frees a MAC context */
void (*free)(fastd_mac_state_t *state);
};
@@ -80,16 +92,19 @@ const fastd_mac_info_t* fastd_mac_info_get_by_name(const char *name);
const fastd_mac_t* fastd_mac_get(const fastd_mac_info_t *info);
+/** Sets a range of memory to zero, ensuring the operation can't be optimized out by the compiler */
static inline void secure_memzero(void *s, size_t n) {
memset(s, 0, n);
__asm__ volatile("" : : "m"(s));
}
+/** XORs two blocks of data */
static inline void xor(fastd_block128_t *x, const fastd_block128_t *a, const fastd_block128_t *b) {
x->qw[0] = a->qw[0] ^ b->qw[0];
x->qw[1] = a->qw[1] ^ b->qw[1];
}
+/** XORs one block of data into another */
static inline void xor_a(fastd_block128_t *x, const fastd_block128_t *a) {
xor(x, x, a);
}
diff --git a/src/dlist.h b/src/dlist.h
index a8118f0..0ca6928 100644
--- a/src/dlist.h
+++ b/src/dlist.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/dlist.h
+ \file
Doubly-linked lists
*/
@@ -38,8 +38,8 @@ typedef struct fastd_dlist_head fastd_dlist_head_t;
/** Doubly-linked list element */
struct fastd_dlist_head {
- fastd_dlist_head_t *prev;
- fastd_dlist_head_t *next;
+ fastd_dlist_head_t *prev; /**< The next element of the list or NULL */
+ fastd_dlist_head_t *next; /**< The previous element of the list or NULL */
};
diff --git a/src/fastd.h b/src/fastd.h
index 50f90a9..3dd5568 100644
--- a/src/fastd.h
+++ b/src/fastd.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/fastd.h
+ \file
\em fastd main header file defining most data structures
*/
diff --git a/src/handshake.c b/src/handshake.c
index d0d6016..e8b2197 100644
--- a/src/handshake.c
+++ b/src/handshake.c
@@ -23,6 +23,12 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ Functions and structures for composing and decomposing handshake packets
+*/
+
#include "handshake.h"
#include "method.h"
@@ -30,6 +36,7 @@
#include <fastd_version.h>
+/** Human-readable names for the TLV record types */
static const char *const RECORD_TYPES[RECORD_MAX] = {
"handshake type",
"reply code",
@@ -50,10 +57,14 @@ static const char *const RECORD_TYPES[RECORD_MAX] = {
};
+/** Reads a TLV record as an 8bit integer */
#define AS_UINT8(ptr) (*(uint8_t*)(ptr).data)
+
+/** Reads a TLV record as a 16bit integer (big endian) */
#define AS_UINT16(ptr) ((*(uint8_t*)(ptr).data) + (*((uint8_t*)(ptr).data+1) << 8))
+/** Generates a zero-separated list of supported methods */
static uint8_t* create_method_list(size_t *len) {
*len = 0;
@@ -72,6 +83,7 @@ static uint8_t* create_method_list(size_t *len) {
return ret;
}
+/** Checks if a string is equal to a buffer with a maximum length */
static inline bool string_equal(const char *str, const char *buf, size_t maxlen) {
if (strlen(str) != strnlen(buf, maxlen))
return false;
@@ -79,10 +91,12 @@ static inline bool string_equal(const char *str, const char *buf, size_t maxlen)
return !strncmp(str, buf, maxlen);
}
+/** Checks if a string is equal to the value of a TLV record */
static inline bool record_equal(const char *str, const fastd_handshake_record_t *record) {
return string_equal(str, (const char*)record->data, record->length);
}
+/** Parses a list of zero-separated strings */
static fastd_string_stack_t* parse_string_list(const uint8_t *data, size_t len) {
const uint8_t *end = data+len;
fastd_string_stack_t *ret = NULL;
@@ -97,6 +111,7 @@ static fastd_string_stack_t* parse_string_list(const uint8_t *data, size_t len)
return ret;
}
+/** Allocates and initializes a new handshake packet */
static fastd_buffer_t new_handshake(uint8_t type, const fastd_method_info_t *method, bool with_method_list, size_t tail_space) {
size_t version_len = strlen(FASTD_VERSION);
size_t protocol_len = strlen(conf.protocol->name);
@@ -139,16 +154,19 @@ static fastd_buffer_t new_handshake(uint8_t type, const fastd_method_info_t *met
return buffer;
}
+/** Allocates and initializes a new initial handshake packet */
fastd_buffer_t fastd_handshake_new_init(size_t tail_space) {
return new_handshake(1, NULL, !conf.secure_handshakes, tail_space);
}
+/** Allocates and initializes a new reply handshake packet */
fastd_buffer_t fastd_handshake_new_reply(uint8_t type, const fastd_method_info_t *method, bool with_method_list, size_t tail_space) {
fastd_buffer_t buffer = new_handshake(type, method, with_method_list, tail_space);
fastd_handshake_add_uint8(&buffer, RECORD_REPLY_CODE, 0);
return buffer;
}
+/** Prints the error corresponding to the given reply code and error detail */
static void print_error(const char *prefix, const fastd_peer_address_t *remote_addr, uint8_t reply_code, uint8_t error_detail) {
const char *error_field_str;
@@ -174,6 +192,7 @@ static void print_error(const char *prefix, const fastd_peer_address_t *remote_a
}
}
+/** Sends an error reply to a peer */
static void send_error(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, const fastd_handshake_t *handshake, uint8_t reply_code, uint8_t error_detail) {
print_error("sending", remote_addr, reply_code, error_detail);
@@ -190,6 +209,7 @@ static void send_error(fastd_socket_t *sock, const fastd_peer_address_t *local_a
fastd_send_handshake(sock, local_addr, remote_addr, peer, buffer);
}
+/** Parses the TLV records of a handshake */
static inline fastd_handshake_t parse_tlvs(const fastd_buffer_t *buffer) {
fastd_handshake_t handshake = {};
@@ -232,6 +252,7 @@ static inline fastd_handshake_t parse_tlvs(const fastd_buffer_t *buffer) {
return handshake;
}
+/** Prints the error found in a received handshake */
static inline void print_error_reply(const fastd_peer_address_t *remote_addr, const fastd_handshake_t *handshake) {
uint8_t reply_code = AS_UINT8(handshake->records[RECORD_REPLY_CODE]);
uint8_t error_detail = RECORD_MAX;
@@ -242,6 +263,7 @@ static inline void print_error_reply(const fastd_peer_address_t *remote_addr, co
print_error("received", remote_addr, reply_code, error_detail);
}
+/** Does some basic validity checks on a received handshake */
static inline bool check_records(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, const fastd_handshake_t *handshake) {
if (handshake->records[RECORD_PROTOCOL_NAME].data) {
if (!record_equal(conf.protocol->name, &handshake->records[RECORD_PROTOCOL_NAME])) {
@@ -281,6 +303,7 @@ static inline bool check_records(fastd_socket_t *sock, const fastd_peer_address_
return true;
}
+/** Returns the method info with a specified name and length */
static inline const fastd_method_info_t* get_method_by_name(const char *name, size_t n) {
char name0[n+1];
memcpy(name0, name, n);
@@ -289,6 +312,7 @@ static inline const fastd_method_info_t* get_method_by_name(const char *name, si
return fastd_method_get_by_name(name0);
}
+/** Returns the most appropriate method to negotiate with a peer a handshake was received from */
static inline const fastd_method_info_t* get_method(const fastd_handshake_t *handshake) {
if (handshake->records[RECORD_METHOD_LIST].data && handshake->records[RECORD_METHOD_LIST].length) {
fastd_string_stack_t *method_list = parse_string_list(handshake->records[RECORD_METHOD_LIST].data, handshake->records[RECORD_METHOD_LIST].length);
@@ -314,6 +338,7 @@ static inline const fastd_method_info_t* get_method(const fastd_handshake_t *han
return get_method_by_name((const char*)handshake->records[RECORD_METHOD_NAME].data, handshake->records[RECORD_METHOD_NAME].length);
}
+/** Handles a handshake packet */
void fastd_handshake_handle(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer) {
char *peer_version = NULL;
const fastd_method_info_t *method = NULL;
diff --git a/src/handshake.h b/src/handshake.h
index 34597ed..2be71e5 100644
--- a/src/handshake.h
+++ b/src/handshake.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/handshake.h
+ \file
Functions and structures for composing and decomposing handshake packets
*/
diff --git a/src/log.h b/src/log.h
index ec11299..7d4ea41 100644
--- a/src/log.h
+++ b/src/log.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/log.h
+ \file
Logging functions and macros
*/
diff --git a/src/method.h b/src/method.h
index da70a7b..4ae9e0a 100644
--- a/src/method.h
+++ b/src/method.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/method.h
+ \file
Management of encryption methods
*/
diff --git a/src/methods/common.c b/src/methods/common.c
index 3fb8561..d26f009 100644
--- a/src/methods/common.c
+++ b/src/methods/common.c
@@ -23,10 +23,17 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ Definitions for the common packet format used by most methods
+*/
+
#include "common.h"
+/** Common initialization for a new session */
void fastd_method_common_init(fastd_method_common_t *session, bool initiator) {
memset(session, 0, sizeof(*session));
@@ -42,6 +49,7 @@ void fastd_method_common_init(fastd_method_common_t *session, bool initiator) {
}
}
+/** Checks if a received nonce is valid */
bool fastd_method_is_nonce_valid(const fastd_method_common_t *session, const uint8_t nonce[COMMON_NONCEBYTES], int64_t *age) {
if ((nonce[0] & 1) != (session->receive_nonce[0] & 1))
return false;
@@ -67,6 +75,7 @@ bool fastd_method_is_nonce_valid(const fastd_method_common_t *session, const uin
return true;
}
+/** Checks if a possibly reordered packet should be accepted */
bool fastd_method_reorder_check(fastd_peer_t *peer, fastd_method_common_t *session, const uint8_t nonce[COMMON_NONCEBYTES], int64_t age) {
if (age < 0) {
size_t shift = age < (-64) ? 64 : ((size_t)-age);
diff --git a/src/methods/common.h b/src/methods/common.h
index 7b0a4ff..7a06f92 100644
--- a/src/methods/common.h
+++ b/src/methods/common.h
@@ -23,26 +23,37 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ Definitions for the common packet format used by most methods
+*/
+
#pragma once
#include "../fastd.h"
+/** The length of the nonce in the common method packet header */
#define COMMON_NONCEBYTES 6
+/** The length of the flags in the common method packet header */
#define COMMON_FLAGBYTES 1
+/** The length of the common method packet header */
#define COMMON_HEADBYTES (COMMON_NONCEBYTES+COMMON_FLAGBYTES)
+
+/** Common method session state */
typedef struct fastd_method_common {
- struct timespec valid_till;
- struct timespec refresh_after;
+ struct timespec valid_till; /**< How long the session is valid */
+ struct timespec refresh_after; /**< When to try refreshing the session */
- uint8_t send_nonce[COMMON_NONCEBYTES];
- uint8_t receive_nonce[COMMON_NONCEBYTES];
+ uint8_t send_nonce[COMMON_NONCEBYTES]; /**< The next nonce to use */
+ uint8_t receive_nonce[COMMON_NONCEBYTES]; /**< The hightest nonce received to far for this session */
- struct timespec reorder_timeout;
- uint64_t receive_reorder_seen;
+ struct timespec reorder_timeout; /**< How long to packets with a lower sequence number (nonce) than the newest received */
+ uint64_t receive_reorder_seen; /**< Bitmap specifying which of the 64 sequence numbers (nonces) before \a receive_nonce have bit seen */
} fastd_method_common_t;
@@ -51,6 +62,11 @@ bool fastd_method_is_nonce_valid(const fastd_method_common_t *session, const uin
bool fastd_method_reorder_check(fastd_peer_t *peer, fastd_method_common_t *session, const uint8_t nonce[COMMON_NONCEBYTES], int64_t age);
+/**
+ The common \a session_is_valid implementation
+
+ A session is valid when session->valid_till has not timeouted, unless almost all nonces have been used up (which \b should be impossible)
+*/
static inline bool fastd_method_session_common_is_valid(const fastd_method_common_t *session) {
if (session->send_nonce[0] == 0xff && session->send_nonce[1] == 0xff)
return false;
@@ -58,10 +74,20 @@ static inline bool fastd_method_session_common_is_valid(const fastd_method_commo
return (!fastd_timed_out(&session->valid_till));
}
+/**
+ The common \a session_is_initiator implementation
+
+ The initiator of a session uses the odd nonces, the responder the even ones.
+*/
static inline bool fastd_method_session_common_is_initiator(const fastd_method_common_t *session) {
return (session->send_nonce[COMMON_NONCEBYTES-1] & 1);
}
+/**
+ The common \a session_want_refresh implementation
+
+ A session wants to be refreshed when session->refresh_after has timeouted, or if lots of nonces have been used up
+*/
static inline bool fastd_method_session_common_want_refresh(const fastd_method_common_t *session) {
if (session->send_nonce[0] == 0xff)
return true;
@@ -72,6 +98,7 @@ static inline bool fastd_method_session_common_want_refresh(const fastd_method_c
return false;
}
+/** The common \a session_superseded implementation */
static inline void fastd_method_session_common_superseded(fastd_method_common_t *session) {
struct timespec valid_max = fastd_in_seconds(KEY_VALID_OLD);
@@ -79,6 +106,12 @@ static inline void fastd_method_session_common_superseded(fastd_method_common_t
session->valid_till = valid_max;
}
+/**
+ Increments the send nonce
+
+ As one side of a connection uses the even nonces and the other side the odd ones,
+ the nonce is always incremented by 2.
+*/
static inline void fastd_method_increment_nonce(fastd_method_common_t *session) {
session->send_nonce[COMMON_NONCEBYTES-1] += 2;
@@ -91,22 +124,30 @@ static inline void fastd_method_increment_nonce(fastd_method_common_t *session)
}
}
+/** Adds the common header to a packet buffer */
static inline void fastd_method_put_common_header(fastd_buffer_t *buffer, const uint8_t nonce[COMMON_NONCEBYTES], uint8_t flags) {
fastd_buffer_pull_head_from(buffer, nonce, COMMON_NONCEBYTES);
fastd_buffer_pull_head_from(buffer, &flags, 1);
}
+/** Removes the common header from a packet buffer */
static inline void fastd_method_take_common_header(fastd_buffer_t *buffer, uint8_t nonce[COMMON_NONCEBYTES], uint8_t *flags) {
fastd_buffer_push_head_to(buffer, flags, 1);
fastd_buffer_push_head_to(buffer, nonce, COMMON_NONCEBYTES);
}
+/** Handles the common header of a packet */
static inline bool fastd_method_handle_common_header(const fastd_method_common_t *session, fastd_buffer_t *buffer, uint8_t nonce[COMMON_NONCEBYTES], uint8_t *flags, int64_t *age) {
fastd_method_take_common_header(buffer, nonce, flags);
return fastd_method_is_nonce_valid(session, nonce, age);
}
+/**
+ Expands a nonce from COMMON_NONCEBYTES to a buffer of arbitrary length
+
+ The last byte of the buffer is set to 1 as many cryptographic algorithms are specified to have a counter starting with 1 concatenated to the nonce
+*/
static inline void fastd_method_expand_nonce(uint8_t *buf, const uint8_t nonce[COMMON_NONCEBYTES], size_t len) {
if (!len)
return;
diff --git a/src/peer.c b/src/peer.c
index 924d4b0..cc27eb4 100644
--- a/src/peer.c
+++ b/src/peer.c
@@ -24,7 +24,7 @@
*/
/**
- \file src/peer.c
+ \file
Implementations of functions for peer management
*/
diff --git a/src/peer.h b/src/peer.h
index 5eb8b87..9da5f3c 100644
--- a/src/peer.h
+++ b/src/peer.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/peer.h
+ \file
Structures and functions for peer management
*/
diff --git a/src/poll.c b/src/poll.c
index f10e619..a2d206b 100644
--- a/src/poll.c
+++ b/src/poll.c
@@ -24,7 +24,7 @@
*/
/**
- \file src/poll.c
+ \file
Portable polling API implementations
*/
diff --git a/src/poll.h b/src/poll.h
index 456ee68..5e1d718 100644
--- a/src/poll.h
+++ b/src/poll.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/poll.h
+ \file
Portable polling API
*/
diff --git a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c
index 70944fe..b97bf4d 100644
--- a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c
+++ b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c
@@ -27,6 +27,7 @@
#include "ec25519_fhmqvc.h"
+/** Converts a private or public key from a hexadecimal string representation to a uint8 array */
static inline bool read_key(uint8_t key[32], const char *hexkey) {
if ((strlen(hexkey) != 64) || (strspn(hexkey, "0123456789abcdefABCDEF") != 64))
return false;
@@ -38,6 +39,7 @@ static inline bool read_key(uint8_t key[32], const char *hexkey) {
return true;
}
+/** Checks if the current session with a peers needs refreshing */
static inline void check_session_refresh(fastd_peer_t *peer) {
protocol_session_t *session = &peer->protocol_state->session;
@@ -49,6 +51,7 @@ static inline void check_session_refresh(fastd_peer_t *peer) {
}
}
+/** Initializes the protocol-specific configuration */
static fastd_protocol_config_t* protocol_init(void) {
fastd_protocol_config_t *protocol_config = malloc(sizeof(fastd_protocol_config_t));
@@ -65,6 +68,7 @@ static fastd_protocol_config_t* protocol_init(void) {
return protocol_config;
}
+/** Checks if a peer configuration is valid */
static void protocol_peer_verify(fastd_peer_config_t *peer_conf) {
if (!peer_conf->key)
exit_error("no key configured for peer `%s'", peer_conf->name);
@@ -74,6 +78,7 @@ static void protocol_peer_verify(fastd_peer_config_t *peer_conf) {
exit_error("invalid key configured for peer `%s'", peer_conf->name);
}
+/** Initializes the protocol-specific peer configuration */
static void protocol_peer_configure(fastd_peer_config_t *peer_conf) {
if (peer_conf->protocol_config)
return;
@@ -96,6 +101,7 @@ static void protocol_peer_configure(fastd_peer_config_t *peer_conf) {
pr_debug("found own key as `%s', ignoring peer", peer_conf->name);
}
+/** Checks if the current session with a peer is valid and resets the connection if not */
static inline bool check_session(fastd_peer_t *peer) {
if (is_session_valid(&peer->protocol_state->session))
return true;
@@ -105,6 +111,7 @@ static inline bool check_session(fastd_peer_t *peer) {
return false;
}
+/** Handles a payload packet received from a peer */
static void protocol_handle_recv(fastd_peer_t *peer, fastd_buffer_t buffer) {
if (!peer->protocol_state || !check_session(peer))
goto fail;
@@ -158,6 +165,7 @@ static void protocol_handle_recv(fastd_peer_t *peer, fastd_buffer_t buffer) {
fastd_buffer_free(buffer);
}
+/** Encrypts and sends a packet to a peer using a specified session */
static void session_send(fastd_peer_t *peer, fastd_buffer_t buffer, protocol_session_t *session) {
size_t stat_size = buffer.len;
@@ -172,6 +180,7 @@ static void session_send(fastd_peer_t *peer, fastd_buffer_t buffer, protocol_ses
peer->keepalive_timeout = fastd_in_seconds(KEEPALIVE_TIMEOUT);
}
+/** Encrypts and sends a packet to a peer */
static void protocol_send(fastd_peer_t *peer, fastd_buffer_t buffer) {
if (!peer->protocol_state || !fastd_peer_is_established(peer) || !check_session(peer)) {
fastd_buffer_free(buffer);
@@ -189,10 +198,13 @@ static void protocol_send(fastd_peer_t *peer, fastd_buffer_t buffer) {
}
}
+/** Sends an empty payload packet (i.e. keepalive) to a peer using a specified session */
void fastd_protocol_ec25519_fhmqvc_send_empty(fastd_peer_t *peer, protocol_session_t *session) {
session_send(peer, fastd_buffer_alloc(0, alignto(session->method->provider->min_encrypt_head_space, 8), session->method->provider->min_encrypt_tail_space), session);
}
+
+/** The \em ec25519-fhmqvc protocol definition */
const fastd_protocol_t fastd_protocol_ec25519_fhmqvc = {
.name = "ec25519-fhmqvc",
diff --git a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h
index 6dcc149..fb07d19 100644
--- a/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h
+++ b/src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h
@@ -23,6 +23,12 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ ec25519-fhmqvc protocol: general definitions
+*/
+
#pragma once
@@ -34,49 +40,64 @@
#include <libuecc/ecc.h>
+/** The length of a \em ec25519-fhmqvc public key */
#define PUBLICKEYBYTES 32
+
+/** The length of a \em ec25519-fhmqvc private key */
#define SECRETKEYBYTES 32
+/** A \e libuecc int256, aligned to 32bit, so it can be used as input to the SHA256 functions */
typedef union aligned_int256 {
- ecc_int256_t int256;
- uint32_t u32[8];
- uint8_t u8[32];
+ ecc_int256_t int256; /**< ecc_int256_t access */
+ uint32_t u32[8]; /**< 32bit-wise access */
+ uint8_t u8[32]; /**< byte-wise access */
} aligned_int256_t;
+/** A keypair */
typedef struct keypair {
- ecc_int256_t secret;
- aligned_int256_t public;
+ ecc_int256_t secret; /**< The section key */
+ aligned_int256_t public; /**< The public key */
} keypair_t;
+/** The protocol-specific configuration */
struct fastd_protocol_config {
- keypair_t key;
+ keypair_t key; /**< The own keypair */
};
+/** The protocol-specific peer configuration */
struct fastd_protocol_peer_config {
- aligned_int256_t public_key;
+ aligned_int256_t public_key; /**< The peer's public key */
};
+/** Session state */
typedef struct protocol_session {
+ /**
+ Stores if remaining handshakes have been unqueued after session establishment.
+
+ After a session has been established, further scheduled handshakes aren't unqueued
+ before it has been ensured the other side has established the session as well.
+ */
bool handshakes_cleaned;
- bool refreshing;
+ bool refreshing; /**< true if a session refresh has been triggered by the local side */
- const fastd_method_info_t *method;
- fastd_method_session_state_t *method_state;
+ const fastd_method_info_t *method; /**< The used crypto method */
+ fastd_method_session_state_t *method_state; /**< The method-specific state */
} protocol_session_t;
+/** Protocol-specific peer state */
struct fastd_protocol_peer_state {
- protocol_session_t old_session;
- protocol_session_t session;
+ protocol_session_t old_session; /**< An old, not yet invalidated session */
+ protocol_session_t session; /**< The newest session */
- uint64_t last_serial;
+ uint64_t last_serial; /**< The serial number of the ephemeral keypair used for the last session establishment */
/* handshake cache */
- uint64_t last_handshake_serial;
- aligned_int256_t peer_handshake_key;
- aligned_int256_t sigma;
- fastd_sha256_t shared_handshake_key;
- fastd_sha256_t shared_handshake_key_compat;
+ uint64_t last_handshake_serial; /**< The serial number of the ephemeral keypair used in the last handshake */
+ aligned_int256_t peer_handshake_key; /**< The peer's ephemeral public key used in the last handshake */
+ aligned_int256_t sigma; /**< The value of sigma used in the last handshake */
+ fastd_sha256_t shared_handshake_key; /**< The shared handshake key used in the last handshake */
+ fastd_sha256_t shared_handshake_key_compat; /**< The shared handshake key used in the last handshake (pre-v11 compatiblity protocol) */
};
@@ -103,13 +124,14 @@ void fastd_protocol_ec25519_fhmqvc_set_shell_env(fastd_shell_env_t *env, const f
bool fastd_protocol_ec25519_fhmqvc_describe_peer(const fastd_peer_t *peer, char *buf, size_t len);
+/** Converts a 32 byte value to a hexadecimal string representation */
static inline void hexdump(char out[65], const unsigned char d[32]) {
size_t i;
for (i = 0; i < 32; i++)
snprintf(out+2*i, 3, "%02x", d[i]);
}
-
+/** Checks if a session is currently valid */
static inline bool is_session_valid(const protocol_session_t *session) {
return (session->method && session->method->provider->session_is_valid(session->method_state));
}
diff --git a/src/protocols/ec25519_fhmqvc/handshake.h b/src/protocols/ec25519_fhmqvc/handshake.h
index 1578913..a05e542 100644
--- a/src/protocols/ec25519_fhmqvc/handshake.h
+++ b/src/protocols/ec25519_fhmqvc/handshake.h
@@ -23,30 +23,56 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ ec25519-fhmqvc protocol: handshake handling
+*/
+
#pragma once
#include "ec25519_fhmqvc.h"
+/**
+ An ephemeral keypair used for the handshake protocol
+
+ When a keypair's \e preferred_till has timed out, a new keypair
+ will be generated.
+*/
typedef struct handshake_key {
+ /**
+ With each keypair, the serial number gets incremented.
+ By saving the serial number for established sessions,
+ it can be ensured that no two sessions with the same peer are established
+ with the same keypair
+ */
uint64_t serial;
- struct timespec preferred_till;
- struct timespec valid_till;
- keypair_t key;
+ struct timespec preferred_till; /**< Specifies how long this keypair will be used for new handshakes */
+ struct timespec valid_till; /**< Specifies how long handshakes using this keypair will be answered */
+
+ keypair_t key; /**< The actual keypair */
} handshake_key_t;
+/**
+ The protocol-specific global state
+
+ There are up to two keys valid at the same time.
+*/
struct fastd_protocol_state {
- handshake_key_t prev_handshake_key;
- handshake_key_t handshake_key;
+ handshake_key_t prev_handshake_key; /**< The previously generated handshake keypair */
+ handshake_key_t handshake_key; /**< The newest handshake keypair */
};
+/** Checks if a handshake keypair is currently valid */
static inline bool is_handshake_key_valid(const handshake_key_t *handshake_key) {
return !fastd_timed_out(&handshake_key->valid_till);
}
+/** Checks if a handshake keypair is currently peferred */
static inline bool is_handshake_key_preferred(const handshake_key_t *handshake_key) {
return !fastd_timed_out(&handshake_key->preferred_till);
}
diff --git a/src/random.c b/src/random.c
index 71a3ad1..72a238b 100644
--- a/src/random.c
+++ b/src/random.c
@@ -23,6 +23,12 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ Utilities for random data
+*/
+
#include "fastd.h"
diff --git a/src/receive.c b/src/receive.c
index 3813d7f..aae4f8f 100644
--- a/src/receive.c
+++ b/src/receive.c
@@ -23,6 +23,12 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ Functions for receiving and handling packets
+*/
+
#include "fastd.h"
#include "handshake.h"
@@ -30,6 +36,7 @@
#include "peer_hashtable.h"
+/** Handles the ancillary control messages of received packets */
static inline void handle_socket_control(struct msghdr *message, const fastd_socket_t *sock, fastd_peer_address_t *local_addr) {
memset(local_addr, 0, sizeof(fastd_peer_address_t));
@@ -77,6 +84,11 @@ static inline void handle_socket_control(struct msghdr *message, const fastd_soc
}
}
+/**
+ Checks if a handshake should be sent after an unexpected payload packet has been received
+
+ backoff_unknown() tries to avoid flooding hosts with handshakes.
+*/
static bool backoff_unknown(const fastd_peer_address_t *addr) {
size_t i;
for (i = 0; i < array_size(ctx.unknown_handshakes); i++) {
@@ -104,6 +116,7 @@ static bool backoff_unknown(const fastd_peer_address_t *addr) {
return false;
}
+/** Handles a packet received from a known peer address */
static inline void handle_socket_receive_known(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer) {
if (!fastd_peer_may_connect(peer)) {
fastd_buffer_free(buffer);
@@ -131,10 +144,12 @@ static inline void handle_socket_receive_known(fastd_socket_t *sock, const fastd
}
}
+/** Determines if packets from known addresses are accepted */
static inline bool allow_unknown_peers(void) {
return conf.has_floating || fastd_allow_verify();
}
+/** Handles a packet received from an unknown address */
static inline void handle_socket_receive_unknown(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_buffer_t buffer) {
const uint8_t *packet_type = buffer.data;
fastd_buffer_push_head(&buffer, 1);
@@ -152,6 +167,7 @@ static inline void handle_socket_receive_unknown(fastd_socket_t *sock, const fas
}
}
+/** Handles a packet read from a socket */
static inline void handle_socket_receive(fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_buffer_t buffer) {
fastd_peer_t *peer = NULL;
diff --git a/src/resolve.c b/src/resolve.c
index 0635ddf..b37cef6 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -24,7 +24,7 @@
*/
/**
- \file src/resolve.c
+ \file
DNS resolver functions
*/
diff --git a/src/send.c b/src/send.c
index ce92244..c613fc6 100644
--- a/src/send.c
+++ b/src/send.c
@@ -23,11 +23,18 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ Functions for sending packets
+*/
+
#include "fastd.h"
#include "peer.h"
+/** Adds packet info to ancillary control messages */
static inline void add_pktinfo(struct msghdr *msg, const fastd_peer_address_t *local_addr) {
if (!local_addr)
return;
@@ -66,6 +73,7 @@ static inline void add_pktinfo(struct msghdr *msg, const fastd_peer_address_t *l
}
}
+/** Adds statistics for a single packet of a given size */
static inline void count_stat(fastd_stats_t *stats, size_t stat_size) {
if (stat_size) {
stats->packets++;
@@ -73,6 +81,7 @@ static inline void count_stat(fastd_stats_t *stats, size_t stat_size) {
}
}
+/** Sends a packet of a given type */
static void send_type(const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, uint8_t packet_type, fastd_buffer_t buffer, size_t stat_size) {
if (!sock)
exit_bug("send: sock == NULL");
@@ -168,12 +177,12 @@ static void send_type(const fastd_socket_t *sock, const fastd_peer_address_t *lo
fastd_buffer_free(buffer);
}
-/** Sends a payload packet to a peer */
+/** Sends a payload packet */
void fastd_send(const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer, size_t stat_size) {
send_type(sock, local_addr, remote_addr, peer, PACKET_DATA, buffer, stat_size);
}
-/** Sends a handshake packet to a peer */
+/** Sends a handshake packet */
void fastd_send_handshake(const fastd_socket_t *sock, const fastd_peer_address_t *local_addr, const fastd_peer_address_t *remote_addr, fastd_peer_t *peer, fastd_buffer_t buffer) {
send_type(sock, local_addr, remote_addr, peer, PACKET_HANDSHAKE, buffer, 0);
}
@@ -205,6 +214,7 @@ static inline fastd_eth_addr_t get_dest_address(const fastd_buffer_t buffer) {
return ret;
}
+/** Handles sending of a payload packet to a single peer in TAP mode */
static inline bool send_data_tap_single(fastd_buffer_t buffer, fastd_peer_t *source) {
if (conf.mode != MODE_TAP)
return false;
@@ -233,6 +243,7 @@ static inline bool send_data_tap_single(fastd_buffer_t buffer, fastd_peer_t *sou
return true;
}
+/** Sends a buffer of payload data to other peers */
void fastd_send_data(fastd_buffer_t buffer, fastd_peer_t *source) {
if (send_data_tap_single(buffer, source))
return;
diff --git a/src/sha256.c b/src/sha256.c
index bed55fd..a9007da 100644
--- a/src/sha256.c
+++ b/src/sha256.c
@@ -24,7 +24,7 @@
*/
/**
- \file src/sha256.c
+ \file
Small SHA256 and HMAC-SHA256 implementation
*/
diff --git a/src/sha256.h b/src/sha256.h
index 2d45b2d..f553cad 100644
--- a/src/sha256.h
+++ b/src/sha256.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/sha256.h
+ \file
Small SHA256 and HMAC-SHA256 implementation
*/
diff --git a/src/shell.c b/src/shell.c
index 524d38e..c573a85 100644
--- a/src/shell.c
+++ b/src/shell.c
@@ -25,7 +25,7 @@
/**
- \file src/shell.c
+ \file
Execution of shell commands and management of environment variables
*/
diff --git a/src/shell.h b/src/shell.h
index 3a402f7..141126b 100644
--- a/src/shell.h
+++ b/src/shell.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/shell.h
+ \file
Execution of shell commands and management of environment variables
*/
diff --git a/src/tuntap.c b/src/tuntap.c
index 7bd5f82..b5a5df9 100644
--- a/src/tuntap.c
+++ b/src/tuntap.c
@@ -23,6 +23,11 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/**
+ \file
+
+ Management of the TUN/TAP interface
+*/
#include "fastd.h"
#include "poll.h"
@@ -46,6 +51,7 @@
#endif
+/** Defines if the platform uses an address family header on TUN interfaces */
#ifdef __linux__
static const bool multiaf_tun = false;
#else
diff --git a/src/types.h b/src/types.h
index 6854a7c..d13828c 100644
--- a/src/types.h
+++ b/src/types.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/types.h
+ \file
Basic enums and typedefs for common types
*/
diff --git a/src/vector.c b/src/vector.c
index 4b451b1..6e8c18d 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -24,7 +24,7 @@
*/
/**
- \file src/vector.c
+ \file
Typesafe dynamically sized arrays
*/
diff --git a/src/vector.h b/src/vector.h
index 526dfaf..0571d4d 100644
--- a/src/vector.h
+++ b/src/vector.h
@@ -24,7 +24,7 @@
*/
/**
- \file src/vector.h
+ \file
Typesafe dynamically sized arrays
*/
@@ -37,8 +37,8 @@
/** A vector descriptor */
typedef struct fastd_vector_desc {
- size_t allocated;
- size_t length;
+ size_t allocated; /**< The number of elements currently allocated */
+ size_t length; /**< The actual number of elements in the vector */
} fastd_vector_desc_t;