Subject: [ntpwg] Fwd: New Version Notification for draft-dfranke-ntp-keyid0-00.txt

From: Daniel Franke <[email-masked]>
Date: Thu, 23 Jun 2016 11:24:10 -0400

I've submitted the following document to the IETF tracker and will
soon be proposing it for WG adoption. It settles the EXT/MAC parsing
debate with a set of simple, complete, and unambiguous rules that are
backward-compatible with existing code and do not rely on any
information outside the packet.

I have a revision in progress which will add a few amendments:

* Further clarify that the dummy MAC needs to be there: you can't just
give a 0 keyid and then have nothing after it, because that looks like
a crypto-NAK.
* Mention that MS-SNTP is squatting on the use of an all-zero MAC as
an in-band signaling mechanism, so senders should pick something else
to use as a dummy value or risk confusing AD servers.
* Add an appendix containing a non-normative reference implementation
of an NTP parser. It will read an NTP packet on stdin and write a
human-readable breakdown to stdout.

---------- Forwarded message ----------
From: [email-masked] <[email-masked]>
Sent: Wednesday, June 22, 2016 8:53 PM
Subject: New Version Notification for draft-dfranke-ntp-keyid0-00.txt

A new version of I-D, draft-dfranke-ntp-keyid0-00.txt
has been successfully submitted by Daniel Fox Franke and posted to the
IETF repository.

Name:           draft-dfranke-ntp-keyid0
Revision:       00
Title:          Clarifying Processing Expectations for Packets with
keyid 0 in the Network Time Protocol Version 4
Document date:  2016-06-22
Group:          Individual Submission
Pages:          4
URL:
https://www.ietf.org/internet-drafts/draft-dfranke-ntp-keyid0-00.txt
Status:         https://datatracker.ietf.org/doc/draft-dfranke-ntp-keyid0/
Htmlized:       https://tools.ietf.org/html/draft-dfranke-ntp-keyid0-00

Abstract:
   This memo clarifies that when a Network Time Protocol Version 4
   packet has a keyid field of zero, the MAC is present solely to
   satisfy certain syntactic constraints, and is to be ignored.

Please note that it may take a couple of minutes from the time of submission
until the htmlized version and diff are available at tools.ietf.org.

The IETF Secretariat
_______________________________________________
ntpwg mailing list
[email-masked]
http://lists.ntp.org/listinfo/ntpwg

---

From: Miroslav Lichvar <[email-masked]>
Date: Mon, 27 Jun 2016 09:55:26 +0200

> information outside the packet.

Using key ID of 0 to indicate that the MAC that should be ignored is
an interesting idea. If this was included in the original RFC 5905, we
probably wouldn't need RFC 7822 and RFC 7821, and I guess a lot of
time would have been saved in discussions on this list :).

If I understand it correctly, it would be useful to allow construction
of packets that are up to 8 octets shorter as the dummy MAC is 20
octets and packets that have only short extension fields and no MAC
don't have to include a no-op 28-octet extension field (e.g. the
checksum complement field from RFC 7821).

One question about the draft. It says:
  In particular, implementations MUST NOT attempt to verify the MAC,
  and MUST NOT respond to the sender with a crypto-NAK.

I think this is exactly what existing NTP implementations do with a
MAC that has key ID of 0. Should it say SHOULD?

> to use as a dummy value or risk confusing AD servers.

Anyone knows what NTP version have requests from clients using
MS-SNTP? IIRC the MS-SNTP specification talks about NTPv3, which
doesn't have extension fields. Maybe the MS-SNTP check on servers
could be restricted to NTPv3 packets.

-- 
Miroslav Lichvar

---

From: Daniel Franke <[email-masked]>
Date: Mon, 27 Jun 2016 09:27:45 -0400

> time would have been saved in discussions on this list :).

The first time I read RFC5905, I *did* get that interpretation out of
it. Apparently nobody else did, though.

> MAC that has key ID of 0. Should it say SHOULD?

Ah foo, you're right. I was looking at receive() and thinking that
passing skeyid=0 to fast_xmit() meant to send an unauthenticated
packet, but actually it switches on the length of the received packet
to decide whether it means that or crypto-NAK. Fortunately, in either
case it still fills in useful timestamp fields, so although this is
ugly it doesn't cause backward-compatibility problems: new clients can
simply disregard the crypto-NAK and treat it like an ordinary
unauthenticated packet.

Another nit that's come up on further code inspection: what about
symmetric and broadcast modes? Existing broadcast clients and
symmetric peers that get a keyid=0 packet will reject it even if they
would have accepted an unauthenticated packet. Another case which
could cause a problem would be if a server received an ordinary packet
with no extensions, but nonetheless decided to respond to it with a
packet containing a dummy MAC; existing clients wouldn't accept this.

These all are funky edge cases that probably won't occur in practice,
but they're just enough to give me second thoughts about this proposal
and think a 28-byte no-op extension field is the way to go. My fear is
not about insufficient backward compatibility per se. My fear is that
other implementors will fear this, and the fear will cause them to
implement some convoluted fallback from one approach to the other. If
that's ever going to be necessary then we're better off just having
the single approach of the 28-byte no-op.

I'm going to write a fork of draft-stenn-ntp-last-extension-00 in
which the extension is padded out to 28 bytes and which provides
guidance as to when it needs to be included. I hope Harlan will regard
this as a friendly amendment, but from the other thread I get the
impression that he won't. Regardless, I think it's a necessary change,
because LAST-EF in its current form violates RFC7822 and creates more
ambiguity than it resolves.

The revised LAST-EF proposal can then duke it out with the keyid 0
proposal. We should adopt one xor the other.
_______________________________________________
ntpwg mailing list
[email-masked]
http://lists.ntp.org/listinfo/ntpwg

---

From: Miroslav Lichvar <[email-masked]>
Date: Mon, 27 Jun 2016 18:54:25 +0200

> packet containing a dummy MAC; existing clients wouldn't accept this.

I think server is supposed to include only extension fields that
correspond to fields that the client used in its request or listed
as supported in the I-Do field. On broadcast server it will have to be
configurable and with symmetric associations there could be some
negotiation. It would be good to have this specified somewhere.

> proposal. We should adopt one xor the other.

I'd lean to the LAST-EF proposal. If it could have any length (>= 28),
it would be also useful for padding requests and responses to make
them symmetric when the number of extension fields or their length is
not symmetric.

However, I think both proposals unnecessarily waste bandwidth. Another
issue that we might want to address and that would probably require a
completely different approach is that per RFC 5905 and RFC 7822 we
can't use smaller extension fields than 16 octets. There is at least
one implementation that drops packets that have shorter fields. If we
allowed all lengths down to 4 octets, it might save a lot of bandwidth
in future.

My suggestion to do this in a compatible way was to specify a packing
extension field that would include smaller extension fields and would
always be at least 28 octets to meet the requirement from RFC 7822. It
would depend on a no-op field with variable length and a MAC extension
field for MACs. If the packing field was present in a packet, there
would be only one and it would contain all optional fields. Old
implementations would see a valid packet with one long extension
field. New implementations could handle packets using this extension
field as if there was a new NTPv4.1 format, which doesn't allow legacy
MACs and doesn't have any restrictions for minimum length of extension
fields. Basically, the header of the packing extension field would be
an extension of the 48-octet NTP header, creating a format with
52-octet header, where the last two octets is the length of all
optional fields plus 4.

The complication in the parser is minimal. It's just a couple of extra
lines of code that disable the detection of MAC. A parser in a python
pseudocode supporting both formats could look like this:

  if len(packet) % 4 or len(packet) < 48:
    return error
  if len(packet) == 48 + 4:
    return crypto_nak
  if len(packet) >= 48 + 28 and packet[48:49] == PACK_EF and
      packet[50:51] == len(packet) - 48:
    format = 1		# new format (NTPv4.1)
    i = 52
  else:
    format = 0 		# old format (NTPv4.0)
    i = 48

  while len(packet[i:]) > 0:
    if format == 1 or len(packet[i:]) >= 28:
      ef_len = packet[i:i+1]
      if (ef_len % 4 or not (4 <= ef_len <= len(packet[i:])))
        return error
      process_ef(packet[i:i+ef_len])
      i += ef_len
    else if len(packet[i:]) < 28:
      process_mac(packet[i:])
      i += len(packet[i:])

  return ok

I think this is the best option if we want the format to:
- have unambiguous parsing
- save bandwidth
- allow packets without legacy MAC
- be compatible with older implementations
- allow arbitrary padding

It's still not clear to me which of these requirements others consider
important. There is a lot of confusion. If we can reach an agreement
that this is a good idea I can write a RFC draft to propose this as a
new recommended format for NTP packets. Or maybe it would be better to
extend the RFC 7822? In any case, if anyone else is interested in
doing that, please feel free.

---

From: Daniel Franke <[email-masked]>
Date: Mon, 27 Jun 2016 13:40:02 -0400

> 52-octet header, where the last two octets is the length of all

I like this idea a lot. A slight complication is that it's not
perfectly backward-compatible, in the sense that an implementation
which understands certain old-format extensions may not understand
them any more when they're packaged as old-format extensions. So we
need to work out some sender-side logic for how to deal with that
possibility, and we may need to allow a mixture of old-format and
new-format extensions in the same packet. All told, this might be a
little hairy, but not so hairy that the algorithm can't be clearly
specified and implemented with reasonable confidence in its
correctness.

Bonus: this proposal gives us a clean slate for adding a bitfield that
provides handling instructions for unrecognized extensions, rather
than having to steal those bits from the field type. In another thread
earlier today I tentatively suggested that we might want a "covered by
MAC" bit. Another possibly-handy thing could be a "critical extension"
bit analogous to the eponymous X.509 feature: packets with any
unrecognized critical extension should be discarded by the receiver;
unrecognized noncritical extensions should simply be ignored.

I'll ponder this a little more, and if I don't come up with any
deal-breakers I'll write it up.
_______________________________________________
ntpwg mailing list
[email-masked]
http://lists.ntp.org/listinfo/ntpwg

---

From: Miroslav Lichvar <[email-masked]>
Date: Tue, 28 Jun 2016 08:39:18 +0200

On Mon, Jun 27, 2016 at 01:40:02PM -0400, Daniel Franke wrote:
> possibility,

I think the sender logic should be similar as for other extension fields.
The client can try sending the field and see if the server responds
with the same field or a field that's related to it. Alternatively, if
the server supports I-Do, it should be listed as supported.

> and we may need to allow a mixture of old-format and
> new-format extensions in the same packet.

Why would we need that? If some new extension field can't be used in
the old format (e.g. because it's too small), its specification should
require support for the new format. Either both server and client
support the new format or they don't. If they don't, they can't work
with the new extension fields.

While technically it's possible to have multiple packing fields mixed
with other fields in one packet, I suspect it would complicate the
parser logic as it would have to know which field is in which format
and where should be detection of legacy MACs enabled. I like the fact
that if the packet is required to have all optional fields in the
packing field, the length of the packet can be verified in constant
time and that it is an additional protection against length-extension
attacks.

> than having to steal those bits from the field type.

You mean to use a different format for headers of extension fields
that are inside the packing field? Theoretically, we could use the
two lowest bits from the field length as the length is divisble by 4,
although I'm not sure if it's worth the complications.

> deal-breakers I'll write it up.

Great, thanks.