X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=src%2Fpae%2Fieee802_1x_kay.c;h=9bb4a949408bc4597010efa9ebe01d9fd82cdeaa;hb=07a6bfe1d2f13ac31cfc2c5b5e15db3feda52e9b;hp=3a93323e36d789d0899f48c6eeb401854d5f8165;hpb=8b4a14884275418b561c30747e3831bcc185644a;p=mech_eap.git diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c index 3a93323..9bb4a94 100644 --- a/src/pae/ieee802_1x_kay.c +++ b/src/pae/ieee802_1x_kay.c @@ -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;