[TLS] Let's remove gmt_unix_time from TLS

Nick Mathewson <nickm@torproject.org> Wed, 11 September 2013 15:44 UTC

Return-Path: <nick.a.mathewson@gmail.com>
X-Original-To: tls@ietfa.amsl.com
Delivered-To: tls@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 5860C21E8150; Wed, 11 Sep 2013 08:44:21 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.233
X-Spam-Level:
X-Spam-Status: No, score=-1.233 tagged_above=-999 required=5 tests=[AWL=-0.744, BAYES_05=-1.11, FM_FORGED_GMAIL=0.622, NO_RELAYS=-0.001]
Received: from mail.ietf.org ([12.22.58.30]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id KWI2VnEZzLl9; Wed, 11 Sep 2013 08:44:20 -0700 (PDT)
Received: from mail-qe0-x230.google.com (mail-qe0-x230.google.com [IPv6:2607:f8b0:400d:c02::230]) by ietfa.amsl.com (Postfix) with ESMTP id 8E3A121E80D6; Wed, 11 Sep 2013 08:43:58 -0700 (PDT)
Received: by mail-qe0-f48.google.com with SMTP id nd7so4559721qeb.21 for <multiple recipients>; Wed, 11 Sep 2013 08:43:53 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:date:message-id:subject:from:to:content-type; bh=nadwBqowODNn1F1WLREZev2cD/GPtWb6g87ZQhWtrY0=; b=q+8McEr3GrF0HK2vPDdHpK7gyzhNs68M5cRdz2p4mSSGJkbYQEKxe2DDiCPa1RS6nx LfLrXUrQZcWHcGx9Na38d73G7oxZ5TkdcM1dKsJJvuCD02SRMA2N2UBcwX8/a0U79Xmx xmAIS8o9ZOBudUZy7t3nVEtXjQvc3j0dGGHpRYpIW5gMwA2EZaDApZzNReyZvJlsqMaR jmHTGl4+12iQ+4OHIiziFJtwrXNCsvIZbmicDf2liyvvuLpx9zQKLSbRlCSEWA9DnTMG iI28BwfbYCQWCHiGqgJA6WHmpgNYkgW2x/4c0yrhdlTkDPn6mv0SqsaOrH5FzjNN7Pkq IJWg==
MIME-Version: 1.0
X-Received: by 10.49.120.72 with SMTP id la8mr4490597qeb.62.1378914233423; Wed, 11 Sep 2013 08:43:53 -0700 (PDT)
Sender: nick.a.mathewson@gmail.com
Received: by 10.140.22.81 with HTTP; Wed, 11 Sep 2013 08:43:53 -0700 (PDT)
Date: Wed, 11 Sep 2013 11:43:53 -0400
X-Google-Sender-Auth: bJai9poECwNKPn3X9boDY4XJEQQ
Message-ID: <CAKDKvuw240Ug4xB3zi2w0y7pUvCwSe0nNFZ2XP2vL-tbtKT0tg@mail.gmail.com>
From: Nick Mathewson <nickm@torproject.org>
To: "tls@ietf.org" <tls@ietf.org>, perpass@ietf.org
Content-Type: text/plain; charset="ISO-8859-1"
Subject: [TLS] Let's remove gmt_unix_time from TLS
X-BeenThere: tls@ietf.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <tls.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tls>, <mailto:tls-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/tls>
List-Post: <mailto:tls@ietf.org>
List-Help: <mailto:tls-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tls>, <mailto:tls-request@ietf.org?subject=subscribe>
X-List-Received-Date: Wed, 11 Sep 2013 15:44:23 -0000

Hi, all.

Here's something I wrote about removing a fingerprinting opportunity
from the current TLS protocol.  I was going to just send it to the tls
list, but Ben Laurie suggested that I send it to the perpass list as
well.

I have little standards-body experience; if this ought to turn into an
RFC or something, I'd be happy to write a draft if need be.


(Tor currently plans to implement this by patching OpenSSL; any
feedback or advice would be appreciated.  The first three approaches
below are implemented in OpenSSL branches named "no_client_timestamp",
"no_client_timestamp_v2" , and "no_client_timestamp_v3" in the git
repository at https://github.com/nmathewson/openssl .  We have long
shipped our privacy-enhanced browser with a feature like this enabled
through an NSS patch.)


====
SYNOPSIS:

In TLS as currently specified, clients and servers each send their
current view of "the time" in the clear as part of their handshake.
This provides a fingerprint that can track users in spite of other
attempts to make them untrackable.  I propose several ways to stop
doing sending this cleartext timestamp; some trivial and some more
complex.


ACKNOWLEDGEMENTS:

Thanks to Adam Langley, Ben Laurie, and everybody else who gave me
feedback here.


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.

Of course, I realize that the gmt_unix_time fingerprint is not the
only way to track a typical client as it moves from network to
network, and not the only way to distinguish different clients
behind a NAT.



BACKGROUND: WHY gmt_unix_time IN THE FIRST PLACE?

According to third-hand reports (and correct me if I'm wrong!)
gmt_unix_time 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, for two reasons:

   * On modern desktop environments, it's not really so strange to
     start two or more TLS connections within the same second.  When
     this occurs, the gmt_unix_time fails in its intended purpose of
     preventing repeated Random values.

   * Nonwithstanding the gmt_unix_time workaround, TLS in general
     does not withstand broken PRNGs.  For one example, if an
     implementation's PRNG is prone to repeating ClientRandom
     values, it is probably prone to repeating those some values as
     ephemeral Diffie-Hellman private values.

Nevertheless, if the goal of providing unique-looking output



WHY ELSE IS gmt_unix_time USED?

The consensus among implementors I've asked 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 gmt_unix_time 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.

Rationale:
   * Some implementations (like TorBrowser) are already doing this
     in practice.

   * It's sensible and simple.  Implementors are quite unlikely to
     mess it up.



PROPOSAL 2:

Suppose that we do not accept the argument about the pointlessness
of gmt_unit_time that I make above, and we want to preserve the
security it allegedly provides.

In that case, we can 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.

I do not think this 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).


PROPOSAL 3

As a hybrid alternative, one could set part of the ClientRandom
field (perhaps 12 bytes or so) based on the HMAC of the time, and
the rest of the ClientRandom field based on the PRNG:

   N = 12

   now = hires_time();
   key = get_random_bytes(32);
   mac = hmac_sha256(key, now)[0:N];  // First N bytes.
   rand = get_random_bytes(32 - N)
   Random = mac ++ rand               // concatenate.

But this seems to be getting pointlessly baroque.



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.


We 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.