diff --git a/source/6LoWPAN/ws/ws_bootstrap.c b/source/6LoWPAN/ws/ws_bootstrap.c index c4b99a22a50..782ab8dcf17 100644 --- a/source/6LoWPAN/ws/ws_bootstrap.c +++ b/source/6LoWPAN/ws/ws_bootstrap.c @@ -2279,8 +2279,8 @@ static void ws_bootstrap_rpl_callback(rpl_event_t event, void *handle) ws_eapol_relay_start(cur, EAPOL_RELAY_SOCKET_PORT, dodag_info.dodag_id, EAPOL_RELAY_SOCKET_PORT); // Set network information to PAE ws_pae_controller_nw_info_set(cur, cur->ws_info->network_pan_id, cur->ws_info->cfg->gen.network_name); - // Network key is valid - ws_pae_controller_nw_key_valid(cur); + // Network key is valid, indicate border router IID to controller + ws_pae_controller_nw_key_valid(cur, &dodag_info.dodag_id[8]); // After successful DAO ACK connection to border router is verified cur->ws_info->pan_timeout_timer = cur->ws_info->cfg->timing.pan_timeout; diff --git a/source/6LoWPAN/ws/ws_pae_controller.c b/source/6LoWPAN/ws/ws_pae_controller.c index b13a272b8c1..05eb06983b6 100644 --- a/source/6LoWPAN/ws/ws_pae_controller.c +++ b/source/6LoWPAN/ws/ws_pae_controller.c @@ -166,7 +166,7 @@ int8_t ws_pae_controller_authenticate(protocol_interface_info_entry_t *interface return 0; } - if (ws_pae_supp_authenticate(controller->interface_ptr, controller->target_pan_id, controller->target_eui_64) < 0) { + if (ws_pae_supp_authenticate(controller->interface_ptr, controller->target_pan_id, controller->target_eui_64, controller->sec_keys_nw_info.network_name) < 0) { controller->auth_completed(interface_ptr, AUTH_RESULT_ERR_UNSPEC, controller->target_eui_64); } #endif @@ -327,7 +327,7 @@ static void ws_pae_controller_nw_info_updated_check(protocol_interface_info_entr } } -int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface_ptr) +int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface_ptr, uint8_t *br_iid) { if (!interface_ptr) { return -1; @@ -338,7 +338,7 @@ int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface return -1; } - return ws_pae_supp_nw_key_valid(interface_ptr); + return ws_pae_supp_nw_key_valid(interface_ptr, br_iid); } static int8_t ws_pae_controller_nw_key_check_and_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks) diff --git a/source/6LoWPAN/ws/ws_pae_controller.h b/source/6LoWPAN/ws/ws_pae_controller.h index 39165832e1e..2f7e01e6dff 100644 --- a/source/6LoWPAN/ws/ws_pae_controller.h +++ b/source/6LoWPAN/ws/ws_pae_controller.h @@ -249,12 +249,13 @@ int8_t ws_pae_controller_nw_info_set(protocol_interface_info_entry_t *interface_ * ws_pae_controller_nw_key_valid network key is valid i.e. used successfully on bootstrap * * \param interface_ptr interface + * \param br_iid border router IID for which the keys are valid * * \return < 0 failure * \return >= 0 success * */ -int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface_ptr); +int8_t ws_pae_controller_nw_key_valid(protocol_interface_info_entry_t *interface_ptr, uint8_t *br_iid); /** * ws_pae_controller_border_router_addr_write write border router address @@ -278,7 +279,7 @@ int8_t ws_pae_controller_border_router_addr_write(protocol_interface_info_entry_ * \return >= 0 success * */ -int8_t ws_pae_controller_border_router_addr_read(protocol_interface_info_entry_t *interface_ptr, uint8_t *eui_64); +int8_t ws_pae_controller_border_router_addr_read(protocol_interface_info_entry_t *interface_ptr, uint8_t *iid); /** * ws_pae_controller_gtk_update update GTKs (test interface) diff --git a/source/6LoWPAN/ws/ws_pae_supp.c b/source/6LoWPAN/ws/ws_pae_supp.c index e6f1ce043fc..47de492c792 100644 --- a/source/6LoWPAN/ws/ws_pae_supp.c +++ b/source/6LoWPAN/ws/ws_pae_supp.c @@ -97,7 +97,8 @@ typedef struct { uint16_t initial_key_retry_timer; /**< Timer to trigger initial EAPOL-Key 1st retry */ trickle_t auth_trickle_timer; /**< Trickle timer for re-sending initial EAPOL-key or for GTK mismatch */ trickle_params_t auth_trickle_params; /**< Trickle parameters for initial EAPOL-key or for GTK mismatch */ - uint8_t new_br_eui_64[8]; /**< Border router EUI-64 indicated by bootstrap */ + uint8_t new_br_eui_64[8]; /**< Border router EUI-64 indicated by bootstrap after bootstrap start */ + uint8_t comp_br_eui_64[8]; /**< Border router EUI-64 indicated by bootstrap after bootstrap completed */ sec_prot_keys_nw_info_t *sec_keys_nw_info; /**< Security keys network information */ sec_timer_cfg_t *sec_timer_cfg; /**< Timer configuration */ sec_prot_cfg_t *sec_prot_cfg; /**< Protocol Configuration */ @@ -106,8 +107,9 @@ typedef struct { bool auth_trickle_running : 1; /**< Initial EAPOL-Key Trickle timer running */ bool auth_requested : 1; /**< Authentication has been requested by the bootstrap */ bool timer_running : 1; /**< Timer is running */ - bool new_br_eui_64_set : 1; /**< Border router address has been set */ + bool new_br_eui_64_set : 1; /**< Border router address has been set after bootstrap start */ bool new_br_eui_64_fresh : 1; /**< Border router address is fresh (set during this authentication attempt) */ + bool comp_br_eui_64_set : 1; /**< Border router address has been set after bootstrap completed */ bool entry_address_active: 1; /**< EAPOL target address is set */ bool tx_failure_on_initial_key: 1; /**< TX failure has happened on initial EAPOL-key sequence */ } pae_supp_t; @@ -124,7 +126,7 @@ static void ws_pae_supp_free(pae_supp_t *pae_supp); static void ws_pae_supp_authenticate_response(pae_supp_t *pae_supp, auth_result_e result); static int8_t ws_pae_supp_initial_key_send(pae_supp_t *pae_supp); static void ws_pae_supp_nvm_update(pae_supp_t *pae_supp); -static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan_id); +static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan_id, char *dest_network_name); static int8_t ws_pae_supp_nvm_keys_write(pae_supp_t *pae_supp); static pae_supp_t *ws_pae_supp_get(protocol_interface_info_entry_t *interface_ptr); static int8_t ws_pae_supp_event_send(kmp_service_t *service, void *data); @@ -180,14 +182,14 @@ static bool ws_pae_supp_address_is_set(pae_supp_t *pae_supp) return pae_supp->entry_address_active; } -int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, uint16_t dest_pan_id, uint8_t *dest_eui_64) +int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, uint16_t dest_pan_id, uint8_t *dest_eui_64, char *dest_network_name) { pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); if (!pae_supp) { return -1; } - if (ws_pae_supp_nw_keys_valid_check(pae_supp, dest_pan_id) >= 0) { + if (ws_pae_supp_nw_keys_valid_check(pae_supp, dest_pan_id, dest_network_name) >= 0) { pae_supp->auth_completed(interface_ptr, AUTH_RESULT_OK, NULL); return 0; } @@ -195,9 +197,10 @@ int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, // Delete GTKs sec_prot_keys_gtks_init(pae_supp->sec_keys_nw_info->gtks); - /* PAN ID has changed, delete key data associated with border router + /* Network name or PAN ID has changed, delete key data associated with border router i.e PMK, PTK, EA-IE data (border router EUI-64) */ - if (pae_supp->sec_keys_nw_info->key_pan_id != 0xFFFF && pae_supp->sec_keys_nw_info->key_pan_id != dest_pan_id) { + if (strcmp(pae_supp->sec_keys_nw_info->network_name, dest_network_name) != 0 || + (pae_supp->sec_keys_nw_info->key_pan_id != 0xFFFF && pae_supp->sec_keys_nw_info->key_pan_id != dest_pan_id)) { sec_prot_keys_pmk_delete(&pae_supp->entry.sec_keys); sec_prot_keys_ptk_delete(&pae_supp->entry.sec_keys); sec_prot_keys_ptk_eui_64_delete(&pae_supp->entry.sec_keys); @@ -207,6 +210,7 @@ int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, // Prepare to receive new border router address pae_supp->new_br_eui_64_fresh = false; + pae_supp->comp_br_eui_64_set = false; // Stores target/parent address kmp_address_init(KMP_ADDR_EUI_64, &pae_supp->target_addr, dest_eui_64); @@ -247,9 +251,14 @@ int8_t ws_pae_supp_border_router_addr_read(protocol_interface_info_entry_t *inte return -1; } + // Check if there is border router EUI-64 on used on 4WH PTK generation uint8_t *br_eui_64 = sec_prot_keys_ptk_eui_64_get(&pae_supp->entry.sec_keys); if (!br_eui_64) { - return -1; + // Check if there is border router EUI-64 indicated by the bootstrap when bootstrap completed + if (!pae_supp->comp_br_eui_64_set) { + return -1; + } + br_eui_64 = pae_supp->comp_br_eui_64; } memcpy(eui_64, br_eui_64, 8); @@ -257,14 +266,31 @@ int8_t ws_pae_supp_border_router_addr_read(protocol_interface_info_entry_t *inte return 0; } -int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr) +int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr, uint8_t *br_iid) { pae_supp_t *pae_supp = ws_pae_supp_get(interface_ptr); if (!pae_supp) { return -1; } - tr_info("NW key valid"); + tr_info("NW key valid indication"); + + // Store border router EUI-64 received on bootstrap complete + memcpy(pae_supp->comp_br_eui_64, br_iid, 8); + pae_supp->comp_br_eui_64[0] ^= 0x02; + pae_supp->comp_br_eui_64_set = true; + + // Get the EUI-64 used on 4WH handshake PTK generation + uint8_t *ptk_eui_64 = sec_prot_keys_ptk_eui_64_get(&pae_supp->entry.sec_keys); + + /* If border router EUI-64 received on bootstrap complete does not match to + EUI-64 stored with keys, delete keys */ + if (memcmp(ptk_eui_64, pae_supp->comp_br_eui_64, 8) != 0) { + tr_warn("Delete keys: PTK EUI-64 %s does not match to BR EUI-64 %s", tr_array(ptk_eui_64, 8), tr_array(pae_supp->comp_br_eui_64, 8)); + sec_prot_keys_pmk_delete(&pae_supp->entry.sec_keys); + sec_prot_keys_ptk_delete(&pae_supp->entry.sec_keys); + sec_prot_keys_ptk_eui_64_delete(&pae_supp->entry.sec_keys); + } // Stored keys are valid pae_supp->nw_keys_used_cnt = 0; @@ -461,7 +487,7 @@ static int8_t ws_pae_supp_initial_key_send(pae_supp_t *pae_supp) return 0; } -static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan_id) +static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan_id, char *dest_network_name) { // Checks how many times authentication has been tried with current network keys if (pae_supp->nw_keys_used_cnt >= STORED_KEYS_MAXIMUM_USE_COUNT) { @@ -476,9 +502,11 @@ static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan return -1; } - /* Checks if keys match to PAN ID and that needed keys exists (PMK, PTK and a GTK), - and calls inserts function that will update the network keys as needed */ - if ((pan_id == pae_supp->sec_keys_nw_info->key_pan_id) && + /* Checks if keys match to network name and PAN ID and that needed keys exists (PMK, + PTK and a GTK), and calls inserts function that will update the network keys as + needed */ + if ((strcmp(dest_network_name, pae_supp->sec_keys_nw_info->network_name) == 0 && + pan_id == pae_supp->sec_keys_nw_info->key_pan_id) && (sec_prot_keys_gtk_count(pae_supp->sec_keys_nw_info->gtks) > 0) && (sec_prot_keys_pmk_get(&pae_supp->entry.sec_keys) != NULL) && (sec_prot_keys_ptk_get(&pae_supp->entry.sec_keys) != NULL)) { @@ -542,6 +570,7 @@ int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const se pae_supp->timer_running = false; pae_supp->new_br_eui_64_set = false; pae_supp->new_br_eui_64_fresh = false; + pae_supp->comp_br_eui_64_set = false; pae_supp->entry_address_active = false; ws_pae_lib_supp_init(&pae_supp->entry); diff --git a/source/6LoWPAN/ws/ws_pae_supp.h b/source/6LoWPAN/ws/ws_pae_supp.h index 869d31d718d..7bd20170616 100644 --- a/source/6LoWPAN/ws/ws_pae_supp.h +++ b/source/6LoWPAN/ws/ws_pae_supp.h @@ -81,13 +81,14 @@ void ws_pae_supp_slow_timer(uint16_t seconds); * \param interface_ptr interface * \param dest_pan_id EAPOL target PAN ID * \param dest_eui_64 EAPOL target + * \param dest_network_name EAPOL target network name * * \return < 0 failure * \return 0 authentication done, continue * \return > 0 authentication started * */ -int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, uint16_t dest_pan_id, uint8_t *dest_eui_64); +int8_t ws_pae_supp_authenticate(protocol_interface_info_entry_t *interface_ptr, uint16_t dest_pan_id, uint8_t *dest_eui_64, char *dest_network_name); /** * ws_pae_supp_border_router_addr_write write border router address @@ -117,12 +118,13 @@ int8_t ws_pae_supp_border_router_addr_read(protocol_interface_info_entry_t *inte * ws_pae_supp_nw_key_valid network key is valid i.e. used successfully on bootstrap * * \param interface_ptr interface + * \param br_iid border router IID for which the keys are valid * * \return < 0 failure * \return >= 0 success * */ -int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr); +int8_t ws_pae_supp_nw_key_valid(protocol_interface_info_entry_t *interface_ptr, uint8_t *br_iid); /** * ws_pae_supp_gtk_hash_update GTK hash has been updated (on PAN configuration)