[08/15] mka: MKPDU SAK Use Body's Delay Protect bit set incorrectly

Message ID 20180302201103.16264-9-msiedzik@extremenetworks.com
State New
Headers show
Series
  • MKA bugfixes and enhancements
Related show

Commit Message

Michael Siedzik March 2, 2018, 8:10 p.m.
From: Mike Siedzik <msiedzik@extremenetworks.com>

Delay Protect and Replay Protect are two separate and distinct features
of MKA.  Per IEEE802.1X-2010 Clause 9.10.1 "Delay Protect, TRUE if LPNs
are being reported sufficiently frequently to allow the receipt to
provide data delay protection.  If FALSE, the LPN can be reported as
zero", and per Clause 9.10 "NOTE - Enforcement of bounded received delay
necessitates transmission of MKPDUs at frequency (0.5 s) intervals, to
meet a maximum data delay of 2 s while minimizing connectivity
interruption due to the possibility of lost or delayed MKPDUs."

This means ieee802_1x_mka_sak_use_body.delay_protect should only be set
TRUE when MKPDUs are being transmitted every 0.5 s (or faster).  By
default the KaY sends MKPDUs every MKA_HELLO_TIME (2.0s), so by default
delay_protect should be FALSE.

A new 'u32 mka_hello_time' parameter to has been added to the
'ieee802_1x_kay' data structure.  If delay protection is desired, the
KaY initialization code should set kay->mka_hello_time to
MKA_BOUNDED_HELLO_TIME (500ms).

Signed-off-by: Michael Siedzik <msiedzik@extremenetworks.com>
---
 src/pae/ieee802_1x_kay.c | 14 +++++++++-----
 src/pae/ieee802_1x_kay.h |  2 ++
 2 files changed, 11 insertions(+), 5 deletions(-)

--
2.11.1

Patch

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 0c3101cd8..ba2636ad6 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -1205,7 +1205,7 @@  ieee802_1x_mka_encode_sak_use_body(
        }

        /* data protect, lowest accept packet number */
-       body->delay_protect = kay->macsec_replay_protect;
+       body->delay_protect = (kay->mka_hello_time <= MKA_BOUNDED_HELLO_TIME);
        pn = ieee802_1x_mka_get_lpn(participant, &participant->lki);
        if (pn > kay->pn_exhaustion) {
                wpa_printf(MSG_WARNING, "KaY: My LPN exhaustion");
@@ -2487,7 +2487,7 @@  static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
                participant->retry_count++;
        }

-       eloop_register_timeout(MKA_HELLO_TIME / 1000, 0,
+       eloop_register_timeout(kay->mka_hello_time / 1000, 0,
                               ieee802_1x_participant_timer,
                               participant, NULL);

@@ -3208,6 +3208,7 @@  ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy,
                kay->macsec_replay_protect = FALSE;
                kay->macsec_replay_window = 0;
                kay->macsec_confidentiality = CONFIDENTIALITY_NONE;
+               kay->mka_hello_time = MKA_HELLO_TIME;
        } else {
                kay->macsec_desired = TRUE;
                kay->macsec_protect = TRUE;
@@ -3221,6 +3222,7 @@  ieee802_1x_kay_init(struct ieee802_1x_kay_ctx *ctx, enum macsec_policy policy,
                kay->macsec_validate = Strict;
                kay->macsec_replay_protect = FALSE;
                kay->macsec_replay_window = 0;
+               kay->mka_hello_time = MKA_HELLO_TIME;
        }

        wpa_printf(MSG_DEBUG, "KaY: state machine created");
@@ -3425,7 +3427,7 @@  ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn,
        wpa_hexdump(MSG_DEBUG, "KaY: Participant created:",
                    ckn->name, ckn->len);

-       usecs = os_random() % (MKA_HELLO_TIME * 1000);
+       usecs = os_random() % (kay->mka_hello_time * 1000);
        eloop_register_timeout(0, usecs, ieee802_1x_participant_timer,
                               participant, NULL);

@@ -3575,7 +3577,7 @@  void ieee802_1x_kay_notify_port_enabled(struct ieee802_1x_kay *kay,
                dl_list_for_each(participant, &kay->participant_list,
                                 struct ieee802_1x_mka_participant, list) {
                        if (participant->participant) {
-                               usecs = os_random() % (MKA_HELLO_TIME * 1000);
+                               usecs = os_random() % (kay->mka_hello_time * 1000);
                                eloop_register_timeout(0, usecs, ieee802_1x_participant_timer,
                                                       participant, NULL);
                        }
@@ -3681,6 +3683,7 @@  int ieee802_1x_kay_get_status(struct ieee802_1x_kay *kay, char *buf,
                          "Is Key Server=%s\n"
                          "Number of Keys Distributed=%u\n"
                          "Number of Keys Received=%u\n",
+                         "MKA Hello Time=%u\n",
                          kay->port_enable ? "Enabled" : "Disabled",
                          kay->active ? "Active" : "Not-Active",
                          kay->authenticated ? "Yes" : "No",
@@ -3690,7 +3693,8 @@  int ieee802_1x_kay_get_status(struct ieee802_1x_kay *kay, char *buf,
                          kay->key_server_priority,
                          kay->is_key_server ? "Yes" : "No",
                          kay->dist_kn - 1,
-                         kay->rcvd_keys);
+                         kay->rcvd_keys,
+                         kay->mka_hello_time);
        if (os_snprintf_error(buflen, len))
                return 0;

diff --git a/src/pae/ieee802_1x_kay.h b/src/pae/ieee802_1x_kay.h
index 8c1a3b2fa..7031c1a83 100644
--- a/src/pae/ieee802_1x_kay.h
+++ b/src/pae/ieee802_1x_kay.h
@@ -21,6 +21,7 @@  struct macsec_init_params;

 /* MKA timer, unit: millisecond */
 #define MKA_HELLO_TIME         2000
+#define MKA_BOUNDED_HELLO_TIME  500
 #define MKA_LIFE_TIME          6000
 #define MKA_SAK_RETIRE_TIME    3000

@@ -187,6 +188,7 @@  struct ieee802_1x_kay {
        u32 macsec_replay_window;
        enum validate_frames macsec_validate;
        enum confidentiality_offset macsec_confidentiality;
+       u32 mka_hello_time;

        u32 ltx_kn;
        u8 ltx_an;