Hello,
The people that have been following Pluggable Transport development may know that I have been working on something tentatively called "obfs4" recently. It's rapidly approaching the point where I would like to open it up for review and feedback, hence the e-mail.
A quick and dirty description would be:
obfs4 is ScrambleSuit with djb crypto. Instead of obfs3 style UniformDH and CTR-AES256/HMAC-SHA256, obfs4 uses a combination of Curve25519, Elligator2, HMAC-SHA256, XSalsa20/Poly1305 and SipHash-2-4.
The feature set offered by obfs4 is comparable to ScrambleSuit with the following differences (implementation specific changes are noted as such):
* The key exchange is based on the ntor handshake, and thus authenticates the server to the client. Both obfs3 and ScrambleSuit depend on the encapsulated protocol to handle this on it's own.
* obfs4 always does a full handshake. ScrambleSuit style session ticket handshakes are not supported. Even with Elligator2 mapping taken into account, the obfs4 handshake is significantly faster, so there is less of a need for this.
* (Impl) obfs4proxy currently does not offer Inter-Arrival Time obfuscation, but this could easily be added if it is something that a lot of people want. It is worth noting that while obfsproxy and obfsclient both support IAT obfuscation, support for it is currently disabled by default as a performance tradeoff.
* (Impl) obfs4proxy is currently written in golang. Neither a clear plus or minus, it does allow people to run bridges on reserved ports significantly easier, is probably faster (native code, can use multiple cores for most things), but is more annoying to build and results in rather large binaries (the go runtime is statically linked).
* (Impl) obfs4 supports a lot of the protocol improvements made to ScrambleSuit that are pending merge (See #11271, #11203). This difference is temporary.
The code and a draft spec is at: https://github.com/Yawning/obfs4
Open questions:
* Is the base design and my implementation sane?
* Should obfs4proxy also have (disabled) IAT obfuscation? Adding it later will not require wire protocol changes.
* The handshake length mimics ScrambleSuit in terms of maximum padding (< 1500 bytes). Should this be increased to be similar to obfs3 (~8k of maximum padding)? The server side cost for this shouldn't be that high.
* Is this different enough from ScrambleSuit to be worth deploying? I would be ok with this ending up as "just a research project" and shelving it if the consensus is otherwise.
* Should I have named it ScrambleSuit 2? It's a direct descendant of ScrambleSuit and is an obfs derivative only in name at this point.
Future plans:
* Implement suggestions/improve the code/fix bugs/write more unit tests.
* Improve goptlib.
* If this is deployed in meaningful amounts, support it in obfsclient.
For the extremely brave, I am running a test bridge with the most recent snapshot of the code:
UseBridges 1 ClientTransportPlugin obfs4 exec /path/to/obfs4proxy # Bridge line of doom, all one line. Bridge obfs4 178.209.52.110:52810 67E72FF33D7D41BF11C569646A0A7B4B188340DF node-id=Z+cv8z19Qb8RxWlkagp7SxiDQN8= public-key=vm+w9k57aMIX/o+A9ef5C7o9xKEkhr7kRBj3N4etDn8=
As with any PT that requires per-bridge arguments, this also requires tor-0.2.5.x. The node-id in this case happens to be my bridge's fingerprint, the public key is the long term key used to validate my bridge's identity and generate M_[C,S]/MAC in the handshake (The bridge line is a bit of a UI/UX disaster unless people are copy/pasting it). Getting either of them wrong will result in handshake failures and tor not bootstrapping.
A few warnings:
* The spec assumes familiarity with ntor, ScrambleSuit and NaCl's crypto_secretbox.
* The wire protocol is not final and I *will* push builds to the bridge as I break backward compatibility without notifying people (It's been 0 days since a wire protocol change.). The test bridge will randomly be broken/rebooted/etc as I also use it for other things.
* Development was done with go1.2.x, older versions of the runtime are not supported.
* It would be a terrible idea to use obfs4proxy as anything other than a client at this point.
Questions, comments, feedback all appreciated.
obfs4 is ScrambleSuit with djb crypto. Instead of obfs3 style UniformDH and CTR-AES256/HMAC-SHA256, obfs4 uses a combination of Curve25519, Elligator2, HMAC-SHA256, XSalsa20/Poly1305 and SipHash-2-4.
Elligator... cool!
- Development was done with go1.2.x, older versions of the runtime are not supported.
Did you get your builds to work with the deterministic build system?
On Wed, 21 May 2014 12:22:46 +0000 David Stainton dstainton415@gmail.com wrote:
obfs4 is ScrambleSuit with djb crypto. Instead of obfs3 style UniformDH and CTR-AES256/HMAC-SHA256, obfs4 uses a combination of Curve25519, Elligator2, HMAC-SHA256, XSalsa20/Poly1305 and SipHash-2-4.
Elligator... cool!
- Development was done with go1.2.x, older versions of the runtime
are not supported.
Did you get your builds to work with the deterministic build system?
Not yet. While it's important I'm sort of working under the assumption that it's mostly a solved problem as the scary build process can handle flashproxy and meek. I've been a bit more focused on getting the protocol design and implementation to a point where I feel generally good about it.
On Wed, May 21, 2014 at 06:36:52AM +0000, Yawning Angel wrote:
- obfs4 always does a full handshake. ScrambleSuit style session ticket handshakes are not supported. Even with Elligator2 mapping taken into account, the obfs4 handshake is significantly faster, so there is less of a need for this.
That's probably a good idea as it leads to less code and complexity. We added session tickets when we were experimenting with a proof-of-work scheme instead of the shared secret which is now wrapped around UniformDH. The PoW scheme turned out to be unpractical but we kept session tickets as they still provided a small computational benefit.
- Should obfs4proxy also have (disabled) IAT obfuscation? Adding it later will not require wire protocol changes.
I don't think that inter-arrival times are a significant practical threat at this point. In addition, it has a major impact on throughput which is the reason why obfsproxy's ScrambleSuit ships with the option being disabled. As you write, it shouldn't be a problem to add IAT obfuscation later on if it turns out to be important for some reason.
- The handshake length mimics ScrambleSuit in terms of maximum padding (< 1500 bytes). Should this be increased to be similar to obfs3 (~8k of maximum padding)? The server side cost for this shouldn't be that high.
I'm not sure if sound decisions can be made without comprehensive data showing how real-world protocols behave. ScrambleSuit's (and perhaps also obfs3's) padding length was determined by gut feeling, so ~8k might be fine as well.
- Is this different enough from ScrambleSuit to be worth deploying? I would be ok with this ending up as "just a research project" and shelving it if the consensus is otherwise.
While you're at it, there are some other things which might be worth improving:
- ScrambleSuit's framing mechanism is vulnerable to this attack: http://www.isg.rhul.ac.uk/~kp/SandPfinal.pdf In a nutshell, the receiver needs to decrypt the ScrambleSuit header before it is able to verify the HMAC which makes it possible for an attacker to tamper with the length fields. While there are probably simpler attacks, it would be nice to have a fix for this problem.
- We didn't push the idea of polymorphism very far. There are more flow characteristics such as "packet directions", "total bytes sent", or "total bytes received" which could be disguised in a systematic fashion. While reasonable protection against traffic analysis is tricky, we could at least decrease a classifier's accuracy a bit more. Some ideas could be taken from this paper: http://arxiv.org/pdf/1401.6022v1.pdf
Cheers, Philipp
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
On 23/05/14 13:16, Philipp Winter wrote:
- ScrambleSuit's framing mechanism is vulnerable to this attack:
http://www.isg.rhul.ac.uk/~kp/SandPfinal.pdf In a nutshell, the receiver needs to decrypt the ScrambleSuit header before it is able to verify the HMAC which makes it possible for an attacker to tamper with the length fields. While there are probably simpler attacks, it would be nice to have a fix for this problem.
In the next version of the Briar transport protocol we're addressing that problem by dividing each frame into two parts. The first part is a fixed-length header, the second is a variable-length body. Each part is separately encrypted and MACed. The header contains the length of the body.
This requires two MACs per frame, but I prefer that to the alternatives: using fixed-length frames, or using the decrypted length field before checking whether it's been tampered with.
Cheers, Michael
On Fri, 23 May 2014 14:16:49 +0200 Philipp Winter phw@nymity.ch wrote:
[snippity]
- Should obfs4proxy also have (disabled) IAT obfuscation? Adding
it later will not require wire protocol changes.
I don't think that inter-arrival times are a significant practical threat at this point. In addition, it has a major impact on throughput which is the reason why obfsproxy's ScrambleSuit ships with the option being disabled. As you write, it shouldn't be a problem to add IAT obfuscation later on if it turns out to be important for some reason.
I went and added the code last night, so it's there if needed (as a command line option).
- The handshake length mimics ScrambleSuit in terms of maximum padding (< 1500 bytes). Should this be increased to be similar
to obfs3 (~8k of maximum padding)? The server side cost for this shouldn't be that high.
I'm not sure if sound decisions can be made without comprehensive data showing how real-world protocols behave. ScrambleSuit's (and perhaps also obfs3's) padding length was determined by gut feeling, so ~8k might be fine as well.
On the gut feeling of "bigger handshakes = more random *waves hands*", I went and jacked it up last night. More real world data would be nice.
- Is this different enough from ScrambleSuit to be worth
deploying? I would be ok with this ending up as "just a research project" and shelving it if the consensus is otherwise.
While you're at it, there are some other things which might be worth improving:
- ScrambleSuit's framing mechanism is vulnerable to this attack: http://www.isg.rhul.ac.uk/~kp/SandPfinal.pdf In a nutshell, the receiver needs to decrypt the ScrambleSuit
header before it is able to verify the HMAC which makes it possible for an attacker to tamper with the length fields. While there are probably simpler attacks, it would be nice to have a fix for this problem.
I believe obfs4 does not have the plaintext recovery issue as the length field is separate from the AEAD construct (Though at present an adversary tampering with the length field is only caught by MAC errors). However I will go and implement randomizing the length on a out of bounds length value (as suggested in section 6 of the paper) to reduce the timing differential.
From reading the paper, I do not believe that ScrambleSuit's vulnerability leads to plaintext recovery either as it uses CTR-AES and recovery is based off CBC-AES, though as the authors note, there may be other side channel hazards.
- We didn't push the idea of polymorphism very far. There are more
flow characteristics such as "packet directions", "total bytes sent", or "total bytes received" which could be disguised in a systematic fashion. While reasonable protection against traffic analysis is tricky, we could at least decrease a classifier's accuracy a bit more. Some ideas could be taken from this paper: http://arxiv.org/pdf/1401.6022v1.pdf
This is the sort of thing that mjuarez is looking into as part of GSOC. As long as a padding frame type is defined, incorporating the results of his research at a later date should be possible without changes to the wire protocol.
Thanks for the feedback!