19115 Commits

Author SHA1 Message Date
Tobias Brunner
12d2b6e2b4 key-exchange: Pass prefix array directly, not a pointer to it 2024-08-08 11:19:16 +02:00
Tobias Brunner
8e2fde6230 child-create: Remove redundant variable assignment 2024-08-08 11:18:24 +02:00
Tobias Brunner
3a850ae191 Merge branch 'multi-ke'
This adds support for multiple key exchanges (no KEMs yet as none are
standardized so far).  Work on this started over five years ago and went
through multiple iterations (first our own protocol, then standardized
extensions in different variations).

IKE_INTERMEDIATE exchanges, defined RFC 9242, are used to transport
multiple KE payloads between the IKE_SA_INIT and IKE_AUTH exchanges.
To rekey IKE and CHILD_SAs with multiple key exchanges, IKE_FOLLOWUP_KE
exchanges are used, as defined in RFC 9370.

In proposals, additional key exchange methods are configured via `keX_`
prefix, where X is a number between 1 and 7.  For example, `ke1_ecp256`
adds ECP_256 as additional KE method.  As with regular key exchanges,
peers have to agree on a method for each round unless no algorithms are
defined by both or `keX_none` is configured to make that round explicitly
optional.

Also changed is how rekey collisions are handled, which makes CHILD_SAs
properly trackable via child_rekey() hook.
2024-08-07 16:20:42 +02:00
Tobias Brunner
f3c7e5227c testing: Add ikev2/rw-cert-multi-ke scenario 2024-08-07 16:20:19 +02:00
Tobias Brunner
ddb9b274c2 unit-tests: Ensure listeners can track SAs via ike/child_updown/rekey()
Previously, it could happen that child_rekey() was triggered twice for
the same "old" SA.  For listeners that would mean they'd loose track as
they'd be tracking a new SA that wasn't relevant anymore and for which
no updown event would ever get triggered (it was the redundant SA in a
collision).  This new assert ensures that events are triggered in a
predictable way and listeners can track SAs properly.
2024-08-07 16:20:19 +02:00
Tobias Brunner
d2b2e1b3fa ikev2: Make CHILD_SAs properly trackable during rekey collisions
As the winner of a rekey collision, we previously always triggered the
child_rekey() event once when creating the redundant SA on behalf of the
peer in the passive child-rekey task and then a second time when
creating the winning SA in the active task.  However, both calls passed
the replaced CHILD_SA as "old". This made tracking CHILD_SAs impossible
because there was no transition from the redundant, "new" SA of the
first event to the "new", winning SA of the second.  Of course, when the
second event was triggered, the redundant SA might not have existed
anymore because the peer is expected to delete it, which could happen
before the CREATE_CHILD_SA response arrives at the initiator.

This refactoring ensures that the child_rekey() event is triggered in
a way that makes the CHILD_SAs trackable in all reasonable (and even
some unreasonable) scenarios.  The event is generally only triggered
once after installing the outbound SA for the new/winning CHILD_SA.
This can be when processing the CREATE_CHILD_SA in the active child-rekey
task, or when processing the DELETE for the old SA in a passive
child-delete task.  There are some cases where the event is still
triggered twice, but it is now ensured that listeners can properly
transition to the winning SA.

Some corner cases are now also handled correctly, e.g. if a responder's
DELETE for the new CHILD_SA arrives before its CREATE_CHILD_SA response
that actually creates it on the initiator.  Also handled properly are
responders of rekeyings that incorrectly send a DELETE for the old
CHILD_SA (previously this caused both, the new and the old SA, to get
deleted).
2024-08-07 16:20:19 +02:00
Tobias Brunner
7ad610a140 ike-init: Indicate support for IKE_INTERMEDIATE 2024-08-07 16:20:19 +02:00
Tobias Brunner
012d99ecf4 proposal: Prevent selection of duplicate key exchange methods
All additional (and the initial) key exchanges must use a different method.
2024-08-07 16:20:19 +02:00
Tobias Brunner
1d5e921911 proposal: Add helper to check if additional key exchanges are contained 2024-08-07 16:20:19 +02:00
Tobias Brunner
882ff93bfd proposal: Accept NONE for additional key exchanges also for IKE proposals 2024-08-07 16:20:19 +02:00
Tobias Brunner
33e421320a unit-tests: Add tests for CHILD_SA rekeying with multiple key exchanges 2024-08-07 16:20:19 +02:00
Tobias Brunner
37eeafa37f unit-tests: Add tests for CHILD_SA creation with multiple key exchanges 2024-08-07 16:20:18 +02:00
Tobias Brunner
329a7b331d unit-tests: Add tests for IKE_SA rekeying with multiple key exchanges 2024-08-07 16:20:18 +02:00
Tobias Brunner
37c56affa1 unit-tests: Support multiple proposals in exchange tests 2024-08-07 16:20:18 +02:00
Andreas Steffen
d4fb07911f vici: Increase maximum proposal length 2024-08-07 16:20:18 +02:00
Andreas Steffen
355f917532 vici: List additional key exchanges
Co-authored-by: Tobias Brunner <tobias@strongswan.org>
2024-08-07 16:20:18 +02:00
Tobias Brunner
c5a6938b9e proposal: Add prefix for additional key exchanges when logging proposals 2024-08-07 16:20:18 +02:00
Tobias Brunner
e05d86b27a key-exchange: Add dynamic parser for additional key exchange methods 2024-08-07 16:20:18 +02:00
Tobias Brunner
95275d2fe5 child-rekey: Support CHILD_SA rekeying with multiple key exchanges 2024-08-07 16:20:18 +02:00
Tobias Brunner
c200bd1668 unit-tests: Fix CHILD_SA rekey tests after INVALID_KE_PAYLOAD handling changed
The responder doesn't create a CHILD_SA and allocate an SPI anymore
when responding with an INVALID_KE_PAYLOAD notify.
2024-08-07 16:20:18 +02:00
Tobias Brunner
d7760416d6 child-create: Add support for multiple key exchanges
It also changes that payloads are built before installing the CHILD_SA
on the responder, that is, the KE payload is generated before keys are
derived, so that key_exchange_t::get_public_key() is called before
get_shared_secret(), or its internal equivalent, which could be relevant
for KE implementations that want to ensure that the key can't be
accessed again after the key derivation.
2024-08-07 16:20:18 +02:00
Tobias Brunner
ca3e6d2d14 ike-rekey: Support IKE_SA rekeying with multiple key exchanges 2024-08-07 16:20:18 +02:00
Tobias Brunner
0d49ddec2e ike-init: Add support for multiple key exchanges
Initially, this is handled with a key derivation for each
IKE_INTERMEDIATE exchange.  When rekeying, the keys are derived only
once all IKE_FOLLOWUP_KE exchanges are done.
2024-08-07 16:20:18 +02:00
Tobias Brunner
eff0c43a17 bus: Support multiple key exchanges in ike/child_keys() events 2024-08-07 16:20:18 +02:00
Tobias Brunner
c14e4ab2a8 keymat_v2: Support key derivation with multiple key exchanges 2024-08-07 16:20:18 +02:00
Tobias Brunner
c36eaf42da key-exchange: Add helper to concatenate shared secrets of several key exchanges 2024-08-07 16:20:18 +02:00
Tobias Brunner
ec0ec55070 keymat_v2: Proper cleanup if derive_ike_keys() is called multiple times 2024-08-07 16:20:18 +02:00
Tobias Brunner
f6b2e6a21f ike-auth: Calculate and collect IntAuth for IKE_INTERMEDIATE exchanges
The message ID of the first IKE_AUTH exchange is a safe-guard against
potential truncation attacks if IKE_INTERMEDIATE exchanges are not used
for multiple key exchanges but some other future use where the number of
exchanges might not depend on the selected proposal.
2024-08-07 16:20:18 +02:00
Tobias Brunner
1212780b32 pubkey-authenticator: Handle IntAuth data 2024-08-07 16:20:18 +02:00
Tobias Brunner
c4dac17d8c psk-authenticator: Handle IntAuth data 2024-08-07 16:20:18 +02:00
Tobias Brunner
5c69262ce6 eap-authenticator: Handle IntAuth data 2024-08-07 16:20:18 +02:00
Tobias Brunner
e5828d26ea keymat_v2: Include optional IntAuth in signed octets 2024-08-07 16:20:18 +02:00
Tobias Brunner
91f09b8d25 authenticator: Add optional method to set IntAuth data 2024-08-07 16:20:18 +02:00
Tobias Brunner
515b9303de message: Store original encrypted payload when generating fragments
If we don't do this, get_plain() will fail after generating the message
fragmented unless it was generated non-fragmented previously.
2024-08-07 16:20:18 +02:00
Tobias Brunner
b9c69f9080 message: Add method to generate data to authenticate IKE_INTERMEDIATE exchanges 2024-08-07 16:20:18 +02:00
Tobias Brunner
5c439bb8a3 generator: Make pointer to length field optional
Only useful if we generate an IKE header.
2024-08-07 16:20:18 +02:00
Tobias Brunner
a24993213e keymat_v2: Add method to calculate IntAuth for IKE_INTERMEDIATE exchanges 2024-08-07 16:20:18 +02:00
Tobias Brunner
b8358936aa message: Add rules for IKE_FOLLOWUP_KE exchanges 2024-08-07 16:20:18 +02:00
Tobias Brunner
414db6cab1 ike-header: Add IKE_FOLLOWUP_KE exchange type 2024-08-07 16:20:18 +02:00
Tobias Brunner
041358976b notify-payload: Add notify types for multiple key exchanges 2024-08-07 16:20:18 +02:00
Tobias Brunner
aedf73f7cf ikev2: Reject IKE_INTERMEDIATE requests after IKE_AUTH
We currently only support these exchanges for additional key exchanges,
so once we have the final keys derived and the ike-init task is removed,
we don't expect any more of them.
2024-08-07 16:20:18 +02:00
Tobias Brunner
25f2cdfc56 message: Add rules for IKE_INTERMEDIATE exchanges 2024-08-07 16:20:18 +02:00
Tobias Brunner
a45d454e94 ike-header: Add IKE_INTERMEDIATE exchange type 2024-08-07 16:20:18 +02:00
Tobias Brunner
cc9ab450d6 notify-payload: Add notify type for IKE_INTERMEDIATE exchange 2024-08-07 16:20:18 +02:00
Tobias Brunner
3e0495745c proposal-substructure: Encode additional key exchange methods 2024-08-07 16:20:18 +02:00
Tobias Brunner
9cc5f4a511 proposal: Make all key exchange transforms optional in ESP/AH proposals 2024-08-07 16:20:18 +02:00
Tobias Brunner
fb6b8c833b proposal: Skip all KE transforms if PROPOSAL_SKIP_KE given 2024-08-07 16:20:18 +02:00
Tobias Brunner
2e059e0c27 transform: Add helper to check if transform type negotiates key exchange 2024-08-07 16:20:18 +02:00
Tobias Brunner
22550bd262 transform: Add additional key exchange transform types 2024-08-07 16:20:18 +02:00
Tobias Brunner
a7f617ab33 kernel-pfkey: Fix list of extension type names on FreeBSD
The list was extended earlier this year.
2024-08-07 15:09:45 +02:00