Does someone know why these IPsec SAs are unidirectional? Usually the
RFC describes some reasoning behind certain design decisions. However, I
can't seem to find a justification other than "It's by design". On the
Internet however, I read that the two SA requirement is chosen from a
security perspective; If the key material of one of the SAs leaks, only
one way of the traffic can be inspected by a third party. The problem
with this reasoning is that I can't seem to find an additional source
claiming the same thing. Therefore, I'm not sure whether it's true.
I like this question :) so I apologize for a lengthy response. Or, let's give you a tl;dr version: for key separation and refresh, mainly for security considerations.
So:
- The _keys_ used in both directions should (preferably) be different, for security. You mentioned one reason, i.e., that the if one of them leaks, the other one will remain secure; I guess that's true, although one may wonder about the scenarios in which only one of the two leaks, as they are used in same devices. A more relevant reason imho is that it may be easier to expose one of the two keys using cryptanalysis, e..g, since attacker can control the plaintext (chosen-plaintext) or can know the plaintext (known-plaintext). Yes, we all know that these are not the common attacks, still, IPsec is designed to defeat these too...
- As Brandon mentioned, the SPIs in the two directions differ. No, that's _not_ a mistake. By keeping these different, we allow each party to choose the SPI of traffic sent to it (that's how it works). This can be used for (1) efficiency - use predefined array of SPIs (think HW), (2) security - choose SPI randomly, defeating spoofed packets sent as part of DoS attack against IPsec tunnel (by off-path attacker).
- And then there's key management. When refreshing a key, or more precisely, changing a key due to exceeding max usage amount/period, we typically negotiate a new key and SPI. Once we got the `ack' from the remote peer (with the new SPI), we can start using the new key, while our peer may still be using an old key to send traffic to us (in fact we have the flexibility of not changing both keys together, e.g., if changing based on amount of traffic).
BTW,
I was actually around in the initial design, but I can't claim to remember the process well enough to say these were exactly the reasons for this at the time; but these are the reasons I'm aware of (and I'll love to learn if there are more or if any of these are incorrect).