summaryrefslogtreecommitdiff
path: root/doc/rfc/rfc9187.txt
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-11-27 20:54:24 +0100
committerThomas Voss <mail@thomasvoss.com> 2024-11-27 20:54:24 +0100
commit4bfd864f10b68b71482b35c818559068ef8d5797 (patch)
treee3989f47a7994642eb325063d46e8f08ffa681dc /doc/rfc/rfc9187.txt
parentea76e11061bda059ae9f9ad130a9895cc85607db (diff)
doc: Add RFC documents
Diffstat (limited to 'doc/rfc/rfc9187.txt')
-rw-r--r--doc/rfc/rfc9187.txt504
1 files changed, 504 insertions, 0 deletions
diff --git a/doc/rfc/rfc9187.txt b/doc/rfc/rfc9187.txt
new file mode 100644
index 0000000..35723c7
--- /dev/null
+++ b/doc/rfc/rfc9187.txt
@@ -0,0 +1,504 @@
+
+
+
+
+Independent Submission J. Touch
+Request for Comments: 9187 Independent Consultant
+Category: Informational January 2022
+ISSN: 2070-1721
+
+
+ Sequence Number Extension for Windowed Protocols
+
+Abstract
+
+ Sliding window protocols use finite sequence numbers to determine
+ segment placement and order. These sequence number spaces wrap
+ around and are reused during the operation of such protocols. This
+ document describes a way to extend the size of these sequence numbers
+ at the endpoints to avoid the impact of that wrap and reuse without
+ transmitting additional information in the packet header. The
+ resulting extended sequence numbers can be used at the endpoints in
+ encryption and authentication algorithms to ensure input bit patterns
+ do not repeat over the lifetime of a connection.
+
+Status of This Memo
+
+ This document is not an Internet Standards Track specification; it is
+ published for informational purposes.
+
+ This is a contribution to the RFC Series, independently of any other
+ RFC stream. The RFC Editor has chosen to publish this document at
+ its discretion and makes no statement about its value for
+ implementation or deployment. Documents approved for publication by
+ the RFC Editor are not candidates for any level of Internet Standard;
+ see Section 2 of RFC 7841.
+
+ Information about the current status of this document, any errata,
+ and how to provide feedback on it may be obtained at
+ https://www.rfc-editor.org/info/rfc9187.
+
+Copyright Notice
+
+ Copyright (c) 2022 IETF Trust and the persons identified as the
+ document authors. All rights reserved.
+
+ This document is subject to BCP 78 and the IETF Trust's Legal
+ Provisions Relating to IETF Documents
+ (https://trustee.ietf.org/license-info) in effect on the date of
+ publication of this document. Please review these documents
+ carefully, as they describe your rights and restrictions with respect
+ to this document.
+
+Table of Contents
+
+ 1. Introduction
+ 2. Background
+ 3. Related Discussion
+ 4. Using SNE in Protocol Design
+ 5. Example Code
+ 6. Validation Suite
+ 7. Security Considerations
+ 8. IANA Considerations
+ 9. Informative References
+ Acknowledgments
+ Author's Address
+
+1. Introduction
+
+ Protocols use sequence numbers to maintain ordering and, in sliding
+ window systems, to control the amount of outstanding unacknowledged
+ information. These sequence numbers are finite and thus commonly
+ wrap around during long connections, reusing past values.
+
+ It can be useful for protocols to keep track of this wrap around in a
+ separate counter, such that the sequence number and counter together
+ form an equivalent number space that need not wrap. This technique
+ was introduced as "Sequence Number Extension" in the TCP
+ Authentication Option (TCP-AO) [RFC5925]. The example provided there
+ was intended to introduce the concept, but the pseudocode provided is
+ not complete.
+
+ This document presents the formal requirements for Sequence Number
+ Extension (SNE), a code example, and a check sequence that can be
+ used to validate this and alternate implementations. Sequence
+ numbers are used in a variety of protocols to support loss detection,
+ reordering, flow control, and congestion control. Limitations in the
+ size of a sequence number protocol field can limit the ways in which
+ these capabilities can be supported.
+
+ Under certain conditions, it is possible for both endpoints of a
+ protocol to keep track of sequence number rollover and effectively
+ extend the sequence number space without requiring modification of
+ the sequence number field used within protocol messages. These
+ conditions assume that the received sequence numbers never vary by
+ more than half the size of the space of the field used in messages,
+ i.e., they never hop forward or backward by more than half that
+ space. This constraint is typical in sliding window protocols, such
+ as TCP. However, although both ends can track rollover
+ unambiguously, doing so can be surprisingly complex. This document
+ provides examples and test cases to simplify that process.
+
+ This document is intended for protocol designers who seek to use
+ larger sequence numbers at the endpoints without needing to extend
+ the sequence number field used in messages, such as for
+ authentication protocols, e.g., TCP-AO [RFC5925]. Use of extended
+ sequence numbers should be part of a protocol specification so that
+ both endpoints can ensure they comply with the requirements needed to
+ enable their use in both locations.
+
+ The remainder of this document describes how SNE can be supported and
+ provides the pseudocode to demonstrate how received messages can
+ unambiguously determine the appropriate extension value, as long as
+ the reordering is constrained. Section 2 provides background on the
+ concept. Section 3 discusses currently known uses of SNE. Section 4
+ discusses how SNE is used in protocol design and how it differs from
+ in-band use of sequence numbers. Section 5 provides a framework for
+ testing SNE implementations, including example code for the SNE
+ function, and Section 6 provides a sequence that can be used by that
+ code for validation. Section 7 concludes with a discussion of
+ security issues.
+
+2. Background
+
+ Protocols use sequence numbers to maintain message order. The
+ transmitter typically increments them either once per message or by
+ the length of the message. The receiver uses them to reorder
+ messages and detect gaps due to inferred loss.
+
+ Sequence numbers are represented within those messages (e.g., in the
+ headers) as values of a finite, unsigned number space. This space is
+ typically represented in a fixed-length bit string, whose values
+ range from 0..(2^N)-1, inclusive.
+
+ The use of finite representations has repercussions on the use of
+ these values at both the transmitter and receiver. Without
+ additional constraints, when the number space "wraps around", it
+ would be impossible for the receiver to distinguish between the uses
+ of the same value.
+
+ As a consequence, additional constraints are required. Transmitters
+ are typically required to limit reuse until they can assume that
+ receivers would successfully differentiate the two uses of the same
+ value. The receiver always interprets values it sees based on the
+ assumption that successive values never differ by just under half the
+ number space. A receiver cannot detect an error in that sequence,
+ but it will incorrectly interpret numbers if reordering violates this
+ constraint.
+
+ The constraint requires that "forward" values advance the values by
+ less than half the sequence number space, ensuring that receivers
+ never experience a series of values that violate that rule.
+
+ We define a sequence space as follows:
+
+ * An unsigned integer within the range of 0..(2^N)-1, i.e., for N
+ bits.
+
+ * An operation that increments values in that space by K, where K <
+ 2^(N-1), i.e., less than half the range. This operation is used
+ exclusively by the transmitter.
+
+ * An operation that compares two values in that space to determine
+ their order, e.g., where X < Y implies that X comes before Y.
+
+ We assume that both sides begin with the same initial value, which
+ can be anywhere in the space. That value is either assumed (e.g., 0)
+ before the protocol begins or coordinated before other messages are
+ exchanged (as with TCP Initial Sequence Numbers (ISNs) [RFC0793]).
+ It is assumed that the receiver always receives values that are
+ always within (2^N)-1, but the successive received values never jump
+ forward or backward by more than 2^(N-1)-1, i.e., just under half the
+ range.
+
+ No other operations are supported. The transmitter is not permitted
+ to "backup", such that values are always used in "increment" order.
+ The receiver cannot experience loss or gaps larger than 2^(N-1)-1,
+ which is typically enforced either by assumption or by explicit
+ endpoint coordination.
+
+ An SNE is a separate number space that can be combined with the
+ sequence number to create a larger number space that need not wrap
+ around during a connection.
+
+ On the transmit side, SNE is trivially accomplished by incrementing a
+ local counter once each time the sequence number increment "wraps"
+ around or by keeping a larger local sequence number whose least-
+ significant part is the message sequence number and most-significant
+ part can be considered the SNE. The transmitter typically does not
+ need to maintain an SNE except when used in local computations, such
+ as for Message Authentication Codes (MACs) in TCP-AO [RFC5925].
+
+ The goal of this document is to demonstrate that SNE can be
+ accomplished on the receiver side without transmitting additional
+ information in messages. It defines the stateful function
+ compute_sne() as follows:
+
+ SNE = compute_sne(seqno)
+
+ The compute_sne() function accepts the sequence number seen in a
+ received message and computes the corresponding SNE. The function
+ includes persistent local state that tracks the largest currently
+ received SNE and seqno combination. The concatenation of SNE and
+ seqno emulates the equivalent larger sequence number space that can
+ avoid wrap around.
+
+ Note that the function defined here is capable of receiving any
+ series of seqno values and computing their correct corresponding SNE,
+ as long as the series never "jumps" more than half the number space
+ "backward" from the largest value seen "forward".
+
+3. Related Discussion
+
+ The DNS uses sequence numbers to determine when a Start of Authority
+ (SOA) serial number is more recent than a previous one, even
+ considering sequence space wrap [RFC1034][RFC1035]. The use of
+ wrapped sequence numbers for sliding windows in network protocols was
+ first described as a sequence number space [IEN74].
+
+ A more recent discussion describes this as "serial number arithmetic"
+ and defines a comparison operator it claimed was missing in IEN-74
+ [RFC1982]. That document defines two operations: addition
+ (presumably shifting the window forward) and comparison (defining the
+ order of two values). Addition is defined in that document as
+ limited to values within the range of 0..windowsize/2-1. Comparison
+ is defined in that document by a set of equations therein, but that
+ document does not provide a way for a receiver to compute the correct
+ equivalent SNE, especially including the potential for sequence
+ number reordering, as is demonstrated in this document.
+
+4. Using SNE in Protocol Design
+
+ As noted in the introduction, message sequence numbers enable
+ reordering, loss detection, flow control, and congestion control.
+ They are also used to differentiate otherwise potentially identical
+ messages that might repeat as part of a sequence or stream.
+
+ The size of the sequence number field used within transferred
+ messages defines the ability of a protocol to tolerate reordering and
+ gaps, notably limited to half the space of that field. For example,
+ a field of 8 bits can reorder and detect losses of smaller than 2^7,
+ i.e., 127 messages. When used for these purposes -- reordering, loss
+ detection, flow control, and congestion control -- the size of the
+ field defines the limits of those capabilities.
+
+ Sequence numbers are also used to differentiate messages; when used
+ this way, they can be problematic if they repeat for otherwise
+ identical messages. Protocols using sequence numbers tolerate that
+ repetition because they are aware of the rollover of these sequence
+ number spaces at both endpoints. In some cases, it can be useful to
+ track this rollover and use the rollover count as an extension to the
+ sequence number, e.g., to differentiate authentication MACs. This
+ SNE is never transmitted in messages; the existing rules of sequence
+ numbers ensure both ends can keep track unambiguously -- both for new
+ messages and reordered messages.
+
+ The constraints required to use SNE have already been presented as
+ background in Section 2. The transmitter must never send messages
+ out of sequence beyond half the range of the sequence number field
+ used in messages. A receiver uses this assumption to interpret
+ whether received numbers are part of pre-wrap sequences or post-wrap
+ sequences. Note that a receiver cannot enforce or detect if the
+ transmitter has violated these assumptions on its own; it relies on
+ explicit coordination to ensure this property is maintained, such as
+ the exchange of acknowledgements.
+
+ SNEs are intended for use when it is helpful for both ends to
+ unambiguously determine whether the sequence number in a message has
+ wrapped and whether a received message is pre-wrap or post-wrap for
+ each such wrap. This can be used by both endpoints to ensure all
+ messages of arbitrarily long sequences can be differentiated, e.g.,
+ ensuring unique MACs.
+
+ SNE does not extend the actual sequence space of a protocol or (thus)
+ its tolerance to reordering or gaps. It also cannot improve its
+ dynamic range for flow control or congestion control, although there
+ are other somewhat related methods that can, such as window scaling
+ [RFC7323] (which increases range at the expense of granularity).
+
+ SNE is not needed if messages are already unique over the entirety of
+ a transfer sequence, e.g., either because the sequence number field
+ used in its messages never wrap around or because other fields
+ provide that disambiguation, such as timestamps.
+
+5. Example Code
+
+ The following C code is provided as a verified example of SNE from 16
+ to 32 bits. The code includes both the framework used for validation
+ and the compute_sne() function, the latter of which can be used
+ operationally.
+
+ A correct test will indicate "OK" for each test. An incorrect test
+ will indicate "ERROR" where applicable.
+
+ <CODE BEGINS> file "compute_sne.c"
+ #include <stdio.h>
+ #include <sys/param.h>
+
+ #define distance(x,y) (((x)<(y))?((y)-(x)):((x)-(y)))
+
+ #define SNEDEBUG 1
+
+ // This is the core code, stand-alone, to compute SNE from seqno
+ // >> replace this function with your own code to test alternates
+ unsigned long compute_sne(unsigned long seqno) {
+ // INPUT: 32-bit unsigned sequence number (low bits)
+ // OUTPUT: 32-bit unsigned SNE (high bits)
+
+ // variables used in this code example to compute SNE:
+
+ static unsigned long
+ RCV_SNE = 0; // high-watermark SNE
+ static int
+ RCV_SNE_FLAG = 1; // set during first half rollover
+ // (prevents re-rollover)
+ static unsigned long
+ RCV_PREV_SEQ = 0; // high-watermark SEQ
+ unsigned long
+ holdSNE; // temp copy of output
+
+ holdSNE = RCV_SNE; // use current SNE to start
+ if (distance(seqno,RCV_PREV_SEQ) < 0x80000000) {
+ // both in same SNE range?
+ if ((seqno >= 0x80000000) && (RCV_PREV_SEQ < 0x80000000)) {
+ // jumps fwd over N/2?
+ RCV_SNE_FLAG = 0; // reset wrap increment flag
+ }
+ RCV_PREV_SEQ = MAX(seqno,RCV_PREV_SEQ);
+ // move prev forward if needed
+ } else {
+ // both in diff SNE ranges
+ if (seqno < 0x80000000) {
+ // jumps forward over zero?
+ RCV_PREV_SEQ = seqno; // update prev
+ if (RCV_SNE_FLAG == 0) {
+ // first jump over zero? (wrap)
+ RCV_SNE_FLAG = 1;
+ // set flag so we increment once
+ RCV_SNE = RCV_SNE + 1;
+ // increment window
+ holdSNE = RCV_SNE;
+ // use updated SNE value
+ }
+ } else {
+ // jump backward over zero
+ holdSNE = RCV_SNE - 1;
+ // use pre-rollover SNE value
+ }
+ }
+ #ifdef SNEDEBUG
+ fprintf(stderr,"state RCV_SNE_FLAG = %1d\n",
+ RCV_SNE_FLAG);
+ fprintf(stderr,"state RCV_SNE = %08lx\n", RCV_SNE);
+ fprintf(stderr,"state RCV_PREV_SEQ = %08lx\n", RCV_PREV_SEQ);
+ #endif
+ return holdSNE;
+ }
+
+ int main() {
+ // variables used as input and output:
+ unsigned long SEG_SEQ; // input - received SEQ
+ unsigned long SNE; // output - SNE corresponding
+ // to received SEQ
+
+ // variables used to validate the computed SNE:
+ unsigned long SEG_HIGH; // input - xmitter side SNE
+ // -> SNE should match this value
+ unsigned long long BIG_PREV; // prev 64-bit total seqno
+ unsigned long long BIG_THIS = 0; // current 64-bit total seqno
+ // -> THIS, PREV should never jump
+ // more than half the SEQ space
+
+ char *prompt = "Input hex numbers only (0x is optional)\n\n")
+ "\tHex input\n"
+ "\t(2 hex numbers separated by whitespace,"
+ "each with 8 or fewer digits)";
+
+ fprintf(stderr,"%s\n",prompt);
+
+ while (scanf("%lx %lx",&SEG_HIGH,&SEG_SEQ) == 2) {
+ BIG_PREV = BIG_THIS;
+ BIG_THIS = (((unsigned long long)SEG_HIGH) << 32)
+ | ((unsigned long long)SEG_SEQ);
+
+ // given SEG_SEQ, compute SNE
+ SNE = compute_sne(SEG_SEQ);
+
+ fprintf(stderr," SEG_SEQ = %08lx\n", SEG_SEQ);
+ fprintf(stderr," SNE = %08lx\n", SNE);
+ fprintf(stderr," SEG_HIGH = %08lx %s\n",SEG_HIGH,
+ (SEG_HIGH == SNE)? " - OK" : " - ERROR !!!!!!!");
+ fprintf(stderr,"\t\tthe jump was %16llx %s %s\n",
+ distance(BIG_PREV,BIG_THIS),
+ ((BIG_PREV < BIG_THIS)?"+":"-"),
+ (((distance(BIG_PREV,BIG_THIS)) > 0x7FFFFFFF)
+ ? "ILLEGAL JUMP" : "."));
+ fprintf(stderr,"\n");
+ fprintf(stderr,"\n");
+
+ fprintf(stderr,"%s\n",prompt);
+
+ }
+ }
+ <CODE ENDS>
+
+6. Validation Suite
+
+ The following numbers are used to validate SNE variants and are shown
+ in the order they legitimately could be received. Each line
+ represents a single 64-bit number, represented as two hexadecimal
+ 32-bit numbers with a space between. The numbers are formatted for
+ use in the example code provided in Section 5.
+
+ A correctly operating extended sequence number system can receive the
+ least-significant half (the right side) and compute the correct most-
+ significant half (the left side) correctly. It specifically tests
+ both forward and backward jumps in received values that represent
+ legitimate reordering.
+
+ 00000000 00000000
+ 00000000 30000000
+ 00000000 90000000
+ 00000000 70000000
+ 00000000 a0000000
+ 00000001 00000001
+ 00000000 e0000000
+ 00000001 00000000
+ 00000001 7fffffff
+ 00000001 00000000
+ 00000001 50000000
+ 00000001 80000000
+ 00000001 00000001
+ 00000001 40000000
+ 00000001 90000000
+ 00000001 b0000000
+ 00000002 0fffffff
+ 00000002 20000000
+ 00000002 90000000
+ 00000002 70000000
+ 00000002 A0000000
+ 00000003 00004000
+ 00000002 D0000000
+ 00000003 20000000
+ 00000003 90000000
+ 00000003 70000000
+ 00000003 A0000000
+ 00000004 00004000
+ 00000003 D0000000
+
+7. Security Considerations
+
+ Sequence numbers and their extensions can be useful in a variety of
+ security contexts. Because the extension part (most-significant
+ half) is determined by the previously exchanged sequence values
+ (least-significant half), the extension should not be considered as
+ adding entropy for the purposes of message authentication or
+ encryption.
+
+8. IANA Considerations
+
+ This document has no IANA actions.
+
+9. Informative References
+
+ [IEN74] Plummmer, W., "Sequence Number Arithmetic", IEN-74,
+ September 1978.
+
+ [RFC0793] Postel, J., "Transmission Control Protocol", STD 7,
+ RFC 793, DOI 10.17487/RFC0793, September 1981,
+ <https://www.rfc-editor.org/info/rfc793>.
+
+ [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",
+ STD 13, RFC 1034, DOI 10.17487/RFC1034, November 1987,
+ <https://www.rfc-editor.org/info/rfc1034>.
+
+ [RFC1035] Mockapetris, P., "Domain names - implementation and
+ specification", STD 13, RFC 1035, DOI 10.17487/RFC1035,
+ November 1987, <https://www.rfc-editor.org/info/rfc1035>.
+
+ [RFC1982] Elz, R. and R. Bush, "Serial Number Arithmetic", RFC 1982,
+ DOI 10.17487/RFC1982, August 1996,
+ <https://www.rfc-editor.org/info/rfc1982>.
+
+ [RFC5925] Touch, J., Mankin, A., and R. Bonica, "The TCP
+ Authentication Option", RFC 5925, DOI 10.17487/RFC5925,
+ June 2010, <https://www.rfc-editor.org/info/rfc5925>.
+
+ [RFC7323] Borman, D., Braden, B., Jacobson, V., and R.
+ Scheffenegger, Ed., "TCP Extensions for High Performance",
+ RFC 7323, DOI 10.17487/RFC7323, September 2014,
+ <https://www.rfc-editor.org/info/rfc7323>.
+
+Acknowledgments
+
+ The need for this document was first noted by Juhamatti Kuusisaari in
+ April 2020 during discussions of the pseudocode in RFC 5925.
+
+Author's Address
+
+ Joe Touch
+ Manhattan Beach, CA 90266
+ United States of America
+
+ Phone: +1 (310) 560-0334
+ Email: touch@strayalpha.com