Subject: [Hipsec] Issue #5: state machine bug

From: [email-masked] (Henderson, Thomas R)
Date: Wed Dec 10 11:29:00 2003

> -----Original Message-----
> From: Julien Laganier [mailto:[email-masked]]
> Sent: Tuesday, December 09, 2003 7:32 AM
> To: HIPsec
> Subject: [Hipsec] Issue #5: state machine bug
>=20
>=20
> Folks,
>=20
> Getting back to issue #5, I've tried to add a new substate to=20
> the state=20
> machine (E4-resync) to be able to receive R2 when the=20
> corresponent node=20
> rebooted and send R1 in reply to an ESP packet with unknown=20
> SPI. I also=20
> renamed E4 in E4-rekey to avoid creating to much substates,=20
> as per Pekka's=20
> suggestion. Let's try to describe the approach:

Before spending too much time resolving this, I would like
to raise the discussion again of why we are sending R1s.

i) it has been stated that IPsec has made a conscious=20
decision not to respond to unknown received SPIs by
rekeying.  Why do we do something different with HIP?  This
implies that we are needing a little more than BEET mode
in the IPsec implementations.

ii) if we decide to respond to unknown SPIs, how do we
know whether the SPI corresponds to a HIP or an IKE SA
if both daemons are running?  This is why I would vote
for maintaining alignment with IPsec current practice.
(is reboot that frequent that we need to optimize for it?
my experience is that reboot typically kills the=20
application that was using the socket anyway)

iii) if, however, we decide to respond, why respond with
an R1?  Why not an I1 or a new packet type (see below)?

I also have a few more suggestions for consideration:

iv) Julien's state diagram has started us down the path of
appending meaningful names to the state shorthand notation
(e.g. E4-rekey).  The next logical step might be to
drop the prefix "E#" since it doesn't convey much meaning
to the reader (especially the new reader).

Old name	New name
--------	--------
E0		START (or UNASSOCIATED or CLOSED)
E1      	INIT1=09
E2       	INIT2
E3     	ESTABLISHED (or ACTIVE or ASSOCIATED)
E4-rekey	REKEYING
E4-resync	RESYNC
E-FAILED	(do we even need this?)

v) I have often found that overloading packet types
to serve multiple purposes leads to ambiguity.  In this case,
we should consider an explicit packet type for RESYNC if
that is what we decide to do (actually, we could reuse
I1 or R1 type but set a control bit that explicitly says
"I am trying to resync with you").  Whether it is a new
packet type or a control bit is not the main issue-- it
is rather trying to remove guesswork from the packet
processing logic.

---

From: [email-masked] (Petri Jokela)
Date: Fri Dec 12 01:55:02 2003

> an R1?  Why not an I1 or a new packet type (see below)?

A question related to sending the R1 when an unknown SPI is received:

If A and B have an established connection between them (both in E3 
state). Now, our attacker, C, decides to send a fake packet with unknown 
SPI to the A using B's source IP address. What will the A host do?

A sends R1 to B, while the A-B connection still remains in the E3 state 
(the sent R1 doesn't have any effect on this). However, B gets an R1 
packet and thinks that A has lost the state, maybe rebooted. It starts 
calculating and finally sends back the I2 packet and moves to state 
E4-resync.

If A sends traffic using the old SA, the B will come back to E3 when 
traffic is received from the old SA (and just forget the new SA). If the 
A does not send traffic, the B remains in E4-resync.

The A receives the I2 packet related to the SA (it can now be mapped 
using the received HIT), it generates a new SA and sends R2 back to the 
B. B receives R2 and generates a new SA.

Now, C has initiated a negotiation between A and B resulting in a new 
SA. If the B is a server (with a thousand connections) and C manages to 
generate a negotiation between clients and the server, the server has 
some calculations to do. And, in fact, the server acts now as the 
Initiator for all those connections thus getting most of the calculation 
work.

Am I missing something or is the automatic R1 sending really a bad idea?

/petri

-- 
Petri Jokela                        Tel:    +358 9 299 2413
Research scientist                  Fax:    +358 9 299 3535
NomadicLab, Ericsson Research       Mobile: +358 44 299 2413
Oy L M Ericsson Ab                  email: [email-masked]

---

From: [email-masked] (Pekka Nikander)
Date: Fri Dec 12 03:15:02 2003

> i) it has been stated that IPsec has made a conscious
> rekeying.  Why do we do something different with HIP?

I don't really know all the reasons Bob had this.

There is one architectural issue, though.  In a way, HIP can
be considered to be part of the "IP substrate" from the
transport protocol point of view.  That is, there will often
be HIP state between a pair of hosts even if there are no
active transport associations.  On the flip side, whenever you
open a transport association, you must first establish HIP
state.  Hence, if there is still ongoing traffic, it might
make sense to recreate HIP state as soon as possible, if
for no other reason then to generate a (secure) TCP RST.

> if both daemons are running?

As you imply, we don't.  OTOH, sending severely rate limited
RESYNCH packets is not necessarily that bad.  If the peer
is an IKE-only peer, it will just drop them.

> an R1?  Why not an I1 or a new packet type (see below)?

I agree that a new packet type would most probably be best.
That avoids the ambiguity you are referring to.

> to the reader (especially the new reader).

Let's do this.

> Old name	New name

I like UNASSOCIATED.

> E1      	INIT1	

I1-SENT?

> E2       	INIT2

I2-SENT?

> E3     	ESTABLISHED (or ACTIVE or ASSOCIATED)

I like ESTABLISHED.

> E4-resync	RESYNC

Ok.

> E-FAILED	(do we even need this?)

Conceptually, yes.  In real life, you probably want to delay
in the FAILED state, generating canned ICMP host unreachable
packets to the upper layer protocols, before trying again.

It would be good to have an appendix on this.  Any takers?

> that is what we decide to do.

While I agree with you in this specific case, i.e. that we
need to make a distinction between R1 and RESYNC(H),
I would be more cautious about the generic comment.

We have to remember that we are developing a new piece of
very fundamental architecture here.  (Or at least we think
that we are doing that :-)  Hence, we really do not know
what people will like to use our technology for.  Consequently,
it makes sense to design the technology so that

   - the mechanisms are as simple as feasible

but at the same time

   - the mechanisms are as generic and extensible as feasible

Much of the difficulty goes into finding the (golden) balance
between these two extremes.  That is, while we want to make
very simple design, we do not want to nail down the protocol
so that it is impossible to extend it later on.  From the other
extreme point of view, while we want to have generic and
extensible mechanisms, we do not want the mechanism to become
complex just because of generality or extensibility.

IMHO, the current extension mechanism is a fairly good compromise.
It is reasonably simple, but still offers quite a lot of generality
and extensibility.  The forthcoming revised mobility and multi-
homing draft will be an example of how this extensibility could
be utilized.

--Pekka Nikander