From d5da100c55d80391d2e941a41c0e0dccf2a6e33e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 28 May 2014 04:52:58 +0200 Subject: Still more documentation --- src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.c | 12 ++++++ src/protocols/ec25519_fhmqvc/ec25519_fhmqvc.h | 60 ++++++++++++++++++--------- src/protocols/ec25519_fhmqvc/handshake.h | 36 +++++++++++++--- 3 files changed, 84 insertions(+), 24 deletions(-) (limited to 'src/protocols') 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 +/** 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); } -- cgit v1.2.3