NTP security (NTS)

I've been hearing about Network Time Security (NTS) being in development for awhile now.  With Cloudflare's release of a public NTS service, I wanted to take a closer look at the protocol and test it out.

The current NTS draft (as of July 2019) goes into the protocol, which has two major pieces.

First piece of NTS is a TLS based service running on TCP.  It grants cookies and shared secret keys.  I'll save that for another post.

The second piece of NTS is extension headers to NTP that allow the whole packet to be authenticated, and part of it can contain encrypted data.

NTP vs NTS tcpdump comparison

Starting with a simple NTP client for comparison, you can see the UDP packets are 48 bytes long.

Normal NTP packet, 48 bytes long

Now a pair of NTP packets with NTS extensions, they're much bigger:

Example NTS packet, 228 bytes long


Let's break apart that request NTS packet.  First, the IPv6+UDP header and the standard NTP packet.  I've color-coded the fields.  This packet is a NTPv4 client request, and sets most of its fields to 0 as the server does not use them.  The server puts the client's transmit timestamp in the originate timestamp field, which can be used to weakly verify the response packet's authenticity.

IPv6, UDP, and NTP request

The new NTS extensions are in the next part of the packet:

NTS extensions in the request

This packet is using the NTS extensions for Unique ID, Cookie, and AEAD ("NTS Authenticator and Encrypted Extension Fields").

For the AEAD section, this packet is only using associated data and has no encrypted data.  AEAD with only associated data and no plaintext is roughly equivalent to a HMAC, but it uses a symmetric cipher instead of a hashing function.  Everything before the 0x404 extension header is authenticated with this header, so no parts of the NTP packet or the NTS extensions can be modified without it being detected.  The cookie is encrypted with a separate key not known to the client and it tells the server the session keys to use and which AEAD algorithm was negotiated.


The first part of the response packet are the normal IPv6/UDP/NTP headers:

IPv6, UDP, NTP response

Not much difference there.

NTS extensions in response

Here, the Unique ID matches the request.  But instead of having a cookie, it has a much longer ciphertext.  This is because the server included a new cookie (with the 0x204 extension) in the encrypted response.  All cookies should be handed to the client in an encrypted form (either through the NTS key exchange, or through the encrypted extensions in the 0x404 header).

Testing tools

I've put together a pair of programs to go through the process of a NTS key exchange, as well as adds the NTS extensions to a NTP request.

Example key exchange:

NTS Key Exchange

Example NTP packet:


More posts to come!