From 9c773f8d112d7374e77ee804e89f5b6b5da84f16 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 26 Jan 2016 11:13:13 +0100 Subject: [PATCH] ha: Properly sync IKEv1 IV if gateway is initiator To handle Phase 2 exchanges on the other HA host we need to sync the last block of the last Phase 1 message (or the last expected IV). If the gateway is the initiator of a Main Mode SA the last message is an inbound message. When handling such messages the expected IV is not updated until it is successfully decrypted so we can't sync the IV when processing the still encrypted (!plain) message. However, as responder, i.e. if the last message is an outbound message, the reverse applies, that is, we get the next IV after successfully encrypting the message, not while handling the plain message. Fixes #1267. --- src/libcharon/plugins/ha/ha_ike.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/libcharon/plugins/ha/ha_ike.c b/src/libcharon/plugins/ha/ha_ike.c index f0671c5..3ffcaee 100644 --- a/src/libcharon/plugins/ha/ha_ike.c +++ b/src/libcharon/plugins/ha/ha_ike.c @@ -314,27 +314,31 @@ METHOD(listener_t, message_hook, bool, sync_vips(this, ike_sa); } } - if (!plain && ike_sa->get_version(ike_sa) == IKEV1) + if (ike_sa->get_version(ike_sa) == IKEV1) { ha_message_t *m; keymat_v1_t *keymat; - u_int32_t mid; chunk_t iv; - mid = message->get_message_id(message); - if (mid == 0) + /* we need the last block (or expected next IV) of Phase 1, which gets + * upated after successful en-/decryption depending on direction */ + if (incoming == plain) { - keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa); - if (keymat->get_iv(keymat, mid, &iv)) + if (message->get_message_id(message) == 0) { - m = ha_message_create(HA_IKE_IV); - m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa)); - m->add_attribute(m, HA_IV, iv); - this->socket->push(this->socket, m); - this->cache->cache(this->cache, ike_sa, m); + keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa); + if (keymat->get_iv(keymat, 0, &iv)) + { + m = ha_message_create(HA_IKE_IV); + m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa)); + m->add_attribute(m, HA_IV, iv); + this->socket->push(this->socket, m); + this->cache->cache(this->cache, ike_sa, m); + } } } - if (!incoming && message->get_exchange_type(message) == TRANSACTION) + if (!plain && !incoming && + message->get_exchange_type(message) == TRANSACTION) { sync_vips(this, ike_sa); } -- 2.7.4