Index: ipsec.c =================================================================== RCS file: /usr/repo/src/sys/netipsec/ipsec.c,v retrieving revision 1.12 diff -u -p -r1.12 ipsec.c --- ipsec.c 2 Jun 2005 23:56:10 -0000 1.12 +++ ipsec.c 23 Mar 2006 23:32:59 -0000 @@ -148,6 +148,21 @@ SYSCTL_INT(_net_inet_ipsec, OID_AUTO, SYSCTL_STRUCT(_net_inet_ipsec, OID_AUTO, ipsecstats, CTLFLAG_RD, &newipsecstat, newipsecstat, ""); +/* + * When set to 1, IPsec will send packets with the same sequence number. + * This allows to verify if the other side has proper replay attacks detection. + */ +int ipsec_replay = 0; +SYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_replay, CTLFLAG_RW, &ipsec_replay, 0, + "Emulate replay attack"); +/* + * When set 1, IPsec will send packets with corrupted HMAC. + * This allows to verify if the other side properly detects modified packets. + */ +int ipsec_integrity = 0; +SYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_integrity, CTLFLAG_RW, + &ipsec_integrity, 0, "Emulate man-in-the-middle attack"); + #ifdef INET6 int ip6_esp_trans_deflev = IPSEC_LEVEL_USE; int ip6_esp_net_deflev = IPSEC_LEVEL_USE; Index: ipsec.h =================================================================== RCS file: /usr/repo/src/sys/netipsec/ipsec.h,v retrieving revision 1.9 diff -u -p -r1.9 ipsec.h --- ipsec.h 15 Mar 2006 21:11:11 -0000 1.9 +++ ipsec.h 23 Mar 2006 23:33:32 -0000 @@ -330,6 +330,8 @@ struct ipsec_history { }; extern int ipsec_debug; +extern int ipsec_replay; +extern int ipsec_integrity; extern struct newipsecstat newipsecstat; extern struct secpolicy ip4_def_policy; Index: xform_ah.c =================================================================== RCS file: /usr/repo/src/sys/netipsec/xform_ah.c,v retrieving revision 1.9 diff -u -p -r1.9 xform_ah.c --- xform_ah.c 23 Mar 2006 23:26:34 -0000 1.9 +++ xform_ah.c 29 Mar 2006 07:15:30 -0000 @@ -998,7 +998,9 @@ ah_output( error = EINVAL; goto bad; } - sav->replay->count++; + /* Emulate replay attack when ipsec_replay is TRUE. */ + if (!ipsec_replay) + sav->replay->count++; ah->ah_seq = htonl(sav->replay->count); } @@ -1178,6 +1180,18 @@ ah_output_cb(struct cryptop *crp) free(tc, M_XDATA); crypto_freereq(crp); + /* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */ + if (ipsec_integrity) { + int alen; + + /* + * Corrupt HMAC if we want to test integrity verification of + * the other side. + */ + alen = AUTHSIZE(sav); + m_copyback(m, m->m_pkthdr.len - alen, alen, ipseczeroes); + } + /* NB: m is reclaimed by ipsec_process_done. */ err = ipsec_process_done(m, isr); KEY_FREESAV(&sav); Index: xform_esp.c =================================================================== RCS file: /usr/repo/src/sys/netipsec/xform_esp.c,v retrieving revision 1.13 diff -u -p -r1.13 xform_esp.c --- xform_esp.c 23 Mar 2006 23:26:34 -0000 1.13 +++ xform_esp.c 29 Mar 2006 07:08:20 -0000 @@ -759,7 +759,12 @@ esp_output( /* Initialize ESP header. */ bcopy((caddr_t) &sav->spi, mtod(mo, caddr_t) + roff, sizeof(u_int32_t)); if (sav->replay) { - u_int32_t replay = htonl(++(sav->replay->count)); + u_int32_t replay; + + /* Emulate replay attack when ipsec_replay is TRUE. */ + if (!ipsec_replay) + sav->replay->count++; + replay = htonl(sav->replay->count); bcopy((caddr_t) &replay, mtod(mo, caddr_t) + roff + sizeof(u_int32_t), sizeof(u_int32_t)); @@ -942,6 +947,22 @@ esp_output_cb(struct cryptop *crp) free(tc, M_XDATA); crypto_freereq(crp); + /* Emulate man-in-the-middle attack when ipsec_integrity is TRUE. */ + if (ipsec_integrity) { + struct auth_hash *esph; + int alen; + + /* + * Corrupt HMAC if we want to test integrity verification of + * the other side. + */ + esph = sav->tdb_authalgxform; + if (esph != NULL) { + alen = esph->authsize; + m_copyback(m, m->m_pkthdr.len - alen, alen, ipseczeroes); + } + } + /* NB: m is reclaimed by ipsec_process_done. */ err = ipsec_process_done(m, isr); KEY_FREESAV(&sav);