Hi, it is absolutely true that it is necessary to do HMAC hash per every existing session, as far as I know there's no other way to tell reliably if the packet really belongs to an existing session... I haven't measured the HMAC performance myself, but I'd guess it would take a bit more than a few hundred packets per second to exhaust a modern CPU.
The for-loop part was originally (shamelessly) adapted from tls_pre_decrypt() @ ssl.c, it could have been more clear I have to admit... I think the memcmp() is already constant-time as the HMAC hash has fixed size per hash algorithm (as far as I can remember, please correct me if I'm wrong). This was also shamelessly adopted from openvpn_decrypt() @ crypto.c. I don't think there are any timing related attack opportunities as accepting the incoming packet does not trigger any immediate replies being sent back to anyone; the accepted packet is just processed as if it was received from the original address. As the data channel packet is being forwarded away from the original sender to the trusted side of the tunnel it should be quite hard for an attacker to make any timing calculations.. I wasn't aware the --float option could be specified per client... Best regards, and nice weekend! Mikko ________________________________________ From: Joachim Schipper [joachim.schip...@fox-it.com] Sent: Friday, March 08, 2013 2:58 PM To: openvpn-devel@lists.sourceforge.net Cc: Mikko Vainikainen; Steffan Karger Subject: RE: [PATCH] Fix for bug #49 for openvpn 2.2.2 > Hi, > > our setup needs openvpn UDP/TLS tunnels with dynamic client IP addresses, so > I implemented a fix for the bug #49 that has been open for over two years. > > The patch is for version 2.2.2 as I had trouble compiling the 2.3.x tarball > from openvpn.net. As the solution is rather simple (just two small utility > functions in mudp.c) I'd guess it could be comfortambly migrated to 2.3.x. > > Basically what the fix does is the following: incoming data channel UDP > packets from an unknown IP are matched against existing UDP/TLS sessions, and > if the packet passes the HMAC authentication against an existing TLS context > we know the client IP has changed and the session state will be instantly > updated accordingly. > > I have tested this fix to some extent, and the IP handover works impressively > smoothly in my test setup where I randomly switch between two routes from > client to server. > > Dynamic client IP's are enabled/disabled with --float in the server side. > > Please feel free to contact me for any questions etc. This is not a full review of the patch, just a few quick remarks. This patch seems to do (number of tunnels) HMAC's for any packet received from an unknown IP. If this is correct, couldn't a server with a couple thousand tunnels be brought just by sending it a few hundred packets a second? authenticate_tls_packet() contains a for() loop, but I see no code path that actually loops - everything seems to return immediately? memcmp() should be replaced by a constant-time function to prevent timing attacks (probably only realistic on a server with a single tunnel); even then, this patch allows determining the (approximate) number of tunnels in use by looking at processing time. I haven't looked at how this interacts with other features; it's at least noteworthy that the floating behavior can't be specified on a per-connection basis. Joachim