Skip to main content

Last Call Review of draft-ietf-tsvwg-port-randomization-
review-ietf-tsvwg-port-randomization-secdir-lc-kaufman-2010-03-03-00

Request Review of draft-ietf-tsvwg-port-randomization
Requested revision No specific revision (document currently at 09)
Type Last Call Review
Team Security Area Directorate (secdir)
Deadline 2010-03-02
Requested 2010-02-20
Authors Michael Larsen , Fernando Gont
Draft last updated 2010-03-03
Completed reviews Secdir Last Call review of -?? by Charlie Kaufman
Assignment Reviewer Charlie Kaufman
State Completed
Review review-ietf-tsvwg-port-randomization-secdir-lc-kaufman-2010-03-03
Completed 2010-03-03
review-ietf-tsvwg-port-randomization-secdir-lc-kaufman-2010-03-03-00
I am reviewing this document as part of the security directorate's ongoing
effort to review all IETF documents being processed by the IESG.  These
comments were written primarily for the benefit of the security area directors.
 Document editors and WG chairs should treat these comments just like any other
last call comments. Feel free to forward to any appropriate forum.

This document (targeting BCP status) describes an obscure but important
practice regarding the selection of ephemeral port IDs when creating TCP
connections. If an attacker can guess the ephemeral port used by a TCP
connection between some pair of nodes, it greatly increases the chances he can
corrupt the data being passed over that connection or cause the connection to
break. To make such an attack harder, the originators of TCP connections should
pick the ephemeral port number randomly (or at least unpredictably) from a
large set of available ports.

For some arcane reasons, picking ports strictly randomly is not the best you
can do, because some choices don't work out. If you pick a port number that has
used for a recently closed TCP connection to the same IP address, the other end
might become confused, think that the old connection is continuing, and
generally mess things up. (Most applications will eventually sort themselves
out after some timeouts and retries, but it is not guaranteed). Another
possible problem is that if someone starts listening on the port you selected
and the timing is "just wrong", you connection could become confused with one
of his.

These problems can be almost certainly avoided by picking ports from a
particular narrow range and picking them in sequence so that no port number is
reused until all have been used once. Unfortunately, doing that increases the
chance that an attacker can predict the port some new connection will choose.

This document describes how various implementations trade-off these two
conflicting goals, and makes recommendations as to how a new implementation
might pick an algorithm.

Unfortunately, this algorithm is a cryptographers dream with lots of
opportunities to make micro-optimizations. I could not resist the temptation to
do so myself when reading the document, but I *can* resist the temptation to
tell anyone about the resulting algorithm. There are only 64K ports, so nothing
anyone can do is going to make a cryptographically significant improvement over
the proposals made here, and spending time debating whether my algorithm beats
your algorithm is a waste of everyone's time.

Detailed security-relevant comments:

p13 para 2: says random must return integers in the range 0 - (2^n-1) where
n>15. Larger values of n (e.g. n=31) are preferred, since otherwise
distribution when reduced mod num_ephemeral will not be uniform.

p16 para 2: suggests use of MD5, which is fine from the point of view of
documenting current practice, and in fact is cryptographically just fine in
this context. Nevertheless, crypto weenies the world over will pounce on you if
it looks like you're suggesting that people use it. It's probably better to
just suggest "some cryptographic hash function", or if you have to suggest
something specific, perhaps SHA-256. The appendix at the end should specify the
hash algorithm used by existing implementations.

Your sample code in many cases, but in particular on page 17 figure 5 ignores
the possibility of integer overflow when incrementing things (e.g.
table[index]++). The results of modular arithmetic when one of the operands is
negative is language dependent, and in ANSI C is not defined, so this code
could corrupt memory (unless the values being incremented are unsigned).

p20 para 2: suggests use of a 32 bit key, which has exploitable security
problems even though MD5 is fine. 64 bits is a bare minimum, and since bits are
cheap someone should really use 128.

p20 last 2 lines: use of pseudo-random data is never harmful and might help, so
"should not be done" seems a little strong.

p24 para 3: Since the local offset function is a cryptographic hash reduced to
a small number of bits, there will be identical offsets for different inputs
and they are generally harmless. If they occurred at greater frequency than
would be expected by chance, the port-offset mechanism proposed in this
document would have a reduced effect.

p24 para 4: Similarly, seeding the random number generator with a good  source
of randomness will make an implementation more secure, but "must" is a bit
strong.

Detailed non-security relevant comments:

The document is titled "Transport Protocol Port Randomization Recommendations",
but it doesn't really make recommendations. It enumerates current practice and
calls out the pros and cons, but it doesn't really recommend what an
implementer should do. That's probably OK, but it seemed a bit odd.

p6 last para section 1: Given that this document never uses SHOULD, MUST, ...
outside of this paragraph, does it really need this paragraph and the reference
to RFC 2119?

p7 end of section 2.1 says ports in the range 49152-65535 are meant for the
selection of ephemeral ports p12 1st para says:  "ephemeral port selection
algorithms should use the whole range 1024-49151". Is this saying you should
use port numbers not intended for this use? Do you mean should use the whole
range 1024-65535?

Typos:

p12 line 2: "is not affected is not affected" -> "is not affected"
p13 para 2 line 2: "interger" -> "integer"
p16 para 3: "chosen as random as possible" -> "chosen to be as random as
possible" p20 para 3: "reasonable" -> "reasonably"

        --Charlie