Subject: [tsvwg] Comments on draft-ietf-tsvwg-udp-options-04

From: "C. M. Heard" <[email-masked]>
Date: Tue, 3 Jul 2018 22:26:54 -0700

Hi Joe,

This version looks really good to me, with only a couple of minor issues.

First, in Section 5.4, Alternate Checksum (ACS), there are two technical
comments that I made on the -02 version that I don't believe have been
properly addressed:

On Sun, May 6, 2018 at 10:23 AM, C. M. Heard wrote:
>
> Also, it is necessary to specify whether the data polynomial is
> constructed as if the bytes are transmitted most significant bit first or
> least significant bit first. Finally, the polynomial is x^16 + x^12 + x^5
> + 1 (which would be 0x11021, but that fact is not needed, and I recommend
> omitting it).
>

In what is probably a typo, the -04 draft has the generator polynomial as "x^16
+ x^12 + x^5 + x" instead of "x^16 + x^12 + x^5 + 1."

It also does not specify how to construct the polynomial represent the data
to be checksummed. That latter point may not be entirely obvious.

In order to re-used existing software used to compute CRC-CCITT, that
polynomial needs to be constructed as if the least significant bit of each
byte is the the coefficient associated with the highest power of x. So, for
example, *0x8b* would correspond to

x^7 + x^6  + x^4 + 1

and not to

x^7 + x^3 + x  + 1

as one might expect. Here is how one might fully specify the algorithm. Suppose
that there are n bytes of checksummed data, indexed from 0 through n-1 in
order of appearance in the (possibly reassembled) datagram, and P(k,x) is
the polynomial representing the kth byte. Then the polynomial M(x)
representing the data to be checksummed would be the sum, taken from k=0 to
n-1, of x^(8*(n-1-k)) * P(k,x). The ACS option then contains the remainder
upon division (modulo 2) of x^16 * M(x)  by the generator polynomial x^16 +
x^12 + x^5 + 1.

I would not belabor such a seemingly trivial point were it not so vexatious
in practice. Maybe you can think of some nice, short, words to make this
point clear. Or maybe there is a suitable stable reference that has the
details, though at this time I am not aware of one. Or maybe I am in the
rough and it really is something that "everyone knows" (but I doubt that).

Also, may I suggest that instead of saying that the "Alternate Checksum
(ACS) provides a stronger alternative to the UDP header checksum" consider
saying instead "Alternate Checksum (ACS) provides a stronger alternative to
the checksum in the UDP header." To me, the words "UDP header checksum"
 suggest a checksum that covers only the UDP header (similar to an
analogous one in IPv4). There are two additional occurrences in Section
5.7, where I have some other editorial suggestions as well:

OLD:

   >> During fragmentation, the UDP header checksum of each fragment
   needs to be recomputed based on each datagram's pseudoheader.

   >> After reassembly is complete and validated using the checksum of
   the terminal FRAG option, the UDP header checksum of the resulting

   datagram needs to be recomputed based on the datagram's
   pseudoheader.

NEW:

   >> During fragmentation, the checksum in the UDP header of each fragment
   needs to be recomputed based on that datagram's pseudoheader.

   >> After reassembly is complete and validated using the checksum of
   the terminal FRAG option, the checksum in the UDP header of the resulting

   datagram needs to be recomputed based on the reassembled datagram's
   pseudoheader.

Thanks and regards,

Mike Heard

---

From: "C. M. Heard" <[email-masked]>
Date: Wed, 4 Jul 2018 07:10:09 -0700

On Tue, Jul 3, 2018 at 10:26 PM, C. M. Heard wrote:
...

> [Section 5.4, Alternate Checksum (ACS)] does not specify how to construct
> the polynomial represent the data to be checksummed. That latter point may
> not be entirely obvious.
>
> n-1, of x^(8*(n-1-k)) * P(k,x). The ACS option then contains the
> remainder upon division (modulo 2) of x^16 * M(x)  by the generator
> polynomial x^16 + x^12 + x^5 + 1.
>

That would be the CRC-CCITT calculated using the above bit-ordering
convention but without inverting the first 16 bits of checksummed data and
without inverting the final final remainder.

> I would not belabor such a seemingly trivial point were it not so
> vexatious in practice. Maybe you can think of some nice, short, words to
> make this point clear. Or maybe there is a suitable stable reference that
> has the details, though at this time I am not aware of one. Or maybe I am
> in the rough and it really is something that "everyone knows" (but I doubt
> that).
>

There is actually a stable reference, namely Appendix C of RFC 1662. It
provides a reference implementation for exact algorithm used by X.25 and
HDLC, in which the first 16 bits of checksummed data are inverted prior to
the calculation and the final remainder is inverted prior to transmission.
It uses the above bit-ordering convention and calculates a 16-bit remainder
in which the most significant bit is the coefficient of x^0 and the lest
significant bit is the coefficient of x^15. That gets transmitted least
significant byte first -- i.e., the opposite way from standard network byte
order -- which is necessary for an implementation that processes the
message + CRC serially.

RFC 5570 relied upon this reference to specify a 16-bit checksum for the
CALIPSO IPv6 option:

   This 16-bit field contains the a CRC-16 checksum as defined in
   Appendix C of RFC 1662
<https://tools.ietf.org/html/rfc1662#appendix-C> [RFC1662
<https://tools.ietf.org/html/rfc1662>].  The checksum is calculated
over
   the entire CALIPSO option in this packet, including option header,
   zeroed-out checksum field, option contents, and any required padding
   zero bits.

Unfortunately, this is underspecified with respect to the byte ordering of
the checksum field. Erratum 4545
(https://www.rfc-editor.org/errata/eid4545) was
filed against RFC 5570 for that reason. We do not want to fall into the
same trap of underspecification with the UDP ACS option.

I would like to propose the following specific changes to the text:

OLD:

   The Alternate Checksum (ACS) provides a stronger alternative to the
   UDP header checksum, using a 16-bit CRC of the conventional UDP
   payload only (excluding the IP pseudoheader, UDP header, and UDP
   options, and not include the LITE area). It does not include the IP
   pseudoheader or UDP header, and so need not be updated by NATs when
   IP addresses or UDP ports are rewritten. Its purpose is to detect
   errors that the UDP checksum might not detect. CRC-CCITT (polynomial
   x^16 + x^12 + x^5 + x) has been chosen because of its ubiquity and
   use in other packet protocols, such as X.25, HDLC, and Bluetooth.
The option contains the remainder of the calculation of the
   polynomial over the UDP payload data (i.e., not inverted).

NEW:

   The Alternate Checksum (ACS) provides a stronger alternative to the
   checksum in the UDP header, using a 16-bit CRC of the conventional
   UDP payload only (excluding the IP pseudoheader, UDP header, and UDP
   options, and not include the LITE area). Since it does not include
   the IP pseudoheader or the UDP header, it need not be updated by NATs
   when IP addresses or UDP ports are rewritten. Its purpose is to detect
   errors that the UDP checksum might not detect. CRC-CCITT (polynomial
   x^16 + x^12 + x^5 + 1) has been chosen because of its ubiquity and
   use in other packet protocols, such as X.25, HDLC, and Bluetooth.

   The option contains the CRC-16 calculated in the manner defined in
   Appendix C of RFC 1662
<https://tools.ietf.org/html/rfc1662#appendix-C> [RFC1662
<https://tools.ietf.org/html/rfc1662>], except that it is not inverted
   and is stored in network byte order.

If you want to exclude the inversion of the first two bytes of checksummed
data, that could be done also. There is no particular technical reason for
one choice versus another; I picked the option that takes fewer words to
specify. Sorry that it took so many words for me to get to this point.

Mike Heard

---

From: Joe Touch <[email-masked]>
Date: Thu, 5 Jul 2018 17:40:46 -0700

Thanks - this will be fixed in the next revision.

Joe

> On Jul 3, 2018, at 10:26 PM, C. M. Heard <[email-masked]> wrote:
> 
> Hi Joe,
> 
> First, in Section 5.4, Alternate Checksum (ACS), there are two technical comments that I made on the -02 version that I don't believe have been properly addressed:
> 
> Also, it is necessary to specify whether the data polynomial is constructed as if the bytes are transmitted most significant bit first or least significant bit first. Finally, the polynomial is x^16 + x^12 + x^5 + 1 (which would be 0x11021, but that fact is not needed, and I recommend omitting it).
> 
> In what is probably a typo, the -04 draft has the generator polynomial as "x^16 + x^12 + x^5 + x" instead of "x^16 + x^12 + x^5 + 1."
> 
> It also does not specify how to construct the polynomial represent the data to be checksummed. That latter point may not be entirely obvious.
> 
> In order to re-used existing software used to compute CRC-CCITT, that polynomial needs to be constructed as if the least significant bit of each byte is the the coefficient associated with the highest power of x. So, for example, 0x8b would correspond to
> 
> x^7 + x^6  + x^4 + 1
> 
> and not to
> 
> x^7 + x^3 + x  + 1
> 
> as one might expect. Here is how one might fully specify the algorithm. Suppose that there are n bytes of checksummed data, indexed from 0 through n-1 in order of appearance in the (possibly reassembled) datagram, and P(k,x) is the polynomial representing the kth byte. Then the polynomial M(x) representing the data to be checksummed would be the sum, taken from k=0 to n-1, of x^(8*(n-1-k)) * P(k,x). The ACS option then contains the remainder upon division (modulo 2) of x^16 * M(x)  by the generator polynomial x^16 + x^12 + x^5 + 1.
> 
> I would not belabor such a seemingly trivial point were it not so vexatious in practice. Maybe you can think of some nice, short, words to make this point clear. Or maybe there is a suitable stable reference that has the details, though at this time I am not aware of one. Or maybe I am in the rough and it really is something that "everyone knows" (but I doubt that).
> 
> Also, may I suggest that instead of saying that the "Alternate Checksum (ACS) provides a stronger alternative to the UDP header checksum" consider saying instead "Alternate Checksum (ACS) provides a stronger alternative to the checksum in the UDP header." To me, the words "UDP header checksum"  suggest a checksum that covers only the UDP header (similar to an analogous one in IPv4). There are two additional occurrences in Section 5.7, where I have some other editorial suggestions as well:
> 
> OLD: