Vulnerability: programs/pluto/ikev1.c in libreswan before 3.17 retransmits in initial-responder states, which allows remote attackers to cause a denial of service (traffic amplification) via a spoofed UDP packet. NOTE: the original behavior complies with the IKEv1 protocol, but has a required security update from the libreswan vendor; as of 2016-06-10, it is expected that several other IKEv1 implementations will have vendor-required security updates, with separate CVE IDs assigned to each.
Vulnerability ID: CVE-2016-5361
CWE: CWE-20
Severity score: 2.9
Project: https://github.com/libreswan/libreswan
Published: 2016-06-16
File: programs/pluto/ikev1.c
Commit message: IKEv1: packet retransmit fixes for Main/Aggr/Xauth modes

- Do not schedule retransmits for inI1outR1 packets (prevent DDOS)
- Do schedule retransmits for XAUTH packets
Commit author: Paul Wouters

Vulnerable version (before fix):
 static const struct state_microcode v1_state_microcode_table[] = { 	{ STATE_MAIN_R0, STATE_MAIN_R1, 	  SMF_ALL_AUTH | SMF_REPLY, 	  P(SA), P(VID) | P(CR), PT(NONE), 	  EVENT_v1_RETRANSMIT, main_inI1_outR1 },  	/* STATE_MAIN_I1: R1 --> I2 	 * HDR, SA --> auth dependent static const struct state_microcode v1_state_microcode_table[] = { 	{ STATE_AGGR_R0, STATE_AGGR_R1, 	  SMF_PSK_AUTH | SMF_DS_AUTH | SMF_REPLY, 	  P(SA) | P(KE) | P(NONCE) | P(ID), P(VID) | P(NATD_RFC), PT(NONE), 	  EVENT_v1_RETRANSMIT, aggr_inI1_outR1 },  	/* STATE_AGGR_I1: 	 * SMF_PSK_AUTH: HDR, SA, KE, Nr, IDir, HASH_R static const struct state_microcode v1_state_microcode_table[] = { 	{ STATE_XAUTH_I0, STATE_XAUTH_I1, 	  SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2, 	  P(MCFG_ATTR) | P(HASH), P(VID), PT(HASH), 	  EVENT_SA_REPLACE, xauth_inI0 },  	{ STATE_XAUTH_I1, STATE_MAIN_I4, 	  SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2, 	  P(MCFG_ATTR) | P(HASH), P(VID), PT(HASH), 	  EVENT_SA_REPLACE, xauth_inI1 },  #undef P #undef PT

Fixed version (after fix):
 static const struct state_microcode v1_state_microcode_table[] = { 	{ STATE_MAIN_R0, STATE_MAIN_R1, 	  SMF_ALL_AUTH | SMF_REPLY, 	  P(SA), P(VID) | P(CR), PT(NONE), 	  EVENT_NULL, main_inI1_outR1 },  	/* STATE_MAIN_I1: R1 --> I2 	 * HDR, SA --> auth dependent static const struct state_microcode v1_state_microcode_table[] = { 	{ STATE_AGGR_R0, STATE_AGGR_R1, 	  SMF_PSK_AUTH | SMF_DS_AUTH | SMF_REPLY, 	  P(SA) | P(KE) | P(NONCE) | P(ID), P(VID) | P(NATD_RFC), PT(NONE), 	  EVENT_NULL, aggr_inI1_outR1 },  	/* STATE_AGGR_I1: 	 * SMF_PSK_AUTH: HDR, SA, KE, Nr, IDir, HASH_R static const struct state_microcode v1_state_microcode_table[] = { 	{ STATE_XAUTH_I0, STATE_XAUTH_I1, 	  SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2, 	  P(MCFG_ATTR) | P(HASH), P(VID), PT(HASH), 	  EVENT_v1_RETRANSMIT, xauth_inI0 },  	{ STATE_XAUTH_I1, STATE_MAIN_I4, 	  SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2, 	  P(MCFG_ATTR) | P(HASH), P(VID), PT(HASH), 	  EVENT_v1_RETRANSMIT, xauth_inI1 },  #undef P #undef PT

Patch:
patch: @@ -245,7 +245,7 @@ static const struct state_microcode v1_state_microcode_table[] = {
 	{ STATE_MAIN_R0, STATE_MAIN_R1,
 	  SMF_ALL_AUTH | SMF_REPLY,
 	  P(SA), P(VID) | P(CR), PT(NONE),
-	  EVENT_v1_RETRANSMIT, main_inI1_outR1 },
+	  EVENT_NULL, main_inI1_outR1 },
 
 	/* STATE_MAIN_I1: R1 --> I2
 	 * HDR, SA --> auth dependent
@@ -394,7 +394,7 @@ static const struct state_microcode v1_state_microcode_table[] = {
 	{ STATE_AGGR_R0, STATE_AGGR_R1,
 	  SMF_PSK_AUTH | SMF_DS_AUTH | SMF_REPLY,
 	  P(SA) | P(KE) | P(NONCE) | P(ID), P(VID) | P(NATD_RFC), PT(NONE),
-	  EVENT_v1_RETRANSMIT, aggr_inI1_outR1 },
+	  EVENT_NULL, aggr_inI1_outR1 },
 
 	/* STATE_AGGR_I1:
 	 * SMF_PSK_AUTH: HDR, SA, KE, Nr, IDir, HASH_R
@@ -571,12 +571,12 @@ static const struct state_microcode v1_state_microcode_table[] = {
 	{ STATE_XAUTH_I0, STATE_XAUTH_I1,
 	  SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2,
 	  P(MCFG_ATTR) | P(HASH), P(VID), PT(HASH),
-	  EVENT_SA_REPLACE, xauth_inI0 },
+	  EVENT_v1_RETRANSMIT, xauth_inI0 },
 
 	{ STATE_XAUTH_I1, STATE_MAIN_I4,
 	  SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2,
 	  P(MCFG_ATTR) | P(HASH), P(VID), PT(HASH),
-	  EVENT_SA_REPLACE, xauth_inI1 },
+	  EVENT_v1_RETRANSMIT, xauth_inI1 },
 
 #undef P
 #undef PT
path: programs/pluto/ikev1.c