From 342d63a45a8918e45ddcf6a0b82b2f593f4bde12 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 30 Mar 2012 18:40:23 +0200 Subject: Limit key validity --- src/config.c | 3 +++ src/fastd.h | 6 ++++++ src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c | 23 +++++++++++------------ src/queue.c | 7 +------ 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/config.c b/src/config.c index 5da6abe..1eda277 100644 --- a/src/config.c +++ b/src/config.c @@ -62,8 +62,11 @@ static void default_config(fastd_config *conf) { conf->mtu = 1500; conf->mode = MODE_TAP; + conf->protocol = &fastd_protocol_null; conf->secret = NULL; + conf->rekey = 3600; + conf->peers = NULL; conf->on_up = NULL; diff --git a/src/fastd.h b/src/fastd.h index 4db53e4..cceaaf3 100644 --- a/src/fastd.h +++ b/src/fastd.h @@ -92,6 +92,7 @@ struct _fastd_config { fastd_protocol *protocol; char *secret; + unsigned rekey; fastd_peer_config *peers; @@ -198,6 +199,11 @@ static inline size_t fastd_max_packet_size(const fastd_context *ctx) { } } +static inline bool timespec_after(const struct timespec *tp1, const struct timespec *tp2) { + return (tp1->tv_sec > tp2->tv_sec || + (tp1->tv_sec == tp2->tv_sec && tp1->tv_nsec > tp2->tv_nsec)); +} + /* returns (tp1 - tp2) in milliseconds */ static inline int timespec_diff(const struct timespec *tp1, const struct timespec *tp2) { return ((tp1->tv_sec - tp2->tv_sec))*1000 + (tp1->tv_nsec - tp2->tv_nsec)/1e6; diff --git a/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c b/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c index 4888589..df551fb 100644 --- a/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c +++ b/src/protocol_ec25519_fhmqvc_xsalsa20_poly1305.c @@ -90,9 +90,8 @@ typedef struct _protocol_handshake { } protocol_handshake; typedef struct _protocol_session { - bool valid; + struct timespec valid_till; uint8_t key[HASHBYTES]; - struct timespec since; uint8_t send_nonce[NONCEBYTES]; uint8_t receive_nonce[NONCEBYTES]; @@ -148,6 +147,10 @@ static inline void increment_nonce(uint8_t nonce[NONCEBYTES]) { } } +static inline bool is_session_valid(fastd_context *ctx, protocol_session *session) { + return timespec_after(&session->valid_till, &ctx->now); +} + static inline bool is_nonce_valid(const uint8_t nonce[NONCEBYTES], const uint8_t old_nonce[NONCEBYTES]) { if ((nonce[0] & 1) != (old_nonce[0] & 1)) return false; @@ -214,11 +217,7 @@ static void init_peer_state(fastd_context *ctx, fastd_peer *peer) { return; peer->protocol_state = malloc(sizeof(fastd_protocol_peer_state)); - - peer->protocol_state->old_session.valid = false; - peer->protocol_state->session.valid = false; - peer->protocol_state->initiating_handshake = NULL; - peer->protocol_state->accepting_handshake = NULL; + memset(peer->protocol_state, 0, sizeof(fastd_protocol_peer_state)); } static inline void free_handshake(protocol_handshake *handshake) { @@ -342,7 +341,7 @@ static void establish(fastd_context *ctx, fastd_peer *peer, const fastd_peer_con int i; uint8_t hashinput[5*PUBLICKEYBYTES]; - if (peer->protocol_state->session.valid) + if (is_session_valid(ctx, &peer->protocol_state->session)) peer->protocol_state->old_session = peer->protocol_state->session; memcpy(hashinput, X->p, PUBLICKEYBYTES); @@ -352,8 +351,8 @@ static void establish(fastd_context *ctx, fastd_peer *peer, const fastd_peer_con memcpy(hashinput+4*PUBLICKEYBYTES, sigma->p, PUBLICKEYBYTES); crypto_hash_sha256(peer->protocol_state->session.key, hashinput, 5*PUBLICKEYBYTES); - peer->protocol_state->session.valid = true; - peer->protocol_state->session.since = ctx->now; + peer->protocol_state->session.valid_till = ctx->now; + peer->protocol_state->session.valid_till.tv_sec += ctx->conf->rekey; peer->protocol_state->session.send_nonce[0] = initiator ? 3 : 2; peer->protocol_state->session.receive_nonce[0] = initiator ? 0 : 1; @@ -589,7 +588,7 @@ static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buf if (buffer.len < NONCEBYTES) goto end; - if (!peer->protocol_state || !peer->protocol_state->session.valid) { + if (!peer->protocol_state || !is_session_valid(ctx, &peer->protocol_state->session)) { pr_debug(ctx, "received unexpected packet from %P", peer); goto end; } @@ -626,7 +625,7 @@ static void protocol_handle_recv(fastd_context *ctx, fastd_peer *peer, fastd_buf } static void protocol_send(fastd_context *ctx, fastd_peer *peer, fastd_buffer buffer) { - if (!peer->protocol_state || !peer->protocol_state->session.valid) { + if (!peer->protocol_state || !is_session_valid(ctx, &peer->protocol_state->session)) { fastd_buffer_free(buffer); return; } diff --git a/src/queue.c b/src/queue.c index a2ef3dc..2509538 100644 --- a/src/queue.c +++ b/src/queue.c @@ -30,11 +30,6 @@ #include -static inline bool after(const struct timespec *tp1, const struct timespec *tp2) { - return (tp1->tv_sec > tp2->tv_sec || - (tp1->tv_sec == tp2->tv_sec && tp1->tv_nsec > tp2->tv_nsec)); -} - void fastd_queue_put(fastd_context *ctx, fastd_queue *queue, fastd_queue_entry *entry, int timeout) { entry->timeout = ctx->now; @@ -50,7 +45,7 @@ void fastd_queue_put(fastd_context *ctx, fastd_queue *queue, fastd_queue_entry * fastd_queue_entry **current; for (current = &queue->head;; current = &(*current)->next) { - if (!(*current) || after(&(*current)->timeout, &entry->timeout)) { + if (!(*current) || timespec_after(&(*current)->timeout, &entry->timeout)) { entry->next = *current; *current = entry; break; -- cgit v1.2.3