Subject: [Ntp] An NTPv5 design sketch

From: Daniel Franke <[email-masked]>
Date: Sun, 12 Apr 2020 12:19:22 -0400

Rendered version:
https://gist.github.com/dfoxfranke/4ca0443b6ff6e0473578cf3827b9ea7f

# Overview

ΤΗ ΚΑΛΛΙΣΤΗΙ!

This is a sketch of a proposed NTPv5 design (by no means a complete
spec, but hopefully good enough to make the concepts clear). It's a
fairly ambitious step forward from previous versions, almost but not
quite a green field design.  I say "almost" because it retains a
couple limited backward-compatibility constraints:

1. It must be possible to cleanly multiplex NTPv5 with NTPv4 (and
   earlier) on the same port. Basically the just means keeping the
   version field in the same place.

2. It must be possible to discipline your clock from a mix of NTPv5
   and NTPv4 sources.

That said, the reader should still find much that is familiar. We've
learned a lot in the nearly 35 years that NTP has been in operation,
but plenty of those lessons have been about what works and not just
about what doesn't!

This design includes *all the goodies* — just about everything from
the [trac wishlist](https://trac.ietf.org/trac/ntp/wiki/NtpVersionFourIssues)
is addressed here. Some highlights follow:

* The packet structure has been completely reworked, aside from
  retaining the version field as previously mentioned.

* Network Time Security is a mandatory and integral part of the
  protocol. NTS-related fields are a part of the base packet rather
  than extension. All information that can be encrypted, is, and
  clients do not send any information servers beyond what is strictly
  necessary for the server to construct a response.

* All communication in NTPv5 is unicast between a stateful client and
  a stateless server. Behavior analagous to symmetric mode of NTPv4 is
  implemented in NTPv5 by two endpoints each functioning as a client
  of the other. The broadcast mode has been eliminated.

* NTPv4's interleaved timestamp functionality is replaced by a
  distinct "follow-up" message, similar to the eponymous functionality
  in PTP.

* NTPv4's "refid" mechanism, intended to detect one-degree timing
  loops, is replaced by a new mechanism based on Bloom filters that
  works out to arbitrary degree.

* Timestamps are now based on the TAI timescale, and time packets
  carry a UTC-TAI offset and more detailed information about recent or
  upcoming leap seconds.

* I adopt PTP's 80-bit timestamp format.

* Time packets carry both an absolute clock (subject to step
  adjustments) and a (stable) difference clock.

* Time packets carry an unencrypted and unauthenticated correction
  field intended for manipulation by middleboxes. The function of this
  field is analogous to PTP's concept of transparent clocks.  We
  define a value for the Router Alert IP option to signal to
  middleboxes that this behavior is desired.

* Methods for selecting among time sources, filtering noise, nd
  disclipining the local clock are not discussed in this sketch, and I
  propose that they no longer be a normative part of the standard. We
  specify only as much as is necessary to define protocol semantics
  and to ensure global stability among heterogenous implementations.

# Additions to NTS-KE

NTS-KE works the same way for NTPv5 as it does for NTPv4. We allocate
a new NTS Next Protocol ID to represent NTPv5 and define new NTS-KE
record types "New Cookie For NTPv5", "NTPv5 Server Negotiation", and
"NTPv5 Port Negotiation" whose structure and semantics are identical
to their NTPv4 counterparts.

We add one additional NTS-KE record, "Request Address-Bound NTPv5
Cookies", whose body is empty and whose critical bit is unset. When
the client includes this record in an NTS-KE request, it is asking
that the cookies that the server returns be cryptographically bound to
the client's network address, such that the NTP server will reject
them as invalid if the client sends them from any other
address. Normally such a restriction is undesirable, because it
interacts poorly with mobile clients and certain NATs and therefore
would lead to a less reliable protocol.  However, it makes possible
certain features which would otherwise be unsafe.

Most of NTPv5 is designed to prevent DDoS amplification: response are
never larger than the request they are responding to. However, the
"follow-up" feature is an exception to this, since the server sends
back two packets in response to a single packet from the
client. Address-bound cookies prevent this from being abused due to
the difficulty of obtaining a cookie bound to a spoofed
address. Servers will be mandated to send follow-up messages only to
clients which present address-bound cookies, and clients will be
advised to request address-bound cookies if and only if they plan to
utilize the follow-up message feature.

# Preliminaries on packet structure

Throughout this document I'll be using the TLS presentation language
to describe packet structure; see RFC 8446, section 3. Of the two
array styles specified there (triangular brackets for arrays preceded
by their length, square brackets for ones that are not), I use use
only the [] style, and the corresponding length field is always
explicit elsewhere in the message.

To be friendly to hardware implementations, all variable-length fields
are padded out to a multiple of 4 octets; the length field gives the
*unpadded* length which is then rounded up to the next multiple of
four to obtain length inclusive of padding. We'll use the following
type to conveniently represent an opaque field that has padding at the
end of it:

```
struct {
  opaque data[4];
} padded;
```

Furthermore, all 1, 2, and 4-octet fields are generally arranged so as
to be self-aligned, and longer fields are arranged to have 4-octet
alignment. Timestamps, which follow the format of PTPv2, are slight
exception to this:

```
struct {
  int48 seconds; // SI seconds, has a range of about ±4.46 million years
  uint32 nanoseconds; // SI nanoseconds, ranging [0..999999999]
  uint16 fracs; // 1/65536ths of a nanosecond
} Timestamp;
```

Although they partly follow the rule by being 12 octets long and
aligned to 4 octets everywhere they occur, the `uint32 nanoseconds`
has odd alignment.

In any case, the padding rules are exactly what is specified in this
grammar; there is no implicit additional padding.

# Top-level packet structure

Every NTPv5 packet has the same top-level format: two fixed octet giving
the version number, a two octet packet type, and then a type-dependent
body.

```
enum {
  request(0),
  response(1),
  request_with_correction(2),
  response_with_correction(3),
  nts_nak(4),
  (65535)
} PacketType;

struct {
  /* Keep this octet fixed like this for all future versions. NTPv6
     and beyond should continue with VN=5 here, and give their actual
     version in the next octet. */
  uint8 legacy_li_vn_mode = 0xe8; // LI = 3 (unsync), VN = 5, Mode = 0

  /* Version field gets a whole octet from now on rather than just 3 bits */
  uint8 version = 5;

  PacketType packet_type;

  select(Packet.packet_type) {
    case request:                  NtsData;
    case response:                 NtsData;
    case request_with_correction:  NtsDataWithCorrection;
    case response_with_correction: NtsDataWithCorrection;
    case crypto_nak:               NtsNak;
  } body;
} Packet;

struct {
  uint8 cookie_length; //Always zero in response packets
  uint8 nonce_length;
  uint16 ciphertext_length;
  opaque unique_identifier[32];
  padded cookie[pad(cookie_length)]; //Always zero-length in response packets
  padded nonce[min(16,pad(cookie_length))]; //Padded up to a minimum 16 octets
  padded ciphertext[pad(ciphertext_length)];
} NtsData;

struct {
  Correction correction;
  NtsData nts_data;
} NtsDataWithCorrection;

struct {
  opaque unique_identifier[32];
} NtsNak;

```

The `Packet` structure is a cryptographic envelope: except for the
`Correction` structure (fully defined later) which is intentionally
manipulable by middleboxes, it exposes only as much information as is
needed for the receiver to locate, authenticate, and decrypt the
ciphertext.

If you are already familiar with NTS for NTPv4, then the meaning of
the fields of `NtsData` should be self-explanatory. While they are now
syntactically part of the base packet rather than being scattered
across NTS extension fields, they have basically the same semantics as
those corresponding extensions. There is only a slight difference in
how the associated data for RFC 5116 is constructed. In NTPv4, the
Associated Data is whatever appears on the wire from the start of the
packet to the start of the NTS Authenticator and Encrypted Extensions
Fields extension field. In NTPv5, the associated data is exactly the
following structure:

```
struct {
  uint8 legacy_li_vn_mode = 0xe8;
  uint8 version = 5;
  PacketType packet_type;
  uint8 cookie_length;
  uint8 nonce_length;
  uint16 ciphertext_length;
  opaque unique_identifier[32];
  padded cookie[pad(cookie_length)];
} NtsAd;
```

The `NtsAd` structure is a pseudo-type which never crosses the wire as
such, but is formed by cpying the corresponding fields out of `Packet`
and `NtsData`. Authenticating some of these fields is redundant but
helps guard against certain implementation mistakes.

Decrypting the ciphertext gives a structure of type `NtsPlaintext`:

```
enum {
  time_request(0),
  time_response(1),
  followup_response(2),
  source_request(3),
  source_response(4),
  (65535)
} MessageType;

struct {
  MessageType msg_type;
  uint8 cookie_len;
  uint8 num_cookies;
  /* num_cookies cookies, each with an unpadded length of cookie_len, and
     padding added to the end of each individual cookie. */
  padded cookies[num_cookies * pad(cookie_len)];
  select (NtsPlaintext.msg_type) {
    case time_request:          TimeRequest;
    case time_response:         TimeResponse;
    case source_request:        SourceRequest;
    case source_response:       SourceResponse;
    case followup_response:     FollowupResponse;
  } body;
} NtsPlaintext;
```

Here we have a bit more machinery for NTS cookies, and a message type
and corresponding body where all the information actually related to
time synchroniziation lives. In request packets, the `cookies` field
contains placeholders, and in response packets it contains fresh
cookies being provided to the client. Again, while I have made the
syntactic change of moving these from extension fields to the base
packet, the semantics are the same as they are in NTPv4.

# Time messages

Unless extensions are present, the body of a time request has only
one bit of any interest; the rest is just anti-amplification padding.
When bit 2 of the `flags` octet is set, the client is requesting that
the server send a follow-up packet to provide a drivestamp.

```
struct {
  uint8 flags; /* bit 2: set = follow-up requested
                  bit 0-1, 3-7: unused, MUST be clear */
  opaque anti_amplification_padding[103];
  Extension extensions[]; // Each extension is self-delimiting, and we're at
                          // the end of the extension list when we're at the
                          // end of the structure
} TimeRequest;
```

Now finally we reach the meat: the `TimeResponse` structure where all
the core time synchronization information lives. Inline comments
briefly describe each field and then I'll circle back to highlight
some details.

```
struct {
  uint8 flags; /* bit 0: set = synchronized, clear = unsynchronized
                  bit 1: set = leap insertion, clear = leap deletion
                  bit 2: set = expect follow-up
                  bit 3-7: unused, MUST be clear */

  /* Same meaning as in NTPv4 */
  int8 precision;

  /* Please don't send me an average of more than one packet per
     2**throttle seconds once you've stabilized */
  int8 throttle;

  /* Please don't send me more than one packet over any
     2**burst_throttle second interval */
  int8 burst_throttle;

  /* Randomly-generated value that identifies this server */
  opaque source_id[16];

  /* Incremented whenever we change upstream sources or whenever one
    of our upstream sources changes its own source_seqno. */
  uint32 source_seqno;

  /* These have no specified epoch; they get set arbitrarily on
     startup and never step. They may receive frequency discipline but
     never offset discipline (c.f. RAD clocks). */
  Timestamp recv;
  Timestamp xmit;

  /* Add this amount to convert the recv and xmit timestamps to a TAI
     timestamp (relative to midnight 1970-01-01 TAI). This estimate
     gets an immediate step adjustment any time we receive a new data
     point. */
  Timestamp tai_loc_offset;

  /* Error estimates for tai_loc_offset (replaces root
     delay/dispersion) */
  Timestamp max_error;
  Timestamp rms_error;

  /* The TAI time of the last-announced leap event, which might be
     past or future. Flag bit 1 says whether it's an insertion or
     deletion */
  Timestamp leap_event;

  /* UTC-TAI offset after the completion of the above event */
  int32 utc_tai_offset;

  /* Counts the number of leap events that have ever historically
     occurred */
  uint32 leap_seqno;

  Extension extensions[]; // Each extension is self-delimiting, and we're at
                          // the end of the extension list when we're at the
                          // end of the structure
} TimeResponse;
```

The `recv` and `xmit` timestamps are captured at the same point as
they are in NTPv4 (the recv timestamp the moment the request is
received, the xmit timestamp as nearly as possible to the moment the
response is sent). However, these timestamps don't have a defined
epoch so they don't actually tell you the time as such: they're just
timers that advance by one second per second of real time — difference
clocks as opposed to absolute clocks. To get an absolute timestamp, you
have to add `tai_loc_offset` to them.

`tai_loc_offset` represents the server's best available estimate of
the offset between its local monotonic clock (what it samples when it
captures `recv` and `xmit` timestamps) and TAI. It's allowed to jump
around every time the server gets a new data point that improves its
estimate. So you can't rely on `xmit + tai_loc_offset` to be at all
stable; it can even move backward. In any computation that assumes
stable monotonic progression, just use `recv` and `xmit` by themselves.

While `recv` and `xmit` are guaranteed to never receive step adjustments,
there is no guarantee about any higher derivatives. For example if a server
thinks its clock is 5ppm slow, it can immediately speed it up by 5ppm; it
does not have to gradually accelerate.

If the `source_id` field has changed from one time response to
another, then `recv` and `xmit` timestamps from before the change are
no longer comparable to the one after. The server may have rebooted
and lost its clock.

Since we've adopted PTPv2's timestamp format, we also adopt their
epoch of January 1, 1970 TAI rather than the NTPv4 epoch of 1900.

`max_error` gives a maximum error bound on `tai_loc_offset`, and
`rms_error` gives the square root of the expected squared error.

We don't specify what kind of estimator `tai_loc_offset` is, e.g. a
minimum-mean-squared-error estimate versus a maximum likelihood
estimate, and we don't require that the estimator be unbiased.
However, since `rms_error` is based on mean-squared error, using any
estimator other than a MMSE estimator requires reporting a larger
`rms_error` than one otherwise might be able to.

The `leap_event` and `utc_tai_offset` fields along with the `leap
insertion/deletion` flag bit are used in converting from TAI to UTC
and notifying of upcoming or recent leap events. `leap_event` gives
the TAI timestamp as of the conclusion of the most recently-announced
leap second event, which might be in the future or might be in the
past. `utc_tai_offset` gives the UTC-TAI offset as of the conclusion
of that event, and the flag bit tells whether the leap event is/was an
insertion or a deletion.

The `throttle` and `burst_throttle` fields replace KoD RATE messages.
Rather than the server sending KoDs to clients that query it too
frequently (which burdens the server with maintaining a table to keep
track of this), it simply communicates its policy on what query rate
is acceptable and clients are expected to follow it.

The `source_seqno` field is part of NTPv5's loop-detection scheme. Its
meaning and purpose will be explained in a later section.

Extensions have the same type-length-value format that they do in NTPv4:

```
struct {
  uint16 type;
  uint16 len;
  padded body[pad(len)];
} Extension;
```

But, as throughout NTPv5, the length field gives the unpadded length
rather than the padded one. Unlike in NTPv4, NTPv5 extension bodies
have no minimum length since we're free of the syntactic ambiguities
that force RFC 7822 to require one.

This design defines no extension fields. Extension fields are only one
of two ways that NTPv5 can be extended; new message types can be
defined as well. Generally, extension fields should be preferred only
when the information they carry is somehow coupled to the time data in
the same packet (such as, to pick a silly example, adding additional
bits of precision to a timestamp). Otherwise it is probably better to
define a new message type instead.

# Follow-up messages

When the client sets flag bit 2 in a `TimeRequest` and the server sets
bit 2 in its `TimeResponse`, it should be immediately followed by a
`FollowupResponse` which provides a corrected `xmit` stamp. The corrected
stamp can be based on a drivestamp from the emitting NIC and therefore
more accurate than the original.

```
struct {
  Timestamp corrected_xmit;
} FollowupResponse;
```

# Source messages and loop detection

NTPv5 uses a loop-detection mechanism based on Bloom filters that
works for a large number of sources out to arbitrary degree. At
startup, each server randomly assigns itself a 128-bit `source_id`.
It then sends each of its upstream sources a `SourceRequest` message —
just a bunch of padding, no meaningful fields.

```
struct {
  opaque anti_amplification_padding[532];
} SourceRequest;
```

It gets back a `SourceResponse` from each one.

```
struct {
  opaque source_id[16];
  uint32 source_seqno;
  opaque bloom_filter[512];
} SourceResponse;
```

Each source has populated a Bloom filter based on its own sources
further upstream. Our newly-online server now builds a Bloom filter of
its own. First, it takes the union (bitwise OR) of all the filters
from upstream. Then it inserts the `source_id`s of its immediate
upstream stources into the filter. Since source IDs are already
uniformly random, the hash functions we employ can be very simple.
Split the 128-bit `source_id` into ten 12-bit values `h_0`, `h_1`, …,
`h_9`, discarding the last 8 bits. Then for each `i`, set the `h_i`'th
bit in the filter.

Once the new server has computed its filter and finished
synchronizing, it comes online with a `source_seqno` of 0. It then
watches the `source_seqno`s in the time responses from its
sources. Whenever one of them changes, it sends a new `SourceRequest`
to that server, recomputes its filter, and increments its own
`source_seqno`. However, if the new filter that comes back includes
our own `source_id`, this indicates a probable timing loop and we
should drop that source.

The use of Bloom filters means that timing loops will always be
detected but there will be occasional false positives. With the filter
size chosen, we can scale to a few hundred transitive upstream sources
before the probability of a false positive becomes non-negligible,
which should be sufficient.

Endpoints that act only as clients and not as servers don't have to
bother doing any of this since they can't possibly be involved in
timing loops.

# Correction fields

The `Correction` structure is deliberately not encrypted or
authenticated, and is intended for maniplation by middleboxes. It is
similar in function to PTP's transparent clocks.

Packets which contain correction fields must also include a Router
Alert IP option (RFC 2113 & 2711) in order to signal to middleboxes
that they want them modified. Middleboxes must rely strictly on this
option (and not merely on something looking like a syntactically-valid
NTPv5 packet going over the NTP port) to detect that they are handling
NTPv5 traffic and that such modifications are desired.

```
struct Correction {
  Timestamp correction;
  uint32 path_crc;
};
```

`correction` is initially 0 when time requests initiate from the
client. Compliant middleboxes increment it by the amount of time that
the request spends queued. The receiving NTP server copies the
correction field it receives into the response. Middleboxes on the
return path decrement the response's correction field by the amount of
time that the response spends queued.

`path_crc` is initially 0 when time requests initiate from the
client. Compliant middleboxes self-assign an identifier at random and
add their identifier to the CRC (where "add" here means the CRC group
operation). The receiving NTP server copies the `path_crc` field it
receives into the response. Middleboxes on the return path subtract
their self-assigned identifier from the `path_crc`. The client receiving
the response verifies that the `path_crc` is 0. If not, there is a
routing asymmetry and the correction should be discarded.

Correction fields can, obviously, be maliciously altered by a MitM in
order to cause the client to obtain a bogus time estimate. Clients
which pay attention to correction fields must set a limit on the
largest correction they will accept. A correction whose absolute value
is in excess of one half the measured RTT is definitely bogus and
should always be rejected, but clients may choose to set bounds
tighter than this.

---

From: "Dieter Sibold" <[email-masked]>
Date: Tue, 14 Apr 2020 13:01:26 +0200

Great Daniel.

I’d like to add that we also need to consider the topic of 
metrological traceability.
Technically the control fields as described in „Guidelines for 
Defining Packet Timestamps“ might be applied to transport the 
necessary information to enable traceability.

Dieter

On 12 Apr 2020, at 18:19, Daniel Franke wrote:

> the [trac 
> wishlist](https://trac.ietf.org/trac/ntp/wiki/NtpVersionFourIssues)
> _______________________________________________
> ntp mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/ntp

---

From: Miroslav Lichvar <[email-masked]>
Date: Tue, 14 Apr 2020 13:25:41 +0200

> couple limited backward-compatibility constraints:

Thanks for writing it down.

It's a bit too much for me to digest at once. I think I like the
general direction. I particularly like that it allows phase
adjustments to be separated from the base clock. I'm not sure about
TAI and PTP timestamps.

The main issue for me will probably be the dependency on NTS (and
TLS). I don't think that will work for many clients if NTPv5 is
supposed to replace NTPv4.

If I understand it correctly, the main advantage is that it makes
exploiting of follow-up messages more difficult. But it doesn't
prevent amplification attacks completely, right? An attacker who has
even a brief access to the victim's network, could capture a client
request asking for a follow-up message, or generate its own request,
and use this request for an attack until the server rotates the key
out.

-- 
Miroslav Lichvar

---

From: Daniel Franke <[email-masked]>
Date: Tue, 14 Apr 2020 10:35:16 -0400

> and use this request for an attack until the server rotates the key

NTS and the scheme for preventing abuse of follow-up messages aren't
particularly closely connected. The NTS cookie provides a convenient
place to hang the network address binding, but if it weren't already
there it would be easy to add a protocol message to acquire it,
following a similar pattern to DTLS's HelloVerifyRequest.

You're correct — having just a brief ability to receive traffic at a
particular IP address allows later amplification of traffic to that
address until the cookie expires. But the same thing is true of
practically every other protocol on the internet. Modern UDP-based
protocols like QUIC implement a similar scheme to this one, with the
same shortcoming and a much larger amplification factor. Anything
TCP-based is susceptible as well, if the attacker can learn (or guess)
the initial SYN value. Basically, I think we're already going
above-and-beyond in terms of anti-amplification measures and such a
very weak attack, with not even a factor-of-2 amplification if it
succeeds, is not one we need to worry about any further.

---

From: Daniel Franke <[email-masked]>
Date: Tue, 14 Apr 2020 11:02:14 -0400

> supposed to replace NTPv4.

What do you think is the obstacle? Code footprint? There are TLS
stacks that fit in as little as 20k. In applications where even that's
is too much you're probably not fully implementing NTPv4 either and
just doing some brain-dead one-shot SNTP deal, and for that NTPv4 is
fine; there's nothing to improve upon.

---

From: Miroslav Lichvar <[email-masked]>
Date: Tue, 14 Apr 2020 17:38:48 +0200

On Tue, Apr 14, 2020 at 10:35:16AM -0400, Daniel Franke wrote:
> the initial SYN value.

I'm not sure if QUIC or TCP is comparable to NTP/NTS. It is not
possible to blindly create a new connection, or replay one, is it?

An existing TCP connection can be exploited only as long as the upper
protocol allows it. For example, is it likely that the attacker would
be able to blindly send requests to its own HTTPS connection
continuously for a week?

-- 
Miroslav Lichvar

---

From: Miroslav Lichvar <[email-masked]>
Date: Tue, 14 Apr 2020 17:52:41 +0200

On Tue, Apr 14, 2020 at 11:02:14AM -0400, Daniel Franke wrote:
> stacks that fit in as little as 20k.

A minimal NTP client is less than a hundred lines of C code and can
run on any CPU/microcontroller.

TLS has a much larger attack surface.

> In applications where even that's

Is NTPv5 not meant to obsolete NTPv4? Even if not, the new features of
NTPv5 may be useful to clients that cannot or won't support TLS.

-- 
Miroslav Lichvar

---

From: Daniel Franke <[email-masked]>
Date: Tue, 14 Apr 2020 11:53:10 -0400

> be able to blindly send requests to its own HTTPS connection

Sure, once you've been able to receive traffic on the victim's network
to get the initial SYN value (for plain HTTP) or complete the TLS
handshake (for HTTPS), this is totally possible and straightforward.
It requires that you're hitting some unused IP on the victim's
network, so there are no TCP RSTs coming back from the victim. But
once you've got all that, everything further is predictable so there's
no further obstacle to blindly spoofing requests for some big download
over and over again, with HTTP 'Connection: keep-alive' headers to
hold the connection open.

---

From: Daniel Franke <[email-masked]>
Date: Tue, 14 Apr 2020 12:29:57 -0400

On Tue, Apr 14, 2020 at 11:52 AM Miroslav Lichvar <[email-masked]> wrote:
> Is NTPv5 not meant to obsolete NTPv4?

It is. But if a dumb "send me back a UDP packet that has a current
timestamp in it, and I'll set my clock to that" protocol is something
that needs to keep existing, we've already got that and re-inventing
the packet format doesn't help anybody. For bureaucratic purposes so
that we can formally obsolete RFC 5905, we can write a short auxiliary
RFC that restates whatever parts of RFC 5905 Section 14 or RFC 4330
need restating and modernizes the Security Considerations section.

> Even if not, the new features of NTPv5 may be useful to clients that cannot or won't support TLS.

If you can point to some real-world examples of systems that can't
make due with SNTP and can't spare 20k for a TLS stack, then you'll
change my mind.

---

From: Miroslav Lichvar <[email-masked]>
Date: Wed, 15 Apr 2020 09:20:23 +0200

> make due with SNTP and can't spare 20k for a TLS stack, then you'll

It's not just about sparing 20k for a TLS stack. That code will likely
need to be updated to fix security issues. Crypto is hard. NTS
requires other things that were not needed with plain NTP. It needs a
full TCP stack and AES-SIV-CMAC. It needs certificates, NTS-KE servers
and some naming for the servers (e.g. DNS). It needs a much more
powerful CPU to be able to perform a TLS handshake in reasonable time
and processing of NTP packets is orders of magnitude slower even with
a hardware AES support. There is also the requirement on having a
rough idea of current time in order to validate the certificates.

For people who need to synchronize computers in an isolated network it
is a lot of extra work. SNTP or NTPv4 may not be good enough for
accuracy (unless they support correction fields).

There are other authentication mechanisms with different tradeoffs
that people might want to use.

I don't see a single reason why NTS should be a requirement of NTPv5.
It would help if you could explain why do you think it should.

-- 
Miroslav Lichvar

---

From: Daniel Franke <[email-masked]>
Date: Wed, 15 Apr 2020 11:57:45 -0400

On Wed, Apr 15, 2020 at 3:20 AM Miroslav Lichvar <[email-masked]> wrote:
>
> That code will likely need to be updated to fix security issues.

So will the NTP code itself, not to mention the OS kernel and whatever
else your device is running. Different NTP implementations have had
serious security issues with widely varying frequency; so have
different TLS implementations. I'm not going to engage in arguments
about the precise quantity, severity, or inevitability of these
vulnerabilities; I'm just asserting the lack of a qualitative
difference in the historical need for patching.

> Crypto is hard. NTS

You're mixing concerns about constrained devices with concerns about
isolated networks and system administration, which are two very
different spaces with different considerations, so I'll address those
separately.

Constrained devices: microcontrollers from the mid-range upward are
plenty capable of TLS and most of them explicitly advertise as much.
The ones smaller than that aren't designed for networked applications
at all; they're designed for like, tying a few pins from an LED or a
motion sensor together with a with a few pins on an I2C bus. The gap
in capabilities between being able to handle all of the network stack
except TLS and being able to handle TLS is tiny, and I assert that in
practice it's non-existent — because TLS is already so ubiquitous that
there's no market for a networked µC that can't handle it.

Isolated networks: TLS doesn't require certificates or DNS! X.509
supports IP-based SANs, and TLS supports PSKs, bypassing X.509
altogether. If today's software support for such options is lacking or
its UX is poor, remember that none of this is getting deployed
tomorrow; if we get this done in three years I'll consider it to have
gone smoothly. When we first decided on AES-SIV for NTS, there was
barely any support for that either. That situation changed because of
the interest that this WG generated.

> It would help if you could explain why do you think it should.

NTPv5 (as I've sketched it) depends on NTS for more than just
cryptographic security; it's also version negotiation (NTS Next
Protocol), server discovery (Server and Port Negotation), and
anti-amplification (address-bound cookies). Making NTS optional would
require alternative approaches to all these issues. It would also
complicate the packet format and add landmines for implementers
(granted, already present in v4 NTS) around correct handling of
unprotected responses.

---

From: Miroslav Lichvar <[email-masked]>
Date: Thu, 16 Apr 2020 10:25:57 +0200

On Wed, Apr 15, 2020 at 11:57:45AM -0400, Daniel Franke wrote:
> else your device is running.

The device may be very simple. It may not have an OS and NTP may be
the only networking it does. It could be measuring intervals in a
physics experiment, or controlling a robot in a factory. Consider
where and why PTP originated and that NTPv5 with its correction field
might be usable there too.

> Different NTP implementations have had

Well, that would be an interesting exercise, but I think just from the
nature of the domains it's much more likely a TLS code will need to be
patched than an NTP code written with the same care. It would be also
interesting to compare just the protocols alone. How many issues does
NTPv2 from 1989 (which is not that different from NTPv4) have?

> require alternative approaches to all these issues.

I don't see a big problem with that. Supporting NTS is much more
difficult than supporting those extensions would be.

Being able to use other authentication mechanisms (e.g. symmetric key,
or a successor of NTS) is an advantage.

> It would also

Protected responses need to be handled in the same way as unprotected
responses. You never know if the server isn't compromised and trying
to attack you.

-- 
Miroslav Lichvar

---

From: Doug Arnold <[email-masked]>
Date: Thu, 16 Apr 2020 16:11:21 +0000

Supporting simple harware implementations in closed specialized networks, like a robot, is a problem already well solved by PTP.  Making NTP do that does not help solve technical problems.  Making a timing protocol that is robust and secure is not at all solved by PTP.  That is how NTPv5 can make the world better.

Doug

________________________________
From: ntp <[email-masked]> on behalf of Miroslav Lichvar <[email-masked]>
Sent: Thursday, April 16, 2020 1:25 AM
To: Daniel Franke <[email-masked]>
Cc: NTP WG <[email-masked]>
Subject: Re: [Ntp] An NTPv5 design sketch

--
Miroslav Lichvar

---

From: Miroslav Lichvar <[email-masked]>
Date: Thu, 16 Apr 2020 18:36:54 +0200

> Supporting simple harware implementations in closed specialized networks, like a robot, is a problem already well solved by PTP.  Making NTP do that does not help solve technical problems.  Making…

Better accuracy seems to be one of the goals of the proposed design as
it includes the correction field. I would like to see it in one form
or another included in the spec.

Maybe the best example of an extremely simple device that needs to
support NTPv5 and nothing else is an NTPv5 stratum-1 server. Consider
how much will the cost of the hardware change if NTS is required
and the same performance is expected.

-- 
Miroslav Lichvar

---

From: James <[email-masked]>
Date: Thu, 16 Apr 2020 18:06:16 +0100

It appears to me that this Working Group's efforts in determining what 
is appropriate for NTPv5 would be helped by analysing where use cases 
like below are mapped to current/expected protocol functionality and 
capabilities across PTP, NTP, and Roughtime. I would be happy to be part 
of or potentially lead such a thing if people felt it was worth the effort.

- J

On 16/04/2020 17:36, Miroslav Lichvar wrote:
> ...

---

From: Daniel Franke <[email-masked]>
Date: Thu, 16 Apr 2020 13:34:03 -0400

> might be usable there too.

I remain skeptical that systems actually exist, even in these domains,
where unprotected NTPv5 would be a good solution but NTPv5 with NTS
would not be. I've forwarded this thread to a friend who has done a
great deal of work with systems of this nature so that she weigh in
further. At any rate, I second Doug Arnold that if a use case is
already well-served by PTP, then complicating NTPv5 on their behalf is
not solving anyone's problem.

> responses. You never know if the server isn't compromised and trying

I think you've misunderstood me here. I'm not talking about cases like
"don't do an out-of-bounds read if the length field is longer than the
actual packet length" which yes, need to be handled regardless. I'm
referring to handling NTS stripping attacks and making sure you don't
accept an unprotected packet from a source that should only be sending
protected ones.

---

From: James <[email-masked]>
Date: Thu, 16 Apr 2020 17:52:21 +0100

- J

---

From: Doug Arnold <[email-masked]>
Date: Fri, 17 Apr 2020 14:22:03 +0000

I think that it is a good idea, and I would be happy to help.

Doug

________________________________
From: ntp <[email-masked]> on behalf of James <[email-masked]>
Sent: Thursday, April 16, 2020 9:52 AM
To: [email-masked] <[email-masked]>
Subject: Re: [Ntp] An NTPv5 design sketch

- J

---

From: "Ulrich Windl" <[email-masked]>
Date: Mon, 20 Apr 2020 13:54:35 +0200

>>> Daniel Franke <[email-masked]> schrieb am 16.04.2020 um 19:34 in
Nachricht
<17898_1587058469_5E989725_17898_95_1_CAJm83bBBAwA9Da7aasneHV+JfVDOaT2j-Ymyem40-
[email-masked]>:
> already well‑served by PTP, then complicating NTPv5 on their behalf is

Yes, beware of "feature-ism" (adding more and more non-essential features)

> "don't do an out‑of‑bounds read if the length field is longer than the

---

From: Miroslav Lichvar <[email-masked]>
Date: Mon, 20 Apr 2020 14:43:41 +0200

On Thu, Apr 16, 2020 at 01:34:03PM -0400, Daniel Franke wrote:
> At any rate, I second Doug Arnold that if a use case is

I think PTP and NTP have different goals, but overlapping use cases.

PTP is basically NTP in broadcast mode, where the protocol is designed
for hardware support to be as easy as possible. NTP may be more
difficult to support in hardware, but if it could be supported, I
think in many cases it would be preferred over PTP.

A use case where the broadcast design of PTP is an issue (and where
NTP would be preferred) is synchronization in large networks where both
multicast and boundary clocks need to be avoided (e.g. to avoid long
chains of servos). The unicast mode of PTP requires a client-specific
state, which is an issue with larger numbers of clients (it's not
unusual for GM clocks to support only 2048 clients or less), and there
is also an issue that it has practically an infinite amplification
factor, so the access needs to be carefully controlled.

-- 
Miroslav Lichvar

---

From: Doug Arnold <[email-masked]>
Date: Mon, 20 Apr 2020 14:18:14 +0000

There are other key differences between PTP and NTP.  I will list, from the point of view of people familiar with NTP:

  *   Many PTP profiles are layer 2 only, no IP, and sometimes not even Ethernet.
  *   Many users of PTP like to have a strict hierarchy of clocks, one grandmaster, and not have clients or higher stratum clocks ensemble time from multiple servers.  Some people currently using PTP hate this and would rather use a version of NTP tailored for high accuracy.
  *   The assumption of many in the PTP world is that masters have extra processing cycles available, and not slaves (the opposite assumption of NTP)
  *   Many PTP profiles want the network hierarchy to be auto configured, as in using the Best Master Clock Algorithm, which depends on multicast operation.

I think the way to make sure that NTPv5 is useful in ways which PTP isn't is to maintain and perhaps enhance the following properties of NTP:

  *   Layer 3
  *   client server
  *   unicast is primary mode of operation
  *   ensemble of time from multiple servers with voting algorithms for robustness
  *   good cryptographic security
  *   works in WANs, including the public internet

As I mentioned above there are people currently using PTP, who wish that they could use NTP, except NTP doesn't have enough accuracy.  They would have the accuracy if they could run NTP at higher message rates, and substitute different servo filters.  One company has done well with financial data center customers by creating a non standard NTP which does these things.  The proposed modular architecture for NTPv5 would accommodate this.

Doug

Sent: Monday, April 20, 2020 5:43 AM

--
Miroslav Lichvar

---

From: [email-masked]
Date: Tue, 21 Apr 2020 13:48:33 +0200

From my recent experience in evaluating and comparing different time transfer technologies for different use cases, I carefully agree with Miroslav.

Several differences between NTP and PTP are inherently polar opposites on parameters (such as the presumed level of support by involved hardware) that seem like they should be viewed as more of a spectrum.

Also, the fact that both protocols already come as pre-determined bundles of parameters (often offering the mentioned polar opposites) artificially creates a separation of use-cases.

Overall, I think three use cases are already well-served:

1) You absolutely need sub-millisecond performance AND you physically control the whole network AND have the resources to install massive amounts of expensive hardware (AND, if you need an absloute reference such as UTC, you have high-accuracy access to it at at least one point in your network),

2) You want to do your synchronization via the internet AND want to use non-specialized hardware AND you really only need tens-hundreds of milliseconds of accuracy guaranteed but are happy if you statistically mostly get three or four orders of magnitude better than that,

3) You need sub-millisecond (possibly sub-microsecond) accuracy AND you have access to an antenna with good reception AND you don't really worry about anyone jamming or spoofing your signal.

Everything else currently seems to require significant compromise and/or research and development.

While I think the points of avoiding featurism and re-inventing solutions for solved use-cases are perfectly valid, I also think it is worth to think about possible (new or unusual or just previously neglected) use-cases that slight variations of NTP could help solving.

Best regards,

Kristof

ntp" <[email-masked]> schrieb: -----

An: "Daniel Franke" <[email-masked]>
Von: "Miroslav Lichvar"
Gesendet von: "ntp"
Datum: 20.04.2020 14:45
Kopie: "NTP WG" <[email-masked]>
Betreff: Re: [Ntp] An NTPv5 design sketch

--
Miroslav Lichvar

---

From: "Salz, Rich" <[email-masked]>
Date: Tue, 21 Apr 2020 13:34:46 +0000

the only networking it does. It could be measuring intervals in a
    physics experiment, or controlling a robot in a factory.

I would like to see this use-case *not* be a requirement for NTPv5.  Let's wait for IoT security to settle itself and then adapt to that.
See, for example, https://datatracker.ietf.org/wg/lake/about/

---

From: Kyle Rose <[email-masked]>
Date: Tue, 21 Apr 2020 09:51:02 -0400

On Tue, Apr 21, 2020 at 9:35 AM Salz, Rich <rsalz=
[email-masked]> wrote:

> I would like to see this use-case *not* be a requirement for NTPv5.
>

Strong agree, but because NTP's purpose is to synchronize wallclock time
first. Intervals are a second-class citizen, and anyway conflict with the
first requirement once you get beyond very short intervals.

---

From: "Ulrich Windl" <[email-masked]>
Date: Tue, 21 Apr 2020 16:00:39 +0200

>>> Kyle Rose <[email-masked]> schrieb am 21.04.2020 um 15:51 in Nachricht
<25459_1587477108_5E9EFA73_25459_2_31_CAJU8_nUXUEtsddE9byQgEfMknLSz8ywMs23CNyYKF
> first requirement once you get beyond very short intervals.

An interesting concept would be a "virtually corrected (software) clock" that leaves the OS clock alone, keeping the offset and drift als variable. So at any time the OS clock could be "fixed" from the virtual clock as if it were continuously adjusted all the time. Eventually this would allow to run multiple versions of NTP on a single host ;-)

---

From: Doug Arnold <[email-masked]>
Date: Tue, 21 Apr 2020 18:14:21 +0000

There are use cases for this concept:

The virtual clock can be kept as a backup to some other source of time, and could take over the system clock if the other source of time went away.  That would allow the NTP servo loop to be warmed up  and experience less startup transient when it took over.

One could have several sources of time come into a device, through different mechanisms, each run its own virtual servo loop. A combining algorithm, outside of each of the mechanisms, controls the clock using information from all of the mechanisms.

A device might have a clock running on some arbitrary timescale as part of a closed system, but keep a virtual NTP clock just to log events with standard time.

Here is a crazy one, but a company actually uses it in their network.  Time is distributed by both PTP and NTP.  If the time from the two distribution mechanisms agree to within the expected error bounds, then the clock is set by PTP, which is assumed to be more accurate.  If PTP and NTP time disagree by too much, then the clock is set by NTP, which is assumed to be more robust.  Kind of embarrassing for both protocols if you ask me.

There are probably other use cases.

Doug

________________________________
From: ntp <[email-masked]> on behalf of Ulrich Windl <[email-masked]>
Sent: Tuesday, April 21, 2020 7:00 AM
To: Rich Salz <rsalz=[email-masked]>; Kyle Rose <[email-masked]>
Cc: [email-masked] <[email-masked]>; [email-masked] <[email-masked]>; Daniel Franke <[email-masked]>
Subject: [Ntp] Antw: [EXT] Re: An NTPv5 design sketch

---

From: "Ulrich Windl" <[email-masked]>
Date: Wed, 22 Apr 2020 08:41:25 +0200

As I just had pressed "reply", only Doug  got the response. Please see it attached. Sorry.

>>> Doug Arnold <[email-masked]> schrieb am 21.04.2020 um 20:14 in
Nachricht
<[email-masked]>

> There are use cases for this concept:

Subject: Antw: Re: [Ntp] Antw: [EXT] Re: An NTPv5 design sketch
From: "Ulrich Windl" <[email-masked]>
To: <[email-masked]>
Date: Wed, 22 Apr 2020 08:38:20 +0200

>>> Doug Arnold <[email-masked]> schrieb am 21.04.2020 um 20:14
in
Nachricht
<[email-masked]>

> The virtual clock can be kept as a backup to some other source of time, and

> could take over the system clock if the other source of time went away. 
That 
> would allow the NTP servo loop to be warmed up  and experience less startup

> transient when it took over.
> 
> One could have several sources of time come into a device, through different

> mechanisms, each run its own virtual servo loop. A combining algorithm, 
> outside of each of the mechanisms, controls the clock using information from

> all of the mechanisms.
> 
> A device might have a clock running on some arbitrary timescale as part of a

> closed system, but keep a virtual NTP clock just to log events with standard

> time.
> 
> Here is a crazy one, but a company actually uses it in their network.  Time

> is distributed by both PTP and NTP.  If the time from the two distribution 
> mechanisms agree to within the expected error bounds, then the clock is set

> by PTP, which is assumed to be more accurate.  If PTP and NTP time disagree

> by too much, then the clock is set by NTP, which is assumed to be more 
> robust.  Kind of embarrassing for both protocols if you ask me.

What does the current NTP implementation do if you have two stratum-1 sources
disagreeing on the correct time while being of "high quality"? Toss a coin?
Officially it does not, but the results are quite similar. It's named "clock
hopping". "prefer" isn't really a solution if you have no control over such
(stratum-1) sources...

> From: ntp <ntp‑[email-masked]> on behalf of Ulrich Windl 
> <[email-masked]‑regensburg.de>
> Cc: [email-masked] <[email-masked]>; [email-masked] <[email-masked]>;

> Daniel Franke <[email-masked]>
<25459_1587477108_5E9EFA73_25459_2_31_CAJU8_nUXUEtsddE9byQgEfMknLSz8ywMs23CNy
> YKF
>>> I would like to see this use‑case *not* be a requirement for NTPv5.
>>>
>>
>> first. Intervals are a second‑class citizen, and anyway conflict with the
> An interesting concept would be a "virtually corrected (software) clock" 
> that leaves the OS clock alone, keeping the offset and drift als variable.
So 
> at any time the OS clock could be "fixed" from the virtual clock as if it 
> were continuously adjusted all the time. Eventually this would allow to run

> multiple versions of NTP on a single host ;‑)
> 
>

---

From: Miroslav Lichvar <[email-masked]>
Date: Wed, 22 Apr 2020 08:52:09 +0200

> hopping". "prefer" isn't really a solution if you have no control over such

If there are two sources and they don't agree, the selection algorithm
will mark them as falsetickers and prevent any updates of the clock.

Even when combining PTP and NTP, it's good to have at least three
time sources, so a single falseticker can be detected. It can be two
NTP servers and one PTP domain, or a single NTP server and two
separate PTP domains (ideally using different hardware), which is more
expensive but allows you to keep the PTP accuracy when a single
failure occurs.

-- 
Miroslav Lichvar