wiki:SWEET32

OpenVPN and SWEET32

Security researchers at INRIA published an attack on 64-bit block ciphers, such as 3DES and Blowfish [0]. They show that they are able to recover plaintext when the same data is sent often enough, and show how they can use cross-site scripting vulnerabilities to send data of interest often enough. This works over HTTPS, but also works for HTTP-over-OpenVPN. See https://sweet32.info/ [0] for a much better and more elaborate explanation.

Am I affected?

This depends on the cipher you've chosen (OpenVPN's --cipher option). OpenVPN's default cipher, BF-CBC, is affected by this attack.

Whether you're affected can be checked by installing OpenVPN 2.3.12 [1] or newer, and running openvpn --show-ciphers. This will show you which ciphers should no longer be used. For convenience, we provide a summary for commonly used cipher here:

The following ciphers are affected, and should no longer be used:

  • BF-*
  • DES* (including 3DES variants)
  • RC2-*

The following ciphers are *not* affected:

  • AES-*
  • CAMELLIA-*
  • SEED-*

Mitigation

1. Change to a larger block cipher

The best mitigation is to transition away from small-block ciphers. This requires editting the cipher setting in all server and client configs (or upgrading to our experimental branch, see below).

Of the currently supported ciphers, OpenVPN currently recommends using AES-256-CBC or AES-128-CBC. OpenVPN 2.4 and newer will also support GCM. For 2.4+, we recommend using AES-256-GCM or AES-128-GCM.

2. Renegotiate more often

If changing the cipher is not possible, for example because you don't control the server, or can not update all client configs on a short notice, you can renegotiate new keys more often. For example, add --reneg-bytes 64000000 to your config to renegatiate after every 64 megabytes.

Note that if you're using two-factor authentication, or username-password authentication, this might require users to re-enter their 2FA token or usernamne and password. To avoid this, do not use --auth-nocache, and use the auth-token option (see below) in the client-connect and auth-user-pass-verify scripts on the server side to ask for 2FA once per session only.

The (undocumented) auth-token option can be pushed by a client-connect script (running on the server) to instruct the connecting client to return this token as the password during the next authentication. The auth-user-pass-verify script (running on the server) should accept this token during the next authentication sessions, until the token expires.

The following client-connect and auth-user-pass-verify scripts illustrate how these options can be used. Note that these scripts are examples for auth-token usage only, and should be adapted to your own needs before using them. These scripts should not be used as-is'''

client-connect:

#!/usr/bin/env python

import base64
import hmac
import os
import sys
import time

username = os.environ['username']

# Create an authentication 'cookie' that binds to the current user and time
ts = time.time()
to_auth = str(ts) + ":" + username

h = hmac.new('mysecret')
h.update(to_auth)
digest = base64.b64encode(h.digest())

auth_token = "push \"auth-token " + str(ts) + ":" + digest + "\""

print "Sending auth-token:", auth_token

open(sys.argv[1], 'w').write(auth_token)

auth-user-pass-verify:

#!/usr/bin/env python

import base64
import hmac
import os
import time

username = os.environ['username']
password = os.environ['password']

# Try password auth first
if (password == "mysecretpassword"):
    print "password OK"
    exit(0)

# Otherwise verify auth-token
token = password.split(":")

to_auth = token[0] + ":" + os.environ['username']

h = hmac.new('mysecret')
h.update(to_auth)
digest = h.digest()

# Exit with error if authentication fails
if digest != base64.b64decode(token[1]):
    print "Auth-token incorrect"
    exit(1)

# Exit with error if auth-token expired
if time.time() - float(token[0]) > 60:
    print "Auth-token expired"
    exit(1)

# All went well!
exit(0)

3. Enable cipher negotiation (experimental!)

OpenVPN 2.4 and newer will support cipher negotiation. If both peers (client and server) support cipher negotiation, OpenVPN will default to using AES-GCM. The bad news is that OpenVPN 2.4 is not available yet, we're still fixing bugs and working our way to the first alpha release. Nevertheless, the code is pretty stable. Most bugs are hiding in seldomly-used corner cases. If you're brave enough, check out the master branch of our git repo [2], and build your own OpenVPN-with-cipher-negotiation support.

References

[0] https://sweet32.info/

[1] https://openvpn.net/index.php/open-source/downloads.html

[2] https://github.com/OpenVPN/openvpn.git

Last modified 4 days ago Last modified on 02/21/17 19:16:43