From: Kristof Provost <k...@freebsd.org> Allow the kernel driver to notify us that it's time to renegotiate keys. The intent is to avoid IV re-use after 2^32 packets.
This is a first draft intended for discussion. The accompanying kernel change for FreeBSD can be found in https://reviews.freebsd.org/D39570 Signed-off-by: Kristof Provost <kprov...@netgate.com> --- src/openvpn/dco_freebsd.c | 4 ++++ src/openvpn/dco_freebsd.h | 1 + src/openvpn/forward.c | 32 +++++++++++++++++++++----------- src/openvpn/multi.c | 4 ++++ src/openvpn/ovpn_dco_freebsd.h | 1 + src/openvpn/ssl.c | 6 ++++++ src/openvpn/ssl.h | 3 +++ 7 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c index a334d5d2..1111abeb 100644 --- a/src/openvpn/dco_freebsd.c +++ b/src/openvpn/dco_freebsd.c @@ -550,6 +550,10 @@ dco_do_read(dco_context_t *dco) dco->dco_message_type = OVPN_CMD_DEL_PEER; break; + case OVPN_NOTIF_ROTATE_KEY: + dco->dco_message_type = OVPN_CMD_SWAP_KEYS; + break; + default: msg(M_WARN, "Unknown kernel notification %d", type); break; diff --git a/src/openvpn/dco_freebsd.h b/src/openvpn/dco_freebsd.h index a07f9b69..e1a054e0 100644 --- a/src/openvpn/dco_freebsd.h +++ b/src/openvpn/dco_freebsd.h @@ -35,6 +35,7 @@ typedef enum ovpn_key_cipher dco_cipher_t; enum ovpn_message_type_t { OVPN_CMD_DEL_PEER, OVPN_CMD_PACKET, + OVPN_CMD_SWAP_KEYS, }; enum ovpn_del_reason_t { diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index b3e0ba5d..d50eb457 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -1232,20 +1232,30 @@ process_incoming_dco(struct context *c) return; } - if (dco->dco_message_type != OVPN_CMD_DEL_PEER) + switch (dco->dco_message_type) { - msg(D_DCO_DEBUG, "%s: received message of type %u - ignoring", __func__, - dco->dco_message_type); - return; - } + case OVPN_CMD_DEL_PEER: + if (dco->dco_del_peer_reason == OVPN_DEL_PEER_REASON_EXPIRED) + { + msg(D_DCO_DEBUG, "%s: received peer expired notification of for peer-id " + "%d", __func__, dco->dco_message_peer_id); + trigger_ping_timeout_signal(c); + return; + } + break; - if (dco->dco_del_peer_reason == OVPN_DEL_PEER_REASON_EXPIRED) - { - msg(D_DCO_DEBUG, "%s: received peer expired notification of for peer-id " - "%d", __func__, dco->dco_message_peer_id); - trigger_ping_timeout_signal(c); - return; + case OVPN_CMD_SWAP_KEYS: + msg(D_DCO_DEBUG, "%s: received key rotation notification for peer-id %d", + __func__, dco->dco_message_peer_id); + tls_session_soft_reset(c->c2.tls_multi); + break; + + default: + msg(D_DCO_DEBUG, "%s: received message of type %u - ignoring", __func__, + dco->dco_message_type); + return; } + #endif /* if defined(ENABLE_DCO) && (defined(TARGET_LINUX) || defined(TARGET_FREEBSD)) */ } diff --git a/src/openvpn/multi.c b/src/openvpn/multi.c index 5444e752..6fb9cff2 100644 --- a/src/openvpn/multi.c +++ b/src/openvpn/multi.c @@ -3284,6 +3284,10 @@ multi_process_incoming_dco(struct multi_context *m) { process_incoming_del_peer(m, mi, dco); } + else if (dco->dco_message_type == OVPN_CMD_SWAP_KEYS) + { + tls_session_soft_reset(mi->context.c2.tls_multi); + } } else { diff --git a/src/openvpn/ovpn_dco_freebsd.h b/src/openvpn/ovpn_dco_freebsd.h index fec33835..53f94dfd 100644 --- a/src/openvpn/ovpn_dco_freebsd.h +++ b/src/openvpn/ovpn_dco_freebsd.h @@ -36,6 +36,7 @@ enum ovpn_notif_type { OVPN_NOTIF_DEL_PEER, + OVPN_NOTIF_ROTATE_KEY, }; enum ovpn_del_reason { diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 60aaee8d..26e86c8d 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -1918,6 +1918,12 @@ key_state_soft_reset(struct tls_session *session) ks->remote_addr = ks_lame->remote_addr; } +void +tls_session_soft_reset(struct tls_multi *tls_multi) +{ + key_state_soft_reset(&tls_multi->session[TM_ACTIVE]); +} + /* * Read/write strings from/to a struct buffer with a u16 length prefix. */ diff --git a/src/openvpn/ssl.h b/src/openvpn/ssl.h index 4ed4cfaa..3c40fbed 100644 --- a/src/openvpn/ssl.h +++ b/src/openvpn/ssl.h @@ -573,6 +573,9 @@ bool tls_session_generate_data_channel_keys(struct tls_multi *multi, struct tls_session *session); +void +tls_session_soft_reset(struct tls_multi *multi); + /** * Load ovpn.xkey provider used for external key signing */ -- 2.40.0 _______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel