Skip to content

Commit

Permalink
Merge pull request #27 from Technica-Engineering/feature/tc17_quick_p…
Browse files Browse the repository at this point in the history
…eer_removal_after_mi_change

Quick removal of peer when its MI changes (backport). Proposed change TC17.
  • Loading branch information
fpedrera-technica authored Mar 11, 2024
2 parents bf7618a + dc4c10a commit f457216
Show file tree
Hide file tree
Showing 14 changed files with 350 additions and 33 deletions.
3 changes: 2 additions & 1 deletion src/linux_daemon/dbus_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,12 @@ on_bus_acquired (GDBusConnection *connection,
strcpy(intf_name, "/de/technica_engineering/mkad/");
char **busname_split = g_strsplit(bus_names[bus], ".", -1);
char *busname = g_strjoinv("", busname_split);
g_strfreev(busname_split);
//strncat(intf_name, g_dbus_escape_object_path(busname), IFNAMSIZ); // g_dbus_escape object is only available on glib >=2.68
strncat(intf_name, busname, IFNAMSIZ);
strncat(intf_name, "/BUS", 4);
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (interfaces[bus]), connection, intf_name, &error);
g_strfreev(busname_split);
g_free(busname);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/linux_daemon/mka_timers_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ bool mka_timer_running(t_mka_timer const* const timer)

bool mka_timer_expired(t_mka_timer const* const timer)
{
MKA_ASSERT(NULL != timer->ref, "Attempt to call a getter on a non-initialised timer.");
return (mka_tick_time_ms >= timer->ref->expiry);
bool const initialised = (bool)(NULL != timer->ref);
return initialised ? (mka_tick_time_ms >= timer->ref->expiry) : false;
}

/******************* Func. definition ***********************/
Expand Down
9 changes: 9 additions & 0 deletions src/mka_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,15 @@ static inline bool MKA_sci_equal(t_MKA_sci const* a, t_MKA_sci const* b)
return 0 == memcmp(a, b, sizeof(t_MKA_sci));
}

static inline bool MKA_is_mi_null(uint8_t const* a)
{
uint8_t sum = 0U;
for(uint8_t i=0U; i<MKA_MI_LENGTH; ++i) {
sum |= a[i];
}
return 0U == sum;
}

static inline bool MKA_mi_equal(uint8_t const* a, uint8_t const* b)
{
return 0 == memcmp(a, b, MKA_MI_LENGTH);
Expand Down
53 changes: 41 additions & 12 deletions src/pae/mka_kay.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,20 @@ void MKA_KAY_MainFunctionTimers(t_MKA_bus bus)
}
else {
t_mka_peer const*const peer = &participant->peer;
t_mka_peer *const peer_secondary = &participant->peer_secondary;

if (mka_timer_expired(&peer->expiry)) {
MKA_LOG_INFO("KaY/%i: %s peer timed out.", bus,
(MKA_PEER_POTENTIAL == peer->state) ? "Potential" : "Live");
mka_peer_cleanup(bus);
}

if (mka_timer_expired(&peer_secondary->expiry)) {
MKA_LOG_INFO("KaY/%i: Secondary peer timed out.", bus);
mka_timer_stop(&peer_secondary->expiry);
memset(peer_secondary, 0, sizeof(*peer_secondary));
}

if (mka_timer_expired(&participant->mka_life) && (MKA_PEER_NONE == peer->state)) {
mka_set_mode(bus, MKA_FAILED);
}
Expand Down Expand Up @@ -503,6 +510,7 @@ void mka_handle_mkpdu(t_MKA_bus bus, uint8_t const*packet, uint32_t length)
t_mka_peer*const peer = &participant->peer;
t_mka_peer_state initial_peer_state = peer->state;
uint32_t offset = sizeof(t_MKA_l2_ether_header)+sizeof(t_mka_eapol_header);
bool main_peer = true; // secondary peer: quick renegotiation after peer resets its MI
bool header_presence[256U];
bool continue_process;
uint16_t param_type = 0U;
Expand All @@ -515,12 +523,12 @@ void mka_handle_mkpdu(t_MKA_bus bus, uint8_t const*packet, uint32_t length)
uint32_t xpn_l_high = 0U;
uint32_t xpn_o_high = 0U;

{ // Basic Parameter Set is always first
//lint -e{9087, 826} [MISRA 2012 Rule 11.3, required] Pointer cast controlled; packed struct representing network data
t_mka_basic_parameter_set const*const bps = (t_mka_basic_parameter_set const*)&packet[offset];
offset += sizeof(t_mka_param_generic) + MKA_ALIGN_TO_32BIT(((uint32_t)bps->length << 8U) + (uint32_t)bps->length_cont);
continue_process = mka_handle_basic_parameter_set(bus, bps);
}
// Basic Parameter Set is always first
//lint -e{9087, 826} [MISRA 2012 Rule 11.3, required] Pointer cast controlled; packed struct representing network data
t_mka_basic_parameter_set const*const bps = (t_mka_basic_parameter_set const*)&packet[offset];
offset += sizeof(t_mka_param_generic) + MKA_ALIGN_TO_32BIT(((uint32_t)bps->length << 8U) + (uint32_t)bps->length_cont);
continue_process = mka_handle_basic_parameter_set(bus, bps);
main_peer = MKA_mi_equal(peer->mi, bps->actor_mi);

/* Re-evaluate in what remote list we are listed, based on the processing
* of potential/live peer lists below, which must be populated right after
Expand Down Expand Up @@ -548,10 +556,12 @@ void mka_handle_mkpdu(t_MKA_bus bus, uint8_t const*packet, uint32_t length)
else {
switch(param_type) {
case PARAMETER_LIVE_PEER_LIST:
continue_process = mka_handle_peer_list(bus, &packet[offset], param_len, MKA_PEER_LIVE);
continue_process = mka_handle_peer_list(bus, &packet[offset], param_len, main_peer, MKA_PEER_LIVE);
main_peer = MKA_mi_equal(peer->mi, bps->actor_mi); // re-evaluate
break;
case PARAMETER_POTENTIAL_PEER_LIST:
continue_process = mka_handle_peer_list(bus, &packet[offset], param_len, MKA_PEER_POTENTIAL);
continue_process = mka_handle_peer_list(bus, &packet[offset], param_len, main_peer, MKA_PEER_POTENTIAL);
main_peer = MKA_mi_equal(peer->mi, bps->actor_mi); // re-evaluate
break;
case PARAMETER_SAK_USE:
// if we are not key server, a SAK USE parameter could be meaningless unless
Expand All @@ -569,11 +579,15 @@ void mka_handle_mkpdu(t_MKA_bus bus, uint8_t const*packet, uint32_t length)
break;

case PARAMETER_ANNOUNCEMENT:
continue_process = mka_handle_announcements(bus, &packet[offset], param_len);
if (main_peer) {
continue_process = mka_handle_announcements(bus, &packet[offset], param_len);
}
break;

case PARAMETER_XPN:
continue_process = mka_handle_xpn(bus, &packet[offset], param_len, &xpn_o_high, &xpn_l_high);
if (main_peer) {
continue_process = mka_handle_xpn(bus, &packet[offset], param_len, &xpn_o_high, &xpn_l_high);
}
break;

case PARAMETER_DISTRIBUTED_CAK:
Expand All @@ -597,6 +611,13 @@ void mka_handle_mkpdu(t_MKA_bus bus, uint8_t const*packet, uint32_t length)
}
}

// case 'secondary' peer has not become 'main' peer at this point
if (!main_peer) {
// does not make sense to continue processing, discard all logic past this point,
// (DIST SAK/SAK USE). its life timer is already updated while processing basic parameter set
continue_process = false;
}

// Conditions to not perform MACsec cipher suite negotiation, after all parameters are handled
if ((!continue_process) || (MKA_PEER_LIVE != peer->state) || (MKA_CS_INVALID != participant->cipher)) {
// No action
Expand Down Expand Up @@ -886,6 +907,8 @@ void mka_participant_cleanup(t_MKA_bus bus)

mka_timer_stop(&participant->mka_life);
mka_peer_cleanup(bus);
memset(&participant->peer_secondary, 0, sizeof(participant->peer_secondary));
mka_timer_init(&participant->peer_secondary.expiry);

mka_timer_init(&participant_cak_life);
mka_timer_init(&participant_mka_life);
Expand Down Expand Up @@ -916,6 +939,8 @@ void mka_new_participant_mi(t_MKA_bus bus)

// Clear participant's peer
mka_peer_cleanup(bus);
memset(&participant->peer_secondary, 0, sizeof(participant->peer_secondary));
mka_timer_init(&participant->peer_secondary.expiry);

MKA_ASSERT(MKA_GetRandomBytes(sizeof(participant->mi), participant->mi), "Cannot generate random numbers");

Expand Down Expand Up @@ -1044,7 +1069,11 @@ t_MKA_sak* mka_find_key(t_MKA_bus bus, uint8_t const* mi, uint32_t kn)
t_mka_participant*const participant = &ctx->participant;
t_MKA_sak* sak;

if (MKA_mi_equal(participant->new_sak.identifier.mi, mi) &&
// Case call from CP with empty key, prevent referencing internal kay structures
if (MKA_is_mi_null(mi) && (0U == kn)) {
sak = NULL;
}
else if (MKA_mi_equal(participant->new_sak.identifier.mi, mi) &&
(participant->new_sak.identifier.kn == kn)) {
sak = &participant->new_sak;
}
Expand Down Expand Up @@ -1137,7 +1166,7 @@ void MKA_KAY_DeleteSAs(t_MKA_bus bus, t_MKA_ki const* ki)
}

// CP is erasing SA associated to current SAK, we just completed a key rotation
if ((key == &participant->current_sak) || (NULL == key)) {
if (key == &participant->current_sak) {
memcpy(&participant->current_sak, &participant->new_sak, sizeof(t_MKA_sak));
memset(&participant->new_sak, 0, sizeof(t_MKA_sak));
}
Expand Down
5 changes: 4 additions & 1 deletion src/pae/mka_kay_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ typedef struct {
// Peer
t_mka_peer peer;

// backport: potential peer for quick renegotiation after remote MI reset, without full multipeer
t_mka_peer peer_secondary;

// Life time
t_mka_timer cak_life;
t_mka_timer mka_life;
Expand Down Expand Up @@ -403,7 +406,7 @@ bool mka_mkpdu_verify(t_MKA_bus bus, uint8_t const*packet, uint32_t *length);
void mka_handle_mkpdu(t_MKA_bus bus, uint8_t const*packet, uint32_t length);
bool mka_handle_basic_parameter_set(t_MKA_bus bus, t_mka_basic_parameter_set const*bps);
bool mka_encode_basic_parameter_set(t_MKA_bus bus, uint8_t *packet, uint32_t *length);
bool mka_handle_peer_list(t_MKA_bus bus, uint8_t const*param, uint32_t body_len, t_mka_peer_state type);
bool mka_handle_peer_list(t_MKA_bus bus, uint8_t const*param, uint32_t body_len, bool main_peer, t_mka_peer_state type);
bool mka_encode_peer_list(t_MKA_bus bus, uint8_t *packet, uint32_t *length);
bool mka_handle_sak_use(t_MKA_bus bus, uint8_t const*param, uint32_t body_len, uint32_t xpn_o_high, uint32_t xpn_l_high);
bool mka_encode_sak_use(t_MKA_bus bus, uint8_t *packet, uint32_t *length);
Expand Down
Loading

0 comments on commit f457216

Please sign in to comment.