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

Bundles (in Kernel)



When I started to read the IPSEC architecture, I had some difficulties
to understand how the bundle thing would work, especially the receive
side was a bit problematic. But, I went on and coded here and there,
building parts of IPSEC one at time, and now I think I have all done.

But, I notice that my choices lead to simple looking implementation,
which does not quite match the description in architecture document
(5.1.1 and 5.2.1). However, my belief (or hope) is that actually "on
the wire" my choice is the same.

I like impelemting "orthogonally", writing simple automaton which does
some basic steps, without giving any concern about the sensibility of
the combinations. In my view it is a higher level issue to decide what
use they put this machinery. Thus, what I have done, will send and
accept whatever combination of ESP/AH/Tunnel one wishes to specify
with the policy. And I don't see why anyone would want to do this
differently.

Totally another issue is, that one could have an optimized
IPCOMP+ESP/AH routine, which is called if this or some other common
pecific combination is detected. It does not change this underlying
"virtual reference implementation", where everything can be done
individually (which is what I have been worrying all along:
optimizations should not cause limitations to the base standard).

The rest of this, tries to describe my implementation (SA bundling
issue part). I do not claim it implements the spirit of IPSEC
architecture, but I do hope it produces correct things happening "on
the wire". If there are potential problems with this implementation, I
am greatful for anyone pointing the pitfalls and errors I have
created, so that I can really write a conforming implementation.

Differences in outgoing (5.1.1)
-------------------------------

	1. Match the packet's selector fields against the outbound
	   policies in the SPD to locate the first appropriate policy,
	   which will point to zero or more SA bundles in the SAD.

Logically no differences, but my selectors don't point to real SA's.
Instead, each selector is attached to list of SA descriptions
(templates) which specify the required operations (AH/ESP, algorithms,
replay window length, etc.)

	2. Match the packet's selector fields against those in the SA
	   bundles found in (1) to locate the first SA bundle that
	   matches.  If no SAs were found or none match, create an
	   appropriate SA bundle and link the SPD entry to the SAD
	   entry.  If no key management entity is found, drop the
	   packet.

Here is rather radical(?) difference: as my selector doesn't point to
real SA bundles. This is what I do:

process the each descriptor in the bundle in order

  a) search SA combining the data from the descriptor and the packet
     (src/dst/protocol etc.) under study (descriptor has flags which
     tell whether SA should match various data, such as
     src/protocol/connection etc., setting these flags is part of the
     policy design)
  b) if SA not found, generate ACQUIRE message (if not already done
     earlier), and proceed to the next description
  c) if SA found, apply the tranformation to the packet. (the
     desctiption may have contained a tunnel address, if so, the
     tunnel transformation is applied first, and only then the AH or
     ESP.

After all descriptors, if any of them failed on (b), drop
packet. Actually, after first (b), I will also skip (c), and loop only
to generate all ACQUIRE messages at one packet.

	3. Use the SA bundle found/created in (2) to do the required
	   IPsec processing, e.g., authenticate and encrypt.

Well, this already got done on previous step.

Differences on incoming (5.2.1)
-------------------------------

Here I have outer loop which runs while there are ESP or AH as a
protocol in the IP packet. For each I do step 1 and 2 from 5.2.1

	1. Use the packet's destination address (outer IP header),
	   IPsec protocol, and SPI to look up the SA in the SAD.  If
	   the SA lookup fails, drop the packet and log/report the
	   error.

Above step 1 is pretty much the same, but next has some major
differences in organization:

	2. Use the SA found in (1) to do the IPsec processing, e.g.,
	   authenticate and decrypt. This step includes matching the
	   packet's (Inner Header if tunneled) selectors to the
	   selectors in the SA.  Local policy determines the
	   specificity of the SA selectors (single value, list, range,
	   wildcard). In general, a packet's source address MUST match
	   the SA selector value. However, an ICMP packet received on
	   a tunnel mode SA may have a source address other than that
	   bound to the SA and thus such packets should be permitted
	   as exceptions to this check.  For an ICMP packet, the
	   selectors from the enclosed problem packet (the source and
	   destination addresses and ports should be swapped) should
	   be checked against the selectors for the SA.  Note that
	   some or all of these selectors may be inaccessible because
	   of limitations on how many bits of the problem packet the
	   ICMP packet is allowed to carry or due to encryption.

My step 2 is much simpler
   a) use the SA found in (1) to do the IPsec processing. (drop packet
      on any error)
   b) if "uncovered" IPIP protocol (this is a tunnel), then process it
      too (unwrap layer of IP).
   c) remember SA and the tunnel address, if it was present

Now I have an IP packet without IPsec layers, this is what I apply to
architecture step 3:

	3. Find an incoming policy in the SPD that matches the packet.
	   This could be done, for example, by use of backpointers
	   from the SAs to the SPD or by matching the packet's
	   selectors (Inner Header if tunneled) against those of the
	   policy entries in the SPD.

...with a difference (I don't have real SA's in policy, nor I see
possibility to use backpointers): I just use the same routine that I
use with outgoing packet to locate the bundle template from SPD (one
may have different SPD lists for in and out, but the search is
same). Also, note that I don't need any wording abot inner/outer
headers at any stage, I just always use what I have at hand in the
packet.

After I have the bundle description, ...

	4. Check whether the required IPsec processing has been
	   applied, i.e., verify that the SA's found in (1) and (2)
	   match the kind and order of SAs required by the policy
	   found in (3).

I loop over each descriptor of the bundle, and as with outgoing
processing, I search for SA combining the data from the descriptor and
the packet (src/dst/protocol etc.) under study (again the same routine
is used). If SA is not found or does not match the SA used in the step
2, or the the tunnel does not match, then drop the packet as invalid
(basicly, non-matching policies, or someone trying to sneak in with
less or different security than policy says). Naturally SA's from step
2 must be in same order (in reality reversed in my implementation) as
the bundle list.

	   NOTE: The correct "matching" policy will not necessarily be
	   the first inbound policy found.  If the check in (4) fails,
	   steps (3) and (4) are repeated until all policy entries
	   have been checked or until the check succeeds.

This is a mystery to me at this point. When using my version of the
implementation, when would this NOTE apply, if ever? I would really
prefer *not* to search more.

regards,
-- 
Markku Savela (msa@hemuli.tte.vtt.fi), Technical Research Centre of Finland
Multimedia Systems, P.O.Box 1203,FIN-02044 VTT,http://www.vtt.fi/tte/staff/msa/