diff options
author | pjd <pjd@FreeBSD.org> | 2006-04-09 19:11:45 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2006-04-09 19:11:45 +0000 |
commit | 0501edbc66645c32bd26858286dc77bbda7e3720 (patch) | |
tree | 77a503b7833e317fcc529ff99d821491c8d3ddfc /sys | |
parent | b9b788a5760c97968cafc3828641761cfe07fae2 (diff) | |
download | FreeBSD-src-0501edbc66645c32bd26858286dc77bbda7e3720.zip FreeBSD-src-0501edbc66645c32bd26858286dc77bbda7e3720.tar.gz |
Introduce two new sysctls:
net.inet.ipsec.test_replay - 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.
net.inet.ipsec.test_integrity - When set 1, IPsec will send packets with
corrupted HMAC. This allows to verify if the other side properly
detects modified packets.
I used the first one to discover that we don't have proper replay attacks
detection in ESP (in fast_ipsec(4)).
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netipsec/ipsec.c | 15 | ||||
-rw-r--r-- | sys/netipsec/ipsec.h | 2 | ||||
-rw-r--r-- | sys/netipsec/xform_ah.c | 16 | ||||
-rw-r--r-- | sys/netipsec/xform_esp.c | 23 |
4 files changed, 54 insertions, 2 deletions
diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c index 4038c00..76bd99e 100644 --- a/sys/netipsec/ipsec.c +++ b/sys/netipsec/ipsec.c @@ -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; diff --git a/sys/netipsec/ipsec.h b/sys/netipsec/ipsec.h index 8fd1068..1d1fa0b 100644 --- a/sys/netipsec/ipsec.h +++ b/sys/netipsec/ipsec.h @@ -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; diff --git a/sys/netipsec/xform_ah.c b/sys/netipsec/xform_ah.c index e3da578..cd23fe3 100644 --- a/sys/netipsec/xform_ah.c +++ b/sys/netipsec/xform_ah.c @@ -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); diff --git a/sys/netipsec/xform_esp.c b/sys/netipsec/xform_esp.c index 8a87f45..a556167 100644 --- a/sys/netipsec/xform_esp.c +++ b/sys/netipsec/xform_esp.c @@ -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) { + static unsigned char ipseczeroes[AH_HMAC_HASHLEN]; + struct auth_hash *esph; + + /* + * Corrupt HMAC if we want to test integrity verification of + * the other side. + */ + esph = sav->tdb_authalgxform; + if (esph != NULL) { + m_copyback(m, m->m_pkthdr.len - AH_HMAC_HASHLEN, + AH_HMAC_HASHLEN, ipseczeroes); + } + } + /* NB: m is reclaimed by ipsec_process_done. */ err = ipsec_process_done(m, isr); KEY_FREESAV(&sav); |