obfs2 Transport Evaluation
The obfs2 protocol was developed and deployed by the Tor Project as part of the initial efforts to counter Iran's DPI based censorship of the Tor link protocol. It is considered trivially breakable by most adversaries and is deprecated and has been evaluated as a historical reference only.
Multiple implementations of the protocol exist, however this evaluation will primarily cover the Python implementation that is part of the obfsproxy suite, with references to the other implementations as needed.
1. Review Coverage and Reviewability Evaluation
1.1 Is the software published, and is it entirely free / open source software?
The obfs2 protocol is implemented in multiple software packages, all under FOSS style licenses. The original implementation was done as a C application named obfsproxy. The protocol was subsequently ported to the Python obfsproxy package, the C++11 client only implementation in obfsclient, and the Go implementation in the obfs4proxy suite.
As it is a relatively simple protocol, there are no special considerations regarding distribution.
1.2 How well documented is the design?
The design is well documented and includes a comprehensive specification and threat model. The documentation has been used by developers to write inter-operable implementations.
1.3 How much existing review has been done? Is the project active?
As it is one of the older Pluggable Transports, it has received considerable amount of attention and review. While the software packages that provide obfs2 functionality are actively maintained and developed, the obfs2 protocol itself is unexpected to change and is inactive. Further improvements will be made in the form of newer protocol designs.
1.4 What is the design's deployment history?
The obfs2 protocol was initially deployed in 2012 as the first Pluggable Transport. Newer protocols have since supreceded obfs2 as censors have improved, however it still sees limited use today from legacy users.
2 Design Evaluation
2.1 How difficult or expensive will it be to block the design?
The design is trivial to block, assuming the censor has DPI capability and is considered broken versus most adversaries. As the threat model notes:
obfs2 (in its default configuration) does not try to protect against
Deep Packet Inspection machines that expect the obfs2 protocol and
have the resources to run it. Such machines can trivially retrieve
the decryption key off the traffic stream and use it to decrypt obfs2
and detect the Tor protocol.
Specifically the first 20 bytes of an obfs2 protocol stream in both directions contain keying material and a known plaintext which serve as a distinguisher for the protocol, at the cost of 1 SHA256 operation and 1 CTR-AES-128 decryption. Additionally obfs2 is vulnerable to censors that specifically look for high-entropy traffic, or those that are willing to use a protocol whitelist, however both of those attacks are considerably more complicated than simply attempting the key derivation and trial decryption.
There is no attempt to obfuscate traffic volume or timing related information and it is believed that such statistical attacks will be able to identify protocols obfuscated within obfs2 flows with high accuracy.
Note: There is a unused (and unimplemented in the current production Go implementation) extension to the key derivation that adds a shared secret component. The deployment of the extension would negate the fact that keying material is sent over the wire, requiring the adversary to mount statistical/entropy based attacks. As the obfs4 protocol is already in production, the necessary code changes to support the shared secret mode are unlikely to occur.
2.2 What impact on anonymity does the design have, if any?
As the obfs2 protocol focuses solely on circumvention, there is no anonymity impact, positive nor negative.
2.3 What is the design's overhead in terms of computational costs and bandwidth?
The obfs2 protocol has a relatively low overhead, with the only added bandwidth costs being that of the handshake (a maximum of 8216 bytes). The CPU overhead consists almost entirely of CTR-AES128 encryption/decryption on outgoing/incoming traffic which should be affordable by all clients and all but the most under-powered Bridges.
2.4 How resilient is the design to active probing?
The basic obfs2 protocol is completely vulnerable to active probing, as the client has zero requirements to prove that it knows that the server accepts obfs2 connections. This is not needed for the basic obfs2 protocol as trivial DPI is sufficient to identify the protocol.
The shared secret extension would make the protocol immune to active probing entirely however it is not deployed, and there are no plans for doing so.
3 Implementation Evaluation
3.1 Does the design use the Tor Project's Pluggable Transport Application Programming Interface (API) already?
Yes, all of the currently actively supported obfs2 implementations use the PT API.
3.2 Is the implementation cross-platform? How about mobile support?
There are 4 different implementations in C, Python, C++11 (client only), and Go, and thus it is one of the more widely supported protocols. For the longest time obfs2 was the only Pluggable Transport to run on mobile environments via the C implementation, though that has now been superseded first by obfsclient (C++11), and presently obfs4proxy (Go). Between the four codebases, obfs2 runs on a large assortment of hardware and operating systems.
3.3 What is the implementation's build process like, how easy is it to deploy, and what is deployment scaling like?
Both obfsproxy and obfs4proxy are capable of being built deterministically and are currently integrated into the Tor Browser's build process. As both of those suites are part of the standard array of software recommended to administrators for running Bridges, pre-built binary packages are widely available and the deployment process is well documented.
As obfs2 is considered broken and deprecated, no new obfs2 installations should be deployed.
3.4 How is the implementation's code from a security and maintainability perspective?
This varies by implementation. The Python and Go versions have the benefit of being written in memory-safe languages, while the C and C++11 versions do not. The test coverage varies by implementation, with the Python obfsproxy code having the most comprehensive tests.
3.5 How well-instrumented is the implementation in terms of collecting usage / performance / etc metrics?
Both the python obfsproxy and Go obfs4proxy server implementations of obfs2 fully support the Extended ORPort mechanism and thus provide metrics information.