Skip to content

Commit

Permalink
On startup deletes NVM GTKs if EUI-64 has been changed (ARMmbed#2576)
Browse files Browse the repository at this point in the history
BR and node now stores the EUI-64 with GTK to NVM so that when storage
is read, the current EUI-64 can be compared to the stored one.
  • Loading branch information
Mika Leppänen authored Mar 4, 2021
1 parent 509a6f9 commit a87646d
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 16 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
### Changes
* Added throttling of number of simultaneous EAPOL authentications based on Border Router TX queue size
* Domain configuration functions implemented. Replacing existing PHY mode ID and channel plan ID set functions.
* Added EAPOL authentication waiting queue to Border Router. Queue makes it possible to start new authentication faster after previous authentication has completed.
* Added EAPOL authentication waiting queue to Border Router. Queue makes it possible to start new authentication faster after previous authentication has completed.
* On startup deletes NVM GTKs if EUI-64 has been changed.

### Bugfix
* All MAC TX failure causes now trigger target change on supplicant EAPOL inititial-key sending
Expand Down
39 changes: 30 additions & 9 deletions source/6LoWPAN/ws/ws_pae_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ static int8_t ws_pae_controller_frame_counter_read(pae_controller_t *controller)
static void ws_pae_controller_frame_counter_reset(frame_counters_t *frame_counters);
static void ws_pae_controller_frame_counter_index_reset(frame_counters_t *frame_counters, uint8_t index);
static int8_t ws_pae_controller_nw_info_read(pae_controller_t *controller, sec_prot_gtk_keys_t *gtks);
static int8_t ws_pae_controller_nvm_nw_info_write(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name, sec_prot_gtk_keys_t *gtks);
static int8_t ws_pae_controller_nvm_nw_info_read(protocol_interface_info_entry_t *interface_ptr, uint16_t *pan_id, char *network_name, sec_prot_gtk_keys_t *gtks);
static int8_t ws_pae_controller_nvm_nw_info_write(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks);
static int8_t ws_pae_controller_nvm_nw_info_read(protocol_interface_info_entry_t *interface_ptr, uint16_t *pan_id, char *network_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks);


static const char *FRAME_COUNTER_FILE = FRAME_COUNTER_FILE_NAME;
Expand Down Expand Up @@ -371,7 +371,13 @@ static void ws_pae_controller_nw_info_updated_check(protocol_interface_info_entr
}

if (controller->sec_keys_nw_info.updated || sec_prot_keys_gtks_are_updated(controller->sec_keys_nw_info.gtks)) {
ws_pae_controller_nvm_nw_info_write(interface_ptr, controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.network_name, controller->sec_keys_nw_info.gtks);
// Get own EUI-64
uint8_t gtk_eui64[8] = {0};
link_layer_address_s mac_params;
if (arm_nwk_mac_address_read(interface_ptr->id, &mac_params) >= 0) {
memcpy(gtk_eui64, mac_params.mac_long, 8);
}
ws_pae_controller_nvm_nw_info_write(interface_ptr, controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.network_name, gtk_eui64, controller->sec_keys_nw_info.gtks);
controller->sec_keys_nw_info.updated = false;
sec_prot_keys_gtks_updated_reset(controller->sec_keys_nw_info.gtks);
}
Expand Down Expand Up @@ -844,32 +850,46 @@ static void ws_pae_controller_frame_counter_index_reset(frame_counters_t *frame_

static int8_t ws_pae_controller_nw_info_read(pae_controller_t *controller, sec_prot_gtk_keys_t *gtks)
{
if (ws_pae_controller_nvm_nw_info_read(controller->interface_ptr, &controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.network_name, gtks) < 0) {
uint8_t nvm_gtk_eui64[8];
if (ws_pae_controller_nvm_nw_info_read(controller->interface_ptr, &controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.network_name, nvm_gtk_eui64, gtks) < 0) {
// If no stored GTKs and network info (pan_id and network name) exits
return -1;
}

/* Get own EUI-64 and compare to the one read from the NVM. In case of mismatch delete GTKs and make
full authentication to update keys with new EUI-64 and in case of authenticator to update new
authenticator EUI-64 to the network. */
uint8_t gtk_eui64[8] = {0};
link_layer_address_s mac_params;
if (arm_nwk_mac_address_read(controller->interface_ptr->id, &mac_params) >= 0) {
memcpy(gtk_eui64, mac_params.mac_long, 8);
}
if (memcmp(nvm_gtk_eui64, gtk_eui64, 8) != 0) {
tr_warn("NVM EUI-64 mismatch, current: %s stored: %s", tr_array(gtk_eui64, 8), tr_array(nvm_gtk_eui64, 8));
sec_prot_keys_gtks_clear(gtks);
}

// Sets also new pan_id used for pan_id set by bootstrap
controller->sec_keys_nw_info.new_pan_id = controller->sec_keys_nw_info.key_pan_id;

return 0;
}

static int8_t ws_pae_controller_nvm_nw_info_write(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name, sec_prot_gtk_keys_t *gtks)
static int8_t ws_pae_controller_nvm_nw_info_write(protocol_interface_info_entry_t *interface_ptr, uint16_t pan_id, char *network_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks)
{
nw_info_nvm_tlv_t *tlv = (nw_info_nvm_tlv_t *) ws_pae_controller_nvm_tlv_get(interface_ptr);
if (!tlv) {
return -1;
}

ws_pae_nvm_store_nw_info_tlv_create(tlv, pan_id, network_name, gtks);
ws_pae_nvm_store_nw_info_tlv_create(tlv, pan_id, network_name, gtk_eui64, gtks);

ws_pae_nvm_store_tlv_file_write(NW_INFO_FILE, (nvm_tlv_t *) tlv);

return 0;
}

static int8_t ws_pae_controller_nvm_nw_info_read(protocol_interface_info_entry_t *interface_ptr, uint16_t *pan_id, char *network_name, sec_prot_gtk_keys_t *gtks)
static int8_t ws_pae_controller_nvm_nw_info_read(protocol_interface_info_entry_t *interface_ptr, uint16_t *pan_id, char *network_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks)
{
nw_info_nvm_tlv_t *tlv_entry = (nw_info_nvm_tlv_t *) ws_pae_controller_nvm_tlv_get(interface_ptr);
if (!tlv_entry) {
Expand All @@ -882,7 +902,7 @@ static int8_t ws_pae_controller_nvm_nw_info_read(protocol_interface_info_entry_t
return -1;
}

if (ws_pae_nvm_store_nw_info_tlv_read(tlv_entry, pan_id, network_name, gtks) < 0) {
if (ws_pae_nvm_store_nw_info_tlv_read(tlv_entry, pan_id, network_name, gtk_eui64, gtks) < 0) {
return -1;
}

Expand Down Expand Up @@ -964,7 +984,8 @@ int8_t ws_pae_controller_auth_init(protocol_interface_info_entry_t *interface_pt
}
if (!read_gtks_to || sec_prot_keys_gtk_count(read_gtks_to) == 0) {
// Key material invalid or GTKs are expired, delete GTKs from NVM
ws_pae_controller_nvm_nw_info_write(controller->interface_ptr, controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.network_name, NULL);
uint8_t gtk_eui64[8] = {0}; // Set GTK EUI-64 to zero
ws_pae_controller_nvm_nw_info_write(controller->interface_ptr, controller->sec_keys_nw_info.key_pan_id, controller->sec_keys_nw_info.network_name, gtk_eui64, NULL);
}
}

Expand Down
10 changes: 8 additions & 2 deletions source/6LoWPAN/ws/ws_pae_nvm_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void ws_pae_nvm_store_generic_tlv_free(nvm_tlv_t *tlv_entry)
ns_dyn_mem_free(tlv_entry);
}

void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks)
void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t pan_id, char *nw_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks)
{
int len;
tlv_entry->tag = PAE_NVM_NW_INFO_TAG;
Expand All @@ -87,6 +87,9 @@ void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t
memcpy((char *)tlv, nw_name, len);
tlv += 33;

memcpy((char *)tlv, gtk_eui64, 8);
tlv += 8;

uint64_t current_time = ws_pae_current_time_get();

for (uint8_t i = 0; i < GTK_NUM; i++) {
Expand Down Expand Up @@ -119,7 +122,7 @@ void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t

}

int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t *pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks)
int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t *pan_id, char *nw_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks)
{
if (!tlv_entry || !pan_id || !nw_name) {
return -1;
Expand All @@ -144,6 +147,9 @@ int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t
}
tlv += 33;

memcpy(gtk_eui64, (char *)tlv, 8);
tlv += 8;

uint64_t current_time = ws_pae_current_time_get();

tr_debug("NVM NW_INFO current time: %"PRIi64, current_time);
Expand Down
8 changes: 4 additions & 4 deletions source/6LoWPAN/ws/ws_pae_nvm_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
#define PAE_NVM_KEY_STORAGE_INDEX_TAG 4
#define PAE_NVM_KEY_STORAGE_TAG 5

// pan_id (2) + network name (33) + (GTK set (1) + GTK expiry timestamp (8) + status (1) + install order (1) + GTK (16)) * 4
#define PAE_NVM_NW_INFO_LEN 2 + 33 + (1 + 8 + 1 + 1 + GTK_LEN) * GTK_NUM
// pan_id (2) + network name (33) + GTK EUI-64 (own EUI-64) (8) + (GTK set (1) + GTK expiry timestamp (8) + status (1) + install order (1) + GTK (16)) * 4
#define PAE_NVM_NW_INFO_LEN 2 + 33 + 8 + (1 + 8 + 1 + 1 + GTK_LEN) * GTK_NUM

// PTK EUI-64 set (1) + PTK EUI-64 (8) + PMK set (1) + PMK lifetime (4) + PMK (32) + PMK replay counter (8) + PTK set (1) + PTK lifetime (4) + PTK (48)
#define PAE_NVM_KEYS_LEN 1 + 8 + 1 + 4 + PMK_LEN + 8 + 1 + 4 + PTK_LEN
Expand Down Expand Up @@ -95,7 +95,7 @@ void ws_pae_nvm_store_generic_tlv_free(nvm_tlv_t *tlv_entry);
* \return TLV entry or NULL
*
*/
void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks);
void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t pan_id, char *nw_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks);

/**
* ws_pae_nvm_store_nw_info_tlv_read read from NVM network info TLV
Expand All @@ -109,7 +109,7 @@ void ws_pae_nvm_store_nw_info_tlv_create(nw_info_nvm_tlv_t *tlv_entry, uint16_t
* \return >= 0 success
*
*/
int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t *pan_id, char *nw_name, sec_prot_gtk_keys_t *gtks);
int8_t ws_pae_nvm_store_nw_info_tlv_read(nw_info_nvm_tlv_t *tlv_entry, uint16_t *pan_id, char *nw_name, uint8_t *gtk_eui64, sec_prot_gtk_keys_t *gtks);

/**
* ws_pae_nvm_store_keys_tlv_create create NVM keys TLV
Expand Down

0 comments on commit a87646d

Please sign in to comment.