[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Part Two: IPv4 Options We Can't Handle




	I have heard several statements on this issue that I disagree
with, and now I have working (well, mostly ;) code that I can use to back
up my disagreement. 

	The first thing I've heard that I disagree with is that we should
not include IPv4 options in the IPv4 authentication computation. There are
two main reasons given:

	1. If we get an option that we can't process, we must ignore
		it (RFC1122). If we can't process it, though, we don't
		know whether the fields are invariant, so we might be
		dropping the packet solely because we can't process
		the option, which conflicts with RFC1122.

	2. Routers might insert, remove, or re-order options.

	I will discuss the latter one first. When routers mess with the
options attached to the packet, you are guaranteeing that the packet does
not have intermediate authenticity because the packet at some points along
its path of travel is not the same as the packet as sent by the sender.
Therefore, whenever routers modify the packet in any way other than the
modification of specific variant fields, you do not have intermediate
authenticity anymore at some or all points along your path. In the
context of my second example, C may legitimately insert an IPSO option,
but if E or F is the router stripping that option and restoring the packet,
the packet will not have intermediate authenticity at D because the packet
is not what A sent or what A intends B to receive.

	However, end-to-end authenticity guarantees are not mutually
exclusive with routers that modify options *as long as they put things
back the way they found them somewhere along the line*. In the context of my
second example, C may legitimately insert an IPSO option so long as D, E, or
F removes it and restores the packet to its original form. As long as it
does, B will see the packet as A intended it to be seen, and it is therefore
end-to-end authentic. If C inserts the IPSO option and no router removes it,
the packet at B is not end-to-end authentic because the packet at B is not
what A sent or intended B to see. It is important that the AH verification
procedure fail in this case exactly because the packet has been modified
in transit. AH has no concept of good or bad modifications, but it has a
strict concept of authenticity. This packet is not authentic because it has
been modified.

	One of our resident experts on routers that insert, examine, and remove
IPSO options into IPv4 packets tells me that "no known router ships configured
to perform IPSO modifications and that such modifications only happen if the
router admin actively configures the router to do so. Further, IPSO
modifications are directly security-relevant -- we do want packets with
intermediate IPSO modifications to fail end-to-end authenticity checks".

	Now to discuss the first problem. A number of interpretations of
RFC1122 have been posted in this discussion, but I would like to work from
what RFC1122 says about options you can't process:

	"The IP and transport layer MUST each interpret those IP
	 options that they understand and silently ignore the
	 others."

	The problem here is one of how we can determine whether fields of
an option are variant or not. I think that we all can agree that if we know
how to handle an option, we can presumably get some sort of consensus on what
is and isn't variant and implement that. So the question is really what
"silently ignore" means. The reason I quote the text here is because most
people have substituted the word "skip" for "silently ignore" and operated
with the assumption that this is the only legitimate interpretation. I
disagree. Consider transport headers and transport data. They're not network-
level, we have no right at the AH level to mess with them. What do we do with
them for AH computation? We run the cryptographic checksum straight over them
with no variance substitutions. Therefore, I believe that a reasonable
definition of "ignore" is also to simply run the cryptographic checksum 
straight over the options we can't handle with no variance substitutions.
Another possibility, which I don't recommend, is to zero out the options
we can't process except for their type and length fields (more on this
later).

	There are three classes of unknown options for purposes of
evaluating which definition of "silently ignore" is most reasonable.
The first are unpredictably variant options. For example, the timestamp
option. The second are invariant options. For example, the IPSO option.
The third are predictably-variant options. For example, the SSRR option.

	Fifth assertion: If both sides cannot process an option and both
sides do the same thing in cases of unknown options (either skip/omit,
zero, or blind-hash), all three methods will work. Only in the last
case, however, will the contents of the option be protected from
modification in transit. In this case, the best option is a blind-hash.

	Now we have the case, which I consider more common and more
interesting, where one side does not know how to process the option
but the other does. If you "skip over" (omit from computation) options
you can't handle, you lose for all three cases because the side that
does know how to process the option will include data, some of which
may be zeroed out, from the option at that position in its computation.

	If you zero out options you can't process except for the type and
length, you win for fields of the first class. In the case of the second class,
the field will be hashed blindly as its value, and you will lose if its value
doesn't happen to be zero. In the case of the third class, the field has a
value that is computed for authentication to match what it would look like at
the receiver -- if it doesn't happen that the value should be zero, you lose.

	If you blindly hash options you can't process, you lose for the
first class unless the values you blindly hash happen to be zero. You never
lose in the second class. You lose in the third class unless you are the
receiver, in which case the values you see and hash are also what you're
supposed to see at the receiver (because you ARE the receiver).

	Skipping over the options you can't process is clearly bad to me
because you always lose if one of the ends can process the option.
Coincidental zeros aside, you lose in two of the three cases if you
zero out the fields other than type and length. Coincidental zeros aside,
you lose in one case all the time and another if you are not the
receiver if you blindly hash the options you can't process.

	Sixth assertion: Blindly hashing the value gives you clearly better
security if both sides can't process an option and slightly better
security if one side can't process an option. It also provides for a simpler
implementation versus hashing the type and length and zeroing the rest,
which would otherwise be the next best way to handle the problem of IPv4
options you can't process.

	For purposes of processing IPv4 options when you don't know how,
keep in mind this statement from RFC1122: "For this purpose, every IP option
except NOP and END-OF-LIST will include a specification of its own length."
RFC791 says that there are two forms an IPv4 option can take: "Case 1: a
single octet of option-type. Case 2: An option-type octet, an option-length
octet, and the actual option-data octets.". 

	Seventh assertion: There are no options of case 1 that make sense
other than NOP and END-OF-LIST, which all non-brain-damaged systems can
handle. Therefore, all options that you do not know how to process will be
of case 2, and you can therefore determine the length of options you can't
handle. This allows you to get back on track when an unknown option is
followed by a known option.

	You're walking with a safety-net here -- in the event that this
assertion is not true, you will eventually either run into an option that
looks legitimate or come into a situation where you are out of option data.

	Eighth assertion: If you encounter an out-of-option-data situation
or encounter the END-OF-LIST option with more data between it and the end
of the option space data (the IP header length with the size of the base IP
header subtracted), you treat all offending data as an unknown option and,
therefore, you blindly hash it. 

	If you run into, for instance, a source route, and that source route's
length points outside the option space data length (computed as
aforementioned), something is wrong with the source route and you can't process
it properly. If you know with certainty that the option is bad, immediately
drop the packet. There is no point in computing the hash over a known-bogus
packet and/or passing it on to the next hop. 

	Padding between the END-OF-LIST option and the end of option space data
"is zero" [RFC791]. This data should be blind-hashed.