mka: Store cipher suite ID in a u64 instead of u8 pointer
[mech_eap.git] / src / pae / ieee802_1x_kay.c
index 3a93323..9bb4a94 100644 (file)
@@ -79,16 +79,6 @@ static int is_ki_equal(struct ieee802_1x_mka_ki *ki1,
 }
 
 
-struct mka_param_body_handler {
-       int (*body_tx)(struct ieee802_1x_mka_participant *participant,
-                      struct wpabuf *buf);
-       int (*body_rx)(struct ieee802_1x_mka_participant *participant,
-                      const u8 *mka_msg, size_t msg_len);
-       int (*body_length)(struct ieee802_1x_mka_participant *participant);
-       Boolean (*body_present)(struct ieee802_1x_mka_participant *participant);
-};
-
-
 static void set_mka_param_body_len(void *body, unsigned int len)
 {
        struct ieee802_1x_mka_hdr *hdr = body;
@@ -286,7 +276,7 @@ ieee802_1x_kay_get_principal_participant(struct ieee802_1x_kay *kay)
                        return participant;
        }
 
-       wpa_printf(MSG_DEBUG, "KaY: principal participant is not founded");
+       wpa_printf(MSG_DEBUG, "KaY: principal participant is not found");
        return NULL;
 }
 
@@ -350,18 +340,6 @@ ieee802_1x_kay_is_in_live_peer(
 
 
 /**
- * ieee802_1x_kay_is_in_peer
- */
-static Boolean
-ieee802_1x_kay_is_in_peer(struct ieee802_1x_mka_participant *participant,
-                         const u8 *mi)
-{
-       return ieee802_1x_kay_is_in_live_peer(participant, mi) ||
-               ieee802_1x_kay_is_in_potential_peer(participant, mi);
-}
-
-
-/**
  * ieee802_1x_kay_get_peer
  */
 static struct ieee802_1x_kay_peer *
@@ -383,12 +361,17 @@ ieee802_1x_kay_get_peer(struct ieee802_1x_mka_participant *participant,
  */
 static struct macsec_ciphersuite *
 ieee802_1x_kay_get_cipher_suite(struct ieee802_1x_mka_participant *participant,
-                               u8 *cs_id)
+                               const u8 *cs_id)
 {
        unsigned int i;
+       u64 cs;
+       be64 _cs;
+
+       os_memcpy(&_cs, cs_id, CS_ID_LEN);
+       cs = be_to_host64(_cs);
 
        for (i = 0; i < CS_TABLE_SIZE; i++) {
-               if (os_memcmp(cipher_suite_tbl[i].id, cs_id, CS_ID_LEN) == 0)
+               if (cipher_suite_tbl[i].id == cs)
                        return &cipher_suite_tbl[i];
        }
 
@@ -715,7 +698,7 @@ ieee802_1x_mka_encode_basic_body(
        os_memcpy(body->actor_mi, participant->mi, sizeof(body->actor_mi));
        participant->mn = participant->mn + 1;
        body->actor_mn = host_to_be32(participant->mn);
-       os_memcpy(body->algo_agility, participant->kay->algo_agility,
+       os_memcpy(body->algo_agility, kay->algo_agility,
                  sizeof(body->algo_agility));
 
        os_memcpy(body->ckn, participant->ckn.name, participant->ckn.len);
@@ -1069,14 +1052,11 @@ ieee802_1x_mka_decode_potential_peer_body(
        struct ieee802_1x_mka_participant *participant,
        const u8 *peer_msg, size_t msg_len)
 {
-       struct ieee802_1x_mka_hdr *hdr;
+       const struct ieee802_1x_mka_hdr *hdr;
        size_t body_len;
-       u32 peer_mn;
-       be32 _peer_mn;
-       const u8 *peer_mi;
        size_t i;
 
-       hdr = (struct ieee802_1x_mka_hdr *) peer_msg;
+       hdr = (const struct ieee802_1x_mka_hdr *) peer_msg;
        body_len = get_mka_param_body_len(hdr);
        if (body_len % 16 != 0) {
                wpa_printf(MSG_ERROR,
@@ -1085,10 +1065,13 @@ ieee802_1x_mka_decode_potential_peer_body(
                return -1;
        }
 
-       for (i = 0; i < body_len; i += MI_LEN + sizeof(peer_mn)) {
-               peer_mi = MKA_HDR_LEN + peer_msg + i;
-               os_memcpy(&_peer_mn, peer_mi + MI_LEN, sizeof(_peer_mn));
-               peer_mn = be_to_host32(_peer_mn);
+       for (i = 0; i < body_len; i += sizeof(struct ieee802_1x_mka_peer_id)) {
+               const struct ieee802_1x_mka_peer_id *peer_mi;
+               u32 peer_mn;
+
+               peer_mi = (struct ieee802_1x_mka_peer_id *)
+                       (peer_msg + MKA_HDR_LEN + i);
+               peer_mn = be_to_host32(peer_mi->mn);
 
                /* it is myself */
                if (os_memcmp(peer_mi, participant->mi, MI_LEN) == 0) {
@@ -1172,6 +1155,7 @@ ieee802_1x_mka_encode_sak_use_body(
        struct wpabuf *buf)
 {
        struct ieee802_1x_mka_sak_use_body *body;
+       struct ieee802_1x_kay *kay = participant->kay;
        unsigned int length;
        u32 pn = 1;
 
@@ -1192,9 +1176,9 @@ ieee802_1x_mka_encode_sak_use_body(
        }
 
        /* data protect, lowest accept packet number */
-       body->delay_protect = participant->kay->macsec_replay_protect;
+       body->delay_protect = kay->macsec_replay_protect;
        pn = ieee802_1x_mka_get_lpn(participant, &participant->lki);
-       if (pn > participant->kay->pn_exhaustion) {
+       if (pn > kay->pn_exhaustion) {
                wpa_printf(MSG_WARNING, "KaY: My LPN exhaustion");
                if (participant->is_key_server)
                        participant->new_sak = TRUE;
@@ -1205,20 +1189,12 @@ ieee802_1x_mka_encode_sak_use_body(
        body->olpn = host_to_be32(pn);
 
        /* plain tx, plain rx */
-       if (participant->kay->macsec_protect)
-               body->ptx = FALSE;
-       else
-               body->ptx = TRUE;
-
-       if (participant->kay->macsec_validate == Strict)
-               body->prx = FALSE;
-       else
-               body->prx = TRUE;
+       body->ptx = !kay->macsec_protect;
+       body->prx = kay->macsec_validate != Strict;
 
        /* latest key: rx, tx, key server member identifier key number */
        body->lan = participant->lan;
-       os_memcpy(body->lsrv_mi, participant->lki.mi,
-                 sizeof(body->lsrv_mi));
+       os_memcpy(body->lsrv_mi, participant->lki.mi, sizeof(body->lsrv_mi));
        body->lkn = host_to_be32(participant->lki.kn);
        body->lrx = participant->lrx;
        body->ltx = participant->ltx;
@@ -1239,16 +1215,11 @@ ieee802_1x_mka_encode_sak_use_body(
 
        /* set CP's variable */
        if (body->ltx) {
-               if (!participant->kay->tx_enable)
-                       participant->kay->tx_enable = TRUE;
-
-               if (!participant->kay->port_enable)
-                       participant->kay->port_enable = TRUE;
-       }
-       if (body->lrx) {
-               if (!participant->kay->rx_enable)
-                       participant->kay->rx_enable = TRUE;
+               kay->tx_enable = TRUE;
+               kay->port_enable = TRUE;
        }
+       if (body->lrx)
+               kay->rx_enable = TRUE;
 
        ieee802_1x_mka_dump_sak_use_body(body);
        return 0;
@@ -1272,7 +1243,8 @@ ieee802_1x_mka_decode_sak_use_body(
        struct ieee802_1x_mka_ki ki;
        u32 lpn;
        Boolean all_receiving;
-       Boolean founded;
+       Boolean found;
+       struct ieee802_1x_kay *kay = participant->kay;
 
        if (!participant->principal) {
                wpa_printf(MSG_WARNING, "KaY: Participant is not principal");
@@ -1314,17 +1286,17 @@ ieee802_1x_mka_decode_sak_use_body(
 
        /* check latest key is valid */
        if (body->ltx || body->lrx) {
-               founded = FALSE;
+               found = FALSE;
                os_memcpy(ki.mi, body->lsrv_mi, sizeof(ki.mi));
                ki.kn = be_to_host32(body->lkn);
                dl_list_for_each(sa_key, &participant->sak_list,
                                 struct data_key, list) {
                        if (is_ki_equal(&sa_key->key_identifier, &ki)) {
-                               founded = TRUE;
+                               found = TRUE;
                                break;
                        }
                }
-               if (!founded) {
+               if (!found) {
                        wpa_printf(MSG_WARNING, "KaY: Latest key is invalid");
                        return -1;
                }
@@ -1335,9 +1307,8 @@ ieee802_1x_mka_decode_sak_use_body(
                        peer->sak_used = TRUE;
                }
                if (body->ltx && peer->is_key_server) {
-                       ieee802_1x_cp_set_servertransmitting(
-                               participant->kay->cp, TRUE);
-                       ieee802_1x_cp_sm_step(participant->kay->cp);
+                       ieee802_1x_cp_set_servertransmitting(kay->cp, TRUE);
+                       ieee802_1x_cp_sm_step(kay->cp);
                }
        }
 
@@ -1371,28 +1342,28 @@ ieee802_1x_mka_decode_sak_use_body(
        }
        if (all_receiving) {
                participant->to_dist_sak = FALSE;
-               ieee802_1x_cp_set_allreceiving(participant->kay->cp, TRUE);
-               ieee802_1x_cp_sm_step(participant->kay->cp);
+               ieee802_1x_cp_set_allreceiving(kay->cp, TRUE);
+               ieee802_1x_cp_sm_step(kay->cp);
        }
 
        /* if i'm key server, and detects peer member pn exhaustion, rekey.*/
        lpn = be_to_host32(body->llpn);
-       if (lpn > participant->kay->pn_exhaustion) {
+       if (lpn > kay->pn_exhaustion) {
                if (participant->is_key_server) {
                        participant->new_sak = TRUE;
                        wpa_printf(MSG_WARNING, "KaY: Peer LPN exhaustion");
                }
        }
 
-       founded = FALSE;
+       found = FALSE;
        dl_list_for_each(txsa, &participant->txsc->sa_list,
                         struct transmit_sa, list) {
                if (sa_key != NULL && txsa->pkey == sa_key) {
-                       founded = TRUE;
+                       found = TRUE;
                        break;
                }
        }
-       if (!founded) {
+       if (!found) {
                wpa_printf(MSG_WARNING, "KaY: Can't find txsa");
                return -1;
        }
@@ -1400,9 +1371,9 @@ ieee802_1x_mka_decode_sak_use_body(
        /* FIXME: Secy creates txsa with default npn. If MKA detected Latest Key
         * npn is larger than txsa's npn, set it to txsa.
         */
-       secy_get_transmit_next_pn(participant->kay, txsa);
+       secy_get_transmit_next_pn(kay, txsa);
        if (lpn > txsa->next_pn) {
-               secy_set_transmit_next_pn(participant->kay, txsa);
+               secy_set_transmit_next_pn(kay, txsa);
                wpa_printf(MSG_INFO, "KaY: update lpn =0x%x", lpn);
        }
 
@@ -1417,10 +1388,7 @@ static Boolean
 ieee802_1x_mka_dist_sak_body_present(
        struct ieee802_1x_mka_participant *participant)
 {
-       if (!participant->to_dist_sak || !participant->new_key)
-               return FALSE;
-
-       return TRUE;
+       return participant->to_dist_sak && participant->new_key;
 }
 
 
@@ -1432,7 +1400,7 @@ ieee802_1x_mka_get_dist_sak_length(
        struct ieee802_1x_mka_participant *participant)
 {
        int length = MKA_HDR_LEN;
-       int cs_index = participant->kay->macsec_csindex;
+       unsigned int cs_index = participant->kay->macsec_csindex;
 
        if (participant->advised_desired) {
                length = sizeof(struct ieee802_1x_mka_dist_sak_body);
@@ -1457,7 +1425,7 @@ ieee802_1x_mka_encode_dist_sak_body(
        struct ieee802_1x_mka_dist_sak_body *body;
        struct data_key *sak;
        unsigned int length;
-       int cs_index;
+       unsigned int cs_index;
        int sak_pos;
 
        length = ieee802_1x_mka_get_dist_sak_length(participant);
@@ -1477,7 +1445,10 @@ ieee802_1x_mka_encode_dist_sak_body(
        cs_index = participant->kay->macsec_csindex;
        sak_pos = 0;
        if (cs_index != DEFAULT_CS_INDEX) {
-               os_memcpy(body->sak, cipher_suite_tbl[cs_index].id, CS_ID_LEN);
+               be64 cs;
+
+               cs = host_to_be64(cipher_suite_tbl[cs_index].id);
+               os_memcpy(body->sak, &cs, CS_ID_LEN);
                sak_pos = CS_ID_LEN;
        }
        if (aes_wrap(participant->kek.key, 16,
@@ -1551,6 +1522,7 @@ ieee802_1x_mka_decode_dist_sak_body(
        int sak_len;
        u8 *wrap_sak;
        u8 *unwrap_sak;
+       struct ieee802_1x_kay *kay = participant->kay;
 
        hdr = (struct ieee802_1x_mka_hdr *) mka_msg;
        body_len = get_mka_param_body_len(hdr);
@@ -1571,8 +1543,8 @@ ieee802_1x_mka_decode_dist_sak_body(
                           "KaY: I can't accept the distributed SAK as myself is key server ");
                return -1;
        }
-       if (!participant->kay->macsec_desired ||
-           participant->kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) {
+       if (!kay->macsec_desired ||
+           kay->macsec_capable == MACSEC_CAP_NOT_IMPLEMENTED) {
                wpa_printf(MSG_ERROR,
                           "KaY: I am not MACsec-desired or without MACsec capable");
                return -1;
@@ -1585,27 +1557,29 @@ ieee802_1x_mka_decode_dist_sak_body(
                           "KaY: The key server is not in my live peers list");
                return -1;
        }
-       if (!sci_equal(&participant->kay->key_server_sci, &peer->sci)) {
+       if (!sci_equal(&kay->key_server_sci, &peer->sci)) {
                wpa_printf(MSG_ERROR, "KaY: The key server is not elected");
                return -1;
        }
+
        if (body_len == 0) {
-               participant->kay->authenticated = TRUE;
-               participant->kay->secured = FALSE;
-               participant->kay->failed = FALSE;
+               kay->authenticated = TRUE;
+               kay->secured = FALSE;
+               kay->failed = FALSE;
                participant->advised_desired = FALSE;
-               ieee802_1x_cp_connect_authenticated(participant->kay->cp);
-               ieee802_1x_cp_sm_step(participant->kay->cp);
+               ieee802_1x_cp_connect_authenticated(kay->cp);
+               ieee802_1x_cp_sm_step(kay->cp);
                wpa_printf(MSG_WARNING, "KaY:The Key server advise no MACsec");
                participant->to_use_sak = TRUE;
                return 0;
        }
+
        participant->advised_desired = TRUE;
-       participant->kay->authenticated = FALSE;
-       participant->kay->secured = TRUE;
-       participant->kay->failed = FALSE;
-       ieee802_1x_cp_connect_secure(participant->kay->cp);
-       ieee802_1x_cp_sm_step(participant->kay->cp);
+       kay->authenticated = FALSE;
+       kay->secured = TRUE;
+       kay->failed = FALSE;
+       ieee802_1x_cp_connect_secure(kay->cp);
+       ieee802_1x_cp_sm_step(kay->cp);
 
        body = (struct ieee802_1x_mka_dist_sak_body *)mka_msg;
        ieee802_1x_mka_dump_dist_sak_body(body);
@@ -1618,10 +1592,11 @@ ieee802_1x_mka_decode_dist_sak_body(
                        return 0;
                }
        }
+
        if (body_len == 28) {
                sak_len = DEFAULT_SA_KEY_LEN;
                wrap_sak =  body->sak;
-               participant->kay->macsec_csindex = DEFAULT_CS_INDEX;
+               kay->macsec_csindex = DEFAULT_CS_INDEX;
        } else {
                cs = ieee802_1x_kay_get_cipher_suite(participant, body->sak);
                if (!cs) {
@@ -1631,7 +1606,7 @@ ieee802_1x_mka_decode_dist_sak_body(
                }
                sak_len = cs->sak_len;
                wrap_sak = body->sak + CS_ID_LEN;
-               participant->kay->macsec_csindex = cs->index;
+               kay->macsec_csindex = cs->index;
        }
 
        unwrap_sak = os_zalloc(sak_len);
@@ -1686,16 +1661,15 @@ ieee802_1x_mka_decode_dist_sak_body(
 
        dl_list_add(&participant->sak_list, &sa_key->list);
 
-       ieee802_1x_cp_set_ciphersuite(
-               participant->kay->cp,
-               cipher_suite_tbl[participant->kay->macsec_csindex].id);
-       ieee802_1x_cp_sm_step(participant->kay->cp);
-       ieee802_1x_cp_set_offset(participant->kay->cp, body->confid_offset);
-       ieee802_1x_cp_sm_step(participant->kay->cp);
-       ieee802_1x_cp_set_distributedki(participant->kay->cp, &sak_ki);
-       ieee802_1x_cp_set_distributedan(participant->kay->cp, body->dan);
-       ieee802_1x_cp_signal_newsak(participant->kay->cp);
-       ieee802_1x_cp_sm_step(participant->kay->cp);
+       ieee802_1x_cp_set_ciphersuite(kay->cp,
+                                     cipher_suite_tbl[kay->macsec_csindex].id);
+       ieee802_1x_cp_sm_step(kay->cp);
+       ieee802_1x_cp_set_offset(kay->cp, body->confid_offset);
+       ieee802_1x_cp_sm_step(kay->cp);
+       ieee802_1x_cp_set_distributedki(kay->cp, &sak_ki);
+       ieee802_1x_cp_set_distributedan(kay->cp, body->dan);
+       ieee802_1x_cp_signal_newsak(kay->cp);
+       ieee802_1x_cp_sm_step(kay->cp);
 
        participant->to_use_sak = TRUE;
 
@@ -1756,12 +1730,9 @@ ieee802_1x_mka_encode_icv_body(struct ieee802_1x_mka_participant *participant,
                return -1;
        }
 
-       if (length != DEFAULT_ICV_LEN)  {
-               os_memcpy(wpabuf_put(buf, length - MKA_HDR_LEN), cmac,
-                         length - MKA_HDR_LEN);
-       } else {
-               os_memcpy(wpabuf_put(buf, length), cmac, length);
-       }
+       if (length != DEFAULT_ICV_LEN)
+               length -= MKA_HDR_LEN;
+       os_memcpy(wpabuf_put(buf, length), cmac, length);
 
        return 0;
 }
@@ -1868,77 +1839,87 @@ static int ieee802_1x_mka_decode_announce_body(
 }
 
 
+struct mka_param_body_handler {
+       int (*body_tx)(struct ieee802_1x_mka_participant *participant,
+                      struct wpabuf *buf);
+       int (*body_rx)(struct ieee802_1x_mka_participant *participant,
+                      const u8 *mka_msg, size_t msg_len);
+       int (*body_length)(struct ieee802_1x_mka_participant *participant);
+       Boolean (*body_present)(struct ieee802_1x_mka_participant *participant);
+};
+
+
 static struct mka_param_body_handler mka_body_handler[] = {
        /* basic parameter set */
        {
-               ieee802_1x_mka_encode_basic_body,
-               NULL,
-               ieee802_1x_mka_basic_body_length,
-               ieee802_1x_mka_basic_body_present
+               .body_tx      = ieee802_1x_mka_encode_basic_body,
+               .body_rx      = NULL,
+               .body_length  = ieee802_1x_mka_basic_body_length,
+               .body_present = ieee802_1x_mka_basic_body_present
        },
 
        /* live peer list parameter set */
        {
-               ieee802_1x_mka_encode_live_peer_body,
-               ieee802_1x_mka_decode_live_peer_body,
-               ieee802_1x_mka_get_live_peer_length,
-               ieee802_1x_mka_live_peer_body_present
+               .body_tx      = ieee802_1x_mka_encode_live_peer_body,
+               .body_rx      = ieee802_1x_mka_decode_live_peer_body,
+               .body_length  = ieee802_1x_mka_get_live_peer_length,
+               .body_present = ieee802_1x_mka_live_peer_body_present
        },
 
        /* potential peer list parameter set */
        {
-               ieee802_1x_mka_encode_potential_peer_body,
-               ieee802_1x_mka_decode_potential_peer_body,
-               ieee802_1x_mka_get_potential_peer_length,
-               ieee802_1x_mka_potential_peer_body_present
+               .body_tx      = ieee802_1x_mka_encode_potential_peer_body,
+               .body_rx      = ieee802_1x_mka_decode_potential_peer_body,
+               .body_length  = ieee802_1x_mka_get_potential_peer_length,
+               .body_present = ieee802_1x_mka_potential_peer_body_present
        },
 
        /* sak use parameter set */
        {
-               ieee802_1x_mka_encode_sak_use_body,
-               ieee802_1x_mka_decode_sak_use_body,
-               ieee802_1x_mka_get_sak_use_length,
-               ieee802_1x_mka_sak_use_body_present
+               .body_tx      = ieee802_1x_mka_encode_sak_use_body,
+               .body_rx      = ieee802_1x_mka_decode_sak_use_body,
+               .body_length  = ieee802_1x_mka_get_sak_use_length,
+               .body_present = ieee802_1x_mka_sak_use_body_present
        },
 
        /* distribute sak parameter set */
        {
-               ieee802_1x_mka_encode_dist_sak_body,
-               ieee802_1x_mka_decode_dist_sak_body,
-               ieee802_1x_mka_get_dist_sak_length,
-               ieee802_1x_mka_dist_sak_body_present
+               .body_tx      = ieee802_1x_mka_encode_dist_sak_body,
+               .body_rx      = ieee802_1x_mka_decode_dist_sak_body,
+               .body_length  = ieee802_1x_mka_get_dist_sak_length,
+               .body_present = ieee802_1x_mka_dist_sak_body_present
        },
 
        /* distribute cak parameter set */
        {
-               NULL,
-               ieee802_1x_mka_decode_dist_cak_body,
-               NULL,
-               NULL
+               .body_tx      = NULL,
+               .body_rx      = ieee802_1x_mka_decode_dist_cak_body,
+               .body_length  = NULL,
+               .body_present = NULL
        },
 
        /* kmd parameter set */
        {
-               NULL,
-               ieee802_1x_mka_decode_kmd_body,
-               NULL,
-               NULL
+               .body_tx      = NULL,
+               .body_rx      = ieee802_1x_mka_decode_kmd_body,
+               .body_length  = NULL,
+               .body_present = NULL
        },
 
        /* announce parameter set */
        {
-               NULL,
-               ieee802_1x_mka_decode_announce_body,
-               NULL,
-               NULL
+               .body_tx      = NULL,
+               .body_rx      = ieee802_1x_mka_decode_announce_body,
+               .body_length  = NULL,
+               .body_present = NULL
        },
 
        /* icv parameter set */
        {
-               ieee802_1x_mka_encode_icv_body,
-               NULL,
-               ieee802_1x_mka_get_icv_length,
-               ieee802_1x_mka_icv_body_present
+               .body_tx      = ieee802_1x_mka_encode_icv_body,
+               .body_rx      = NULL,
+               .body_length  = ieee802_1x_mka_get_icv_length,
+               .body_present = ieee802_1x_mka_icv_body_present
        },
 };
 
@@ -2060,8 +2041,8 @@ ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
                    conf->key, conf->key_len);
 
        os_memcpy(conf->ki.mi, participant->mi, MI_LEN);
-       conf->ki.kn = participant->kay->dist_kn;
-       conf->an = participant->kay->dist_an;
+       conf->ki.kn = kay->dist_kn;
+       conf->an = kay->dist_an;
        conf->offset = kay->macsec_confidentiality;
        conf->rx = TRUE;
        conf->tx = TRUE;
@@ -2076,7 +2057,7 @@ ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
        participant->new_key = sa_key;
 
        dl_list_add(&participant->sak_list, &sa_key->list);
-       ieee802_1x_cp_set_ciphersuite(participant->kay->cp,
+       ieee802_1x_cp_set_ciphersuite(kay->cp,
                                      cipher_suite_tbl[kay->macsec_csindex].id);
        ieee802_1x_cp_sm_step(kay->cp);
        ieee802_1x_cp_set_offset(kay->cp, conf->offset);
@@ -2090,12 +2071,12 @@ ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
                         struct ieee802_1x_kay_peer, list)
                peer->sak_used = FALSE;
 
-       participant->kay->dist_kn++;
-       participant->kay->dist_an++;
-       if (participant->kay->dist_an > 3)
-               participant->kay->dist_an = 0;
+       kay->dist_kn++;
+       kay->dist_an++;
+       if (kay->dist_an > 3)
+               kay->dist_an = 0;
 
-       participant->kay->dist_time = time(NULL);
+       kay->dist_time = time(NULL);
 
        os_free(conf->key);
        os_free(conf);
@@ -2104,6 +2085,18 @@ ieee802_1x_kay_generate_new_sak(struct ieee802_1x_mka_participant *participant)
 }
 
 
+static int compare_priorities(const struct ieee802_1x_kay_peer *peer,
+                             const struct ieee802_1x_kay_peer *other)
+{
+       if (peer->key_server_priority < other->key_server_priority)
+               return -1;
+       if (other->key_server_priority < peer->key_server_priority)
+               return 1;
+
+       return os_memcmp(peer->sci.addr, other->sci.addr, ETH_ALEN);
+}
+
+
 /**
  * ieee802_1x_kay_elect_key_server - elect the key server
  * when to elect: whenever the live peers list changes
@@ -2134,29 +2127,19 @@ ieee802_1x_kay_elect_key_server(struct ieee802_1x_mka_participant *participant)
                        continue;
                }
 
-               if (peer->key_server_priority <
-                   key_server->key_server_priority) {
+               if (compare_priorities(peer, key_server) < 0)
                        key_server = peer;
-               } else if (peer->key_server_priority ==
-                          key_server->key_server_priority) {
-                       if (os_memcmp(peer->sci.addr, key_server->sci.addr,
-                                     ETH_ALEN) < 0)
-                               key_server = peer;
-               }
        }
 
        /* elect the key server between me and the above elected peer */
        i_is_key_server = FALSE;
        if (key_server && participant->can_be_key_server) {
-               if (kay->actor_priority
-                          < key_server->key_server_priority) {
+               struct ieee802_1x_kay_peer tmp;
+
+               tmp.key_server_priority = kay->actor_priority;
+               os_memcpy(&tmp.sci, &kay->actor_sci, sizeof(tmp.sci));
+               if (compare_priorities(&tmp, key_server) < 0)
                        i_is_key_server = TRUE;
-               } else if (kay->actor_priority
-                                       == key_server->key_server_priority) {
-                       if (os_memcmp(kay->actor_sci.addr, key_server->sci.addr,
-                                     ETH_ALEN) < 0)
-                               i_is_key_server = TRUE;
-               }
        } else if (participant->can_be_key_server) {
                i_is_key_server = TRUE;
        }
@@ -2372,27 +2355,16 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
        participant = (struct ieee802_1x_mka_participant *)eloop_ctx;
        kay = participant->kay;
        if (participant->cak_life) {
-               if (now > participant->cak_life) {
-                       kay->authenticated = FALSE;
-                       kay->secured = FALSE;
-                       kay->failed = TRUE;
-                       ieee802_1x_kay_delete_mka(kay, &participant->ckn);
-                       return;
-               }
+               if (now > participant->cak_life)
+                       goto delete_mka;
        }
 
        /* should delete MKA instance if there are not live peers
         * when the MKA life elapsed since its creating */
        if (participant->mka_life) {
                if (dl_list_empty(&participant->live_peers)) {
-                       if (now > participant->mka_life) {
-                               kay->authenticated = FALSE;
-                               kay->secured = FALSE;
-                               kay->failed = TRUE;
-                               ieee802_1x_kay_delete_mka(kay,
-                                                         &participant->ckn);
-                               return;
-                       }
+                       if (now > participant->mka_life)
+                               goto delete_mka;
                } else {
                        participant->mka_life = 0;
                }
@@ -2480,6 +2452,14 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
        eloop_register_timeout(MKA_HELLO_TIME / 1000, 0,
                               ieee802_1x_participant_timer,
                               participant, NULL);
+
+       return;
+
+delete_mka:
+       kay->authenticated = FALSE;
+       kay->secured = FALSE;
+       kay->failed = TRUE;
+       ieee802_1x_kay_delete_mka(kay, &participant->ckn);
 }
 
 
@@ -2907,13 +2887,13 @@ static int ieee802_1x_kay_mkpdu_sanity_check(struct ieee802_1x_kay *kay,
                return -1;
        }
 
-       /* MKPDU should not less than 32 octets */
+       /* MKPDU should not be less than 32 octets */
        mka_msg_len = be_to_host16(eapol_hdr->length);
        if (mka_msg_len < 32) {
                wpa_printf(MSG_MSGDUMP, "KaY: MKPDU is less than 32 octets");
                return -1;
        }
-       /* MKPDU should multiple 4 octets */
+       /* MKPDU should be a multiple of 4 octets */
        if ((mka_msg_len % 4) != 0) {
                wpa_printf(MSG_MSGDUMP,
                           "KaY: MKPDU is not multiple of 4 octets");
@@ -2959,21 +2939,19 @@ static int ieee802_1x_kay_mkpdu_sanity_check(struct ieee802_1x_kay *kay,
                wpa_printf(MSG_ERROR, "KaY: omac1_aes_128 failed");
                return -1;
        }
+
        msg_icv = ieee802_1x_mka_decode_icv_body(participant, (u8 *) mka_hdr,
                                                 mka_msg_len);
-
-       if (msg_icv) {
-               if (os_memcmp_const(msg_icv, icv,
-                                   mka_alg_tbl[kay->mka_algindex].icv_len) !=
-                   0) {
-                       wpa_printf(MSG_ERROR,
-                                  "KaY: Computed ICV is not equal to Received ICV");
-               return -1;
-               }
-       } else {
+       if (!msg_icv) {
                wpa_printf(MSG_ERROR, "KaY: No ICV");
                return -1;
        }
+       if (os_memcmp_const(msg_icv, icv,
+                           mka_alg_tbl[kay->mka_algindex].icv_len) != 0) {
+               wpa_printf(MSG_ERROR,
+                          "KaY: Computed ICV is not equal to Received ICV");
+               return -1;
+       }
 
        return 0;
 }
@@ -2992,7 +2970,6 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
        u8 body_type;
        int i;
        const u8 *pos;
-       Boolean my_included;
        Boolean handled[256];
 
        if (ieee802_1x_kay_mkpdu_sanity_check(kay, buf, len))
@@ -3013,21 +2990,10 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
        left_len -= body_len + MKA_HDR_LEN;
 
        /* check i am in the peer's peer list */
-       my_included = ieee802_1x_mka_i_in_peerlist(participant, pos, left_len);
-       if (my_included) {
+       if (ieee802_1x_mka_i_in_peerlist(participant, pos, left_len) &&
+           !ieee802_1x_kay_is_in_live_peer(participant,
+                                           participant->current_peer_id.mi)) {
                /* accept the peer as live peer */
-               if (!ieee802_1x_kay_is_in_peer(
-                           participant,
-                           participant->current_peer_id.mi)) {
-                       if (!ieee802_1x_kay_create_live_peer(
-                                   participant,
-                                   participant->current_peer_id.mi,
-                                   be_to_host32(
-                                           participant->current_peer_id.mn)))
-                               return -1;
-                       ieee802_1x_kay_elect_key_server(participant);
-                       ieee802_1x_kay_decide_macsec_use(participant);
-               }
                if (ieee802_1x_kay_is_in_potential_peer(
                            participant, participant->current_peer_id.mi)) {
                        if (!ieee802_1x_kay_move_live_peer(
@@ -3036,9 +3002,15 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
                                    be_to_host32(participant->
                                                 current_peer_id.mn)))
                                return -1;
-                       ieee802_1x_kay_elect_key_server(participant);
-                       ieee802_1x_kay_decide_macsec_use(participant);
+               } else if (!ieee802_1x_kay_create_live_peer(
+                                  participant, participant->current_peer_id.mi,
+                                  be_to_host32(participant->
+                                               current_peer_id.mn))) {
+                               return -1;
                }
+
+               ieee802_1x_kay_elect_key_server(participant);
+               ieee802_1x_kay_decide_macsec_use(participant);
        }
 
        /*
@@ -3524,14 +3496,15 @@ ieee802_1x_kay_new_sak(struct ieee802_1x_kay *kay)
  * ieee802_1x_kay_change_cipher_suite -
  */
 int
-ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay, int cs_index)
+ieee802_1x_kay_change_cipher_suite(struct ieee802_1x_kay *kay,
+                                  unsigned int cs_index)
 {
        struct ieee802_1x_mka_participant *participant;
 
        if (!kay)
                return -1;
 
-       if ((unsigned int) cs_index >= CS_TABLE_SIZE) {
+       if (cs_index >= CS_TABLE_SIZE) {
                wpa_printf(MSG_ERROR,
                           "KaY: Configured cipher suite index is out of range");
                return -1;