Filename: 222-remove-client-timestamps.txt Title: Stop sending client timestamps Authors: Nick Mathewson Created: 22 August 2013 Target: 0.2.5.x Status: Open
0. Summary
There are a few places in Tor where clients and servers send timestamps. I list them and discuss how to eliminate them.
1. Introduction
Despite this late date, many hosts aren't running NTP and don't have very well synchronized clocks. Even more hosts aren't running a secure NTP; it's probably easy to desynchronize target hosts.
Given all of this, it's probably a fingerprinting opportunity whenever clients send their view of the current time. Let's try to avoid that.
I'm also going to list the places where servers send their view of the current time, and propose that we eliminate some of those.
Scope: This proposal is about eliminating passive timestamp exposure, not about tricky active detection mechanisms where you do something like offering a client a large number of about-to-expire/just-expired certificates to see which ones they accept.
2. The Tor link protocol
2.1. NETINFO (client and server)
NETINFO cells specify that both parties include a 4-byte timestamp.
Instead, let's say that clients should set this timestamp to 0. Nothing currently looks at a client's setting for this field, so this change should be safe.
2.2. AUTHENTICATE (server)
The AUTHENTICATE cell is not ordinarily sent by clients. It contains an 8-byte timestamp and a 16-byte random value. Instead, let's replace both with a 24-byte (truncated) HMAC of the current time, using a random key.
This will achieve the goal of including a timestamp in the cell (preventing replays even in the presence of bad entropy), while at the same time not including the time here.
2.3. TLS
2.3.1. ClientRandom in the TLS handshake
See TLS proposal in appendix A.
This presents a TLS fingerprinting/censorship opportunity. I propose that we investigate whether "random " or "zero" is more common on the wire, choose that, and lobby for changes to TLS implementations.
2.3.2. Certificate validity intervals
Servers use the current time in setting certificate validity for their initial certificates. They randomize this value somewhat. I propose that we don't change this, since it's a server-only issue, and already somewhat mitigated.
3. Directory protocol
3.1. Published
This field in descriptors is generated by servers only; I propose no change.
3.2. The Date header
This HTTP header is sent by directory servers only; I propose no change.
4. The hidden service protocol
4.1. Descriptor publication time
Hidden service descriptors include a publication time. I propose that we round this time down to the nearest N minutes, perhaps for N=30.
4.2. INTRODUCE2 cell timestamp
INTRODUCE2 cells once limited the duration of their replay caches by including a timestamp in the INTRODUCE2 cells. Since 0.2.3.9-alpha, this timestamp is ignored, and key lifetime is used instead.
When we determine that no hidden services are running on 0.2.2.x (and really, no hidden services should be running on 0.2.2.x!), we can simply send 0 instead. (See ticket #7803).
This might be a good place to use a consensus parameter, so that a large number of clients switch at the same time.
I claim this would be suitable for backport to 0.2.4.
5. The application layer
The application layer is mostly out of scope for this proposal, except:
TorBrowser already (I hear) drops the timestamp from the ClientRandom field in TLS. We should encourage other TLS applications to do so. (See Appendix A.)
================================================================= APPENDIX A: "Let's replace gmt_unix_time in TLS"
PROBLEM:
The gmt_unix_time field in the Random field in the TLS handshake provides a way for an observer to fingerprint clients.
Despite the late date, much of the world is still not synchronized to the second via an ntp-like service. This means that different clients have different views of the current time, which provides a fingerprint that helps to track and distinguish them. This fingerprint is useful for tracking clients as they move around. It can also distinguish clients using a single VPN, NAT, or privacy network. (Tor's modified firefox avoids this by not sending the time.)
Worse, some implementations don't send the current time, but the process time, or the computer's uptime, both of which are far more distinguishing than the current time() value.
The information fingerprint here is strong enough to uniquely identify some TLS users (the ones whose clocks are hours off). Even for the ones whose clocks are mostly right (within a second or two), the field leaks a bit of information, and it only takes so many bits to make a user unique.
WHY gmt_unix_time IN THE FIRST PLACE?
According to third-hand reports -- (and correct me if I'm wrong!) it was introduced in SSL 3.0 to prevent complete failure in cases where the PRNG was completely broken, by making a part of the Random field that would definitely vary between TLS handshakes.
I doubt that this goal is really achieved: on modern desktop environments, it's not really so strange to start two TLS connections within the same second.
WHY ELSE IS gmt_unix_time USED?
The consensus among implementors seems to be that it's unwise to depend on any particular value or interpretation for the field. The TLS 1.2 standard, RFC 5246, says that "Clocks are not required to be set correctly by the basic TLS protocol; higher-level or application protocols may define additional requirements."
Some implementations set the entire field randomly; this appears not to have broken TLS on the internet.
At least one tool (tlsdate) uses the server-side value of the field as an authenticated view of the current time.
PROPOSAL 1:
Declare that implementations MAY replace gmt_unix_time either with four more random bytes, or four bytes of zeroes.
Make your implementation just do that.
(Rationale: some implementations (like TorBrowser) are already doing this in practice. It's sensible and simple. You're unlikely to mess it up, or cause trouble.)
PROPOSAL 2:
Okay, if you really want to preserve the security allegedly provided by gmt_unix_time, allow the following approach instead:
Set the Random field, not to 32 bytes from your PRNG, but to the HMAC-SHA256 of any high resolution timer that you have, using 32 bytes from your PRNG as a key. In other words, replace this:
Random.gmt_unix_time = time(); Random.random_bytes = get_random_bytes(28)
with this:
now = hires_time(); // clock_gettime(), or concatenate time() // with a CPU timer, or process // uptime, or whatever. key = get_random_bytes(32); Random = hmac_sha256(key, now);
This approach is better than the status quo on the following counts:
* It doesn't leak your view of the current time, assuming that your PRNG isn't busted.
* It actually fixes the problem that gmt_unix_time purported to fix, by using a high-resolution time that's much less likely to be used twice. Even if the PRNG is broken, the value is still nonrepeating.
It is not worse than the status quo:
* It is unpredictable from an attacker's POV, assuming that the PRNG works. (Because an HMAC, even of known data, with an unknown random key is supposed to look random).
CONSIDERATIONS:
I'd personally suggest proposal 1 (just set the field at random) for most users. Yes, it makes things a little worse if your PRNG can generate repeat values... but nearly everything in cryptography fails if your PRNG is broken.
You might want to apply this fix on clients only. With a few exceptions (like hidden services) the server's view of the current time is not sensitive.
Implementors might want to make this feature optional and on-by-default, just in case some higher-level application protocol really does depend on it. ==================================================================
Nick Mathewson nickm@torproject.org writes:
Filename: 222-remove-client-timestamps.txt Title: Stop sending client timestamps Authors: Nick Mathewson Created: 22 August 2013 Target: 0.2.5.x Status: Open
Summary
There are a few places in Tor where clients and servers send timestamps. I list them and discuss how to eliminate them.
Introduction
Despite this late date, many hosts aren't running NTP and
<snipage>
field, so this change should be safe.
2.2. AUTHENTICATE (server)
The AUTHENTICATE cell is not ordinarily sent by clients. It contains an 8-byte timestamp and a 16-byte random value. Instead, let's replace both with a 24-byte (truncated) HMAC of the current time, using a random key.
This will achieve the goal of including a timestamp in the cell (preventing replays even in the presence of bad entropy), while at the same time not including the time here.
Hey Nick,
how does the client verify the contents of the AUTHENTICATE cell (including the timestamp), if the timestamp is encrypted with a random key?
On Thu, Aug 22, 2013 at 12:33 PM, George Kadianakis desnacked@riseup.net wrote: [...]
2.2. AUTHENTICATE (server)
The AUTHENTICATE cell is not ordinarily sent by clients. It contains an 8-byte timestamp and a 16-byte random value. Instead, let's replace both with a 24-byte (truncated) HMAC of the current time, using a random key.
This will achieve the goal of including a timestamp in the cell (preventing replays even in the presence of bad entropy), while at the same time not including the time here.
Hey Nick,
how does the client verify the contents of the AUTHENTICATE cell (including the timestamp), if the timestamp is encrypted with a random key?
Two points and a real answer. The two points first:
* The authenticate cell is sent from a server initiator to a server responder. Clients never get them, and never verify them.
* HMAC isn't encryption. :)
The real answer:
* The contents of the timestamp are never actually checked; the protocol only includes a timestamp there in a voodoo-like imitation of the ClientRandom field. The requirement is that there be _something_ in this position, and that the entire AUTHENTICATE cell be correctly signed.
On Thu, Aug 22, 2013 at 6:46 PM, Nick Mathewson nickm@torproject.org wrote:
Despite this late date, many hosts aren't running NTP and don't have very well synchronized clocks. Even more hosts aren't running a secure NTP; it's probably easy to desynchronize target hosts.
Not strongly related to the proposal, but authenticated (autokey) NTP is not really secure. http://tools.ietf.org/html/draft-ietf-ntp-network-time-security http://www.innovationslab.net/~brian/NTP/autokey-analysis.pdf