From 024c310b537abc3ddbac3054de71fd759d422824 Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Wed, 8 Apr 2009 20:15:01 +0200 Subject: Fixes broken cryptographic authentication in OSPF Cryptographic authentication in OSPF is defective by design - there might be several packets independently sent to the network (for example HELLO, LSUPD and LSACK) where they might be reordered and that causes crypt. sequence number error. That can be workarounded by not incresing sequence number too often. Now we update it only when last packet was sent before at least one second. This can constitute a risk of replay attacks, but RFC supposes something similar (like time in seconds used as CSN). --- proto/ospf/packet.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'proto/ospf/packet.c') diff --git a/proto/ospf/packet.c b/proto/ospf/packet.c index c6b233f..23785fe 100644 --- a/proto/ospf/packet.c +++ b/proto/ospf/packet.c @@ -75,13 +75,25 @@ ospf_pkt_finalize(struct ospf_iface *ifa, struct ospf_packet *pkt) pkt->checksum = 0; + /* Perhaps use random value to prevent replay attacks after + reboot when system does not have independent RTC? */ if (!ifa->csn) - ifa->csn = (u32) time(NULL); + { + ifa->csn = (u32) now; + ifa->csn_use = now; + } + + /* We must have sufficient delay between sending a packet and increasing + CSN to prevent reordering of packets (in a network) with different CSNs */ + if ((now - ifa->csn_use) > 1) + ifa->csn++; + + ifa->csn_use = now; pkt->u.md5.keyid = passwd->id; pkt->u.md5.len = OSPF_AUTH_CRYPT_SIZE; pkt->u.md5.zero = 0; - pkt->u.md5.csn = htonl(ifa->csn++); + pkt->u.md5.csn = htonl(ifa->csn); tail = ((void *)pkt) + ntohs(pkt->length); MD5Init(&ctxt); MD5Update(&ctxt, (char *) pkt, ntohs(pkt->length)); @@ -184,12 +196,14 @@ ospf_pkt_checkauth(struct ospf_neighbor *n, struct ospf_iface *ifa, struct ospf_ if (n) { - if(ntohs(pkt->u.md5.csn) < n->csn) - { - OSPF_TRACE(D_PACKETS, "OSPF_auth: lower sequence number"); - return 0; - } - n->csn = ntohs(pkt->u.md5.csn); + u32 rcv_csn = ntohl(pkt->u.md5.csn); + if(rcv_csn < n->csn) + { + OSPF_TRACE(D_PACKETS, "OSPF_auth: lower sequence number (rcv %d, old %d)", rcv_csn, n->csn); + return 0; + } + + n->csn = rcv_csn; } MD5Init(&ctxt); -- cgit v1.2.3