Draft: draft-ietf-quic-load-balancers

Commentary: Attempt to , . Examples and test vectors not yet updated . PTAL at the description . Is the algorithm accurately described Are things clearer or not 
 Thanks for all the formatting suggestions . It 's cleaned up a bit , although I was n't able to get aasvg to work . PTAL 
 Correction . I got aasvg to work but it did not look good at all , probably due to user incompetence . If you would like to submit a PR after this that is prettier , I would welcome it . 
   points out this problem with the 4 - pass method : Indeed , there are ways to avoid ugly and error - prone bit shifting while avoiding this property . In particular , we can always use expand - left , but just padding odd - bytes with zeros to preserve byte boundaries and avoid bit - shifting . 
 Fixed by 
 Several problems here : A lot of the description relies on examples rather than normative language . The split of a CID that has an odd length produces HEX sequences with an odd number of characters , which in many circumstances will be interpreted as being ( left-)padded with 4 zero bits . If that happened , then bad things would occur . You really need to retain the number of bits . Step 3 passes two arguments to , when it has three . The encryption does n't bind to the configuration that is in use ; instead the high bits of the first octet are set to 0 . The formatting of the operations wraps awkwardly . The operators that this uses ( ^ and primarily ) are n't defined . The third input to seems to increment without explanation . Given the examples , I could no doubt work this all out satisfactorily , but that should n't be necessary . 
 Fixed by 
 A lot . 
 Yes , the new text seems clear , and correct .
The expand_left() function outputs 16 octets, with its first argument
in the most significant bits, its second argument in the least
significant byte, its third argument in the second least significant
byte, and zeros in all other positions.  Thus,
expand_right() is similar, except that the second argument is in the
most significant byte, the third is in the second most significant
byte, and the first argument is in the least significant bits.
Therefore,
The server concatenates the server ID and nonce to create
plaintext_CID.
The server splits plaintext_CID into components left_0 and right_0
of equal length, splitting an odd octet in half if necessary.  For
example, 0x7040b81b55ccf3 would split into a left_0 of 0x7040b81
and right_0 of 0xb55ccf3.
Encrypt the result of expand_left(left_0, index)) to obtain a
ciphertext, where 'index' is one octet: the two most significant
bits of which are 0b00, and the six least significant bits are the
length of the resulting connection ID in bytes, cid_len.
XOR the least significant bits of the ciphertext with right_0 to
form right_1.
Repeat steps 3 and 4, but use them to compute left_1 by expanding
and encrypting right_1 with the most significant octet as the
concatenation of 0b01 and cid_len, and XOR the results with
left_0.
Repeat steps 3 and 4, but use them to compute right_2 by expanding
and encrypting left_1 with the least significant octet as the
concatenation of 0b10 and cid_len, and XOR the results with
right_1.
Repeat steps 3 and 4, but use them to compute left_2 by expanding
and encrypting right_2 with the most significant octet as the
concatenation of 0b11 ands cid_len, and XOR the results with
left_1.
The server concatenates left_2 with right_2 to form the ciphertext
CID, which it appends to the first octet.
When configured with both a key, and a nonce length and server ID
length that sum to any number other than 16, the server MUST follow
the algorith below to encrypt the connection ID.
The 4-pass algorithm is a four-round Feistel Network with the round
function being AES-ECB.  Most modern applications of Feistel Networks
have more than four rounds.  The implications of this choice, which
is meant to limit the per-packet compute overhead at load balancers,
are discussed in distinguishing-attacks.
The server concatenates the server ID and nonce into a single field,
which is then split into equal halves.  In successive passes, one of
these halves is expanded into a 16B plaintext, encrypted with AES-
ECB, and the result XORed with the other half.  The diagram below
shows the conceptual processing of a plaintext server ID and nonce
into a connection ID.  'FO' stands for 'First Octet'.
The expand(length, pass, input_bytes) function concatenates three
arguments and outputs 16 zero-padded octets.
The first argument 'length' is an 8-bit integer that reports the sum
of the configured nonce length and server id length in octets, and
forms the most significant octet of the output.  The 'length'
argument MUST NOT exceed 28.
The second argument is an 8-bit integer that is the 'pass' of the
algorithm, and forms the second-most significant octet of the output.
The third argument is a variable-length stream of octets, which is
copied into the third-most significant octet of the output and
beyond.  The length of this octet stream is half the 'length',
rounded up.  All remaining octets of the output are zero.
For example,
Similarly, truncate(input, n) returns the first n octets of 'input'.
Let 'half_len' be equal to 'plaintext_len' / 2, rounded up.
The server concatenates the server ID and nonce to create
plaintext_CID.  The length of the result in octets is
plaintext_len.
The server splits plaintext_CID into components left_0 and right_0
of equal length half_len.  If plaintext_len is odd, right_0 clears
its first four bits, and left_0 clears its last four bits.  For
example, 0x7040b81b55ccf3 would split into a left_0 of 0x7040b810
and right_0 of 0x0b55ccf3.
Encrypt the result of expand(plaintext_len, 1, left_0) using an
AES-ECB-128 cipher to obtain a ciphertext.
If the plaintext_len is odd, clear the first four bits of right_1.
Repeat steps 3 and 4, but use them to compute left_1 by expanding
and encrypting right_1 with pass = 2, and XOR the results with
left_0.
If the plaintext_len is odd, clear the last four bits of left_1.
Repeat steps 3 and 4, but use them to compute right_2 by expanding
and encrypting left_1 with pass = 3, and XOR the results with
right_1.
If the plaintext_len is odd, clear the first four bits of right_2.
Repeat steps 3 and 4, but use them to compute left_2 by expanding
and encrypting right_2 with pass = 4, and XOR the results with
left_1.
If the plaintext_len is odd, clear the last four bits of left_2.
The server concatenates left_2 with right_2 to form the ciphertext
CID, which it appends to the first octet.  If plaintext_len is
odd, the four least significant bits of left_2 and four most
significant bits of right_2, which are all zero, are stripped off
before concatenation to make the resulting ciphertext the same
length as the original plaintext.