Skip to content

Commit 95c506a

Browse files
author
Mika Leppänen
authored
Frame counters for nw keys are now stored to NVM only after send key is set (ARMmbed#2641)
* Frame counters for nw keys are now stored to NVM only after send key is set This way if the device resets right after startup, frame counters are not incremented to NVM, which could lead to frame counter are exhaustion.
1 parent 3b3010a commit 95c506a

File tree

3 files changed

+23
-25
lines changed

3 files changed

+23
-25
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
* Statistics for MAC data request latencies. Separated to adaptation layer and MAC queueing delays.
1414
* Changed initial EAPOL-key retries from trickle to exponential backup.
1515
* Adjusted stagger random from [min,max] to [min,min+max] and for small networks set the stagger value to 10 seconds.
16+
* Frame counter values for network keys are now stored to NVM only after network key for sending is set.
1617

1718
### Bug fixes
1819
* Added ignoring of retry messages from RADIUS server when waiting EAP-TLS

source/6LoWPAN/ws/ws_pae_controller.c

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ static bool ws_pae_controller_auth_congestion_get(protocol_interface_info_entry_
122122
#endif
123123
static pae_controller_t *ws_pae_controller_get(protocol_interface_info_entry_t *interface_ptr);
124124
static void ws_pae_controller_frame_counter_timer(uint16_t seconds, pae_controller_t *entry);
125-
static void ws_pae_controller_frame_counter_timer_trigger(uint16_t seconds, pae_controller_t *entry);
126125
static void ws_pae_controller_frame_counter_store(pae_controller_t *entry, bool use_threshold);
127126
static void ws_pae_controller_nvm_frame_counter_write(frame_cnt_nvm_tlv_t *tlv_entry);
128127
static int8_t ws_pae_controller_nvm_frame_counter_read(uint32_t *restart_cnt, uint64_t *stored_time, uint16_t *pan_version, frame_counters_t *counters);
@@ -516,10 +515,6 @@ static int8_t ws_pae_controller_nw_key_check_and_insert(protocol_interface_info_
516515
controller->nw_frame_counter_set(controller->interface_ptr, curr_frame_counter, i);
517516
}
518517
}
519-
/* Trigger storing of frame counters; there is 5 seconds delay to give time for the
520-
other keys to be inserted, so that frame counters for several keys are updated on
521-
a same time. */
522-
ws_pae_controller_frame_counter_timer_trigger(FRAME_COUNTER_STORE_TRIGGER, controller);
523518
}
524519
}
525520

@@ -614,6 +609,8 @@ static void ws_pae_controller_frame_counter_store_and_nw_keys_remove(protocol_in
614609

615610
tr_info("NW keys remove");
616611

612+
controller->gtk_index = -1;
613+
617614
nw_key_t *nw_key = controller->nw_key;
618615
for (uint8_t i = 0; i < GTK_NUM; i++) {
619616
// Deletes the key if it is set
@@ -637,9 +634,12 @@ static void ws_pae_controller_nw_key_index_check_and_set(protocol_interface_info
637634
}
638635

639636
if (controller->nw_send_key_index_set) {
637+
controller->gtk_index = index;
638+
/* Checks if frame counters needs to be stored for the new GTK that is taken into
639+
use; this is the last check that stored counters are in sync before activating key */
640+
ws_pae_controller_frame_counter_store(controller, true);
640641
tr_info("NW send key index set: %i", index + 1);
641642
controller->nw_send_key_index_set(interface_ptr, index);
642-
controller->gtk_index = index;
643643
}
644644

645645
// Do not update PAN version for initial key index set
@@ -661,13 +661,14 @@ static void ws_pae_controller_active_nw_key_set(protocol_interface_info_entry_t
661661
}
662662

663663
if (controller->nw_send_key_index_set) {
664+
controller->gtk_index = index;
664665
/* Checks if frame counters needs to be stored for the new GTK that is taken into
665666
use; this is the last check that stored counters are in sync before activating key */
666667
ws_pae_controller_frame_counter_store(controller, true);
667668
// Activates key on MAC
668669
controller->nw_send_key_index_set(controller->interface_ptr, index);
669670
tr_info("NW send key index set: %i", index + 1);
670-
controller->gtk_index = index;
671+
671672
}
672673
}
673674

@@ -801,7 +802,6 @@ static int8_t ws_pae_controller_frame_counter_read(pae_controller_t *controller)
801802
// Increments PAN version to ensure that it is fresh
802803
controller->sec_keys_nw_info.pan_version += PAN_VERSION_STORAGE_READ_INCREMENT;
803804

804-
bool updated = false;
805805
// Checks frame counters
806806
for (uint8_t index = 0; index < GTK_NUM; index++) {
807807
if (controller->frame_counters.counter[index].set) {
@@ -817,15 +817,8 @@ static int8_t ws_pae_controller_frame_counter_read(pae_controller_t *controller)
817817
controller->frame_counters.counter[index].frame_counter;
818818

819819
tr_info("Read frame counter: index %i value %"PRIu32"", index, controller->frame_counters.counter[index].frame_counter);
820-
821-
updated = true;
822820
}
823821
}
824-
if (updated) {
825-
// Writes incremented frame counters
826-
ws_pae_nvm_store_frame_counter_tlv_create((frame_cnt_nvm_tlv_t *) &controller->pae_nvm_buffer, controller->restart_cnt, controller->sec_keys_nw_info.pan_version, &controller->frame_counters);
827-
ws_pae_controller_nvm_frame_counter_write((frame_cnt_nvm_tlv_t *) &controller->pae_nvm_buffer);
828-
}
829822
}
830823

831824
return ret_value;
@@ -836,6 +829,7 @@ static void ws_pae_controller_frame_counter_reset(frame_counters_t *frame_counte
836829
for (uint8_t index = 0; index < GTK_NUM; index++) {
837830
ws_pae_controller_frame_counter_index_reset(frame_counters, index);
838831
}
832+
frame_counters->active_gtk_index = -1;
839833
}
840834

841835
static void ws_pae_controller_frame_counter_index_reset(frame_counters_t *frame_counters, uint8_t index)
@@ -1712,13 +1706,6 @@ static void ws_pae_controller_frame_counter_timer(uint16_t seconds, pae_controll
17121706
}
17131707
}
17141708

1715-
static void ws_pae_controller_frame_counter_timer_trigger(uint16_t seconds, pae_controller_t *entry)
1716-
{
1717-
if (entry->frame_cnt_store_timer > seconds) {
1718-
entry->frame_cnt_store_timer = seconds;
1719-
}
1720-
}
1721-
17221709
static void ws_pae_controller_frame_counter_store(pae_controller_t *entry, bool use_threshold)
17231710
{
17241711
bool update_needed = false;
@@ -1731,7 +1718,7 @@ static void ws_pae_controller_frame_counter_store(pae_controller_t *entry, bool
17311718
* frame counters will be still valid.
17321719
*/
17331720
if (entry->nw_key[i].installed) {
1734-
// Reads frame counter for the key
1721+
// Reads MAC frame counter for the key
17351722
uint32_t curr_frame_counter;
17361723
entry->nw_frame_counter_read(entry->interface_ptr, &curr_frame_counter, i);
17371724

@@ -1752,13 +1739,22 @@ static void ws_pae_controller_frame_counter_store(pae_controller_t *entry, bool
17521739
tr_debug("Stored updated frame counter: index %i value %"PRIu32"", i, frame_counter);
17531740
}
17541741
} else {
1755-
// For new or modified network keys, stores the frame counter value
1742+
// New or modified network key
17561743
entry->frame_counters.counter[i].set = true;
17571744
memcpy(entry->frame_counters.counter[i].gtk, entry->nw_key[i].gtk, GTK_LEN);
17581745
entry->frame_counters.counter[i].frame_counter = curr_frame_counter;
17591746
entry->frame_counters.counter[i].stored_frame_counter = curr_frame_counter;
1747+
tr_debug("Pending to store new frame counter: index %i value %"PRIu32"", i, curr_frame_counter);
1748+
}
1749+
1750+
/* If currently active key is changed or active key is set for the first time,
1751+
stores the frame counter value */
1752+
if (entry->gtk_index == i && entry->frame_counters.active_gtk_index != i) {
1753+
entry->frame_counters.active_gtk_index = entry->gtk_index;
17601754
update_needed = true;
1761-
tr_debug("Stored new frame counter: index %i value %"PRIu32"", i, curr_frame_counter);
1755+
// Updates MAC frame counter for the key
1756+
entry->nw_frame_counter_set(entry->interface_ptr, entry->frame_counters.counter[i].frame_counter, i);
1757+
tr_debug("Stored frame counters, active key set: index %i value %"PRIu32"", i, entry->frame_counters.counter[i].frame_counter);
17621758
}
17631759
}
17641760
}

source/Security/protocols/sec_prot_keys.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ typedef struct {
114114

115115
typedef struct {
116116
frame_counter_t counter[GTK_NUM]; /**< Frame counter for each GTK key */
117+
int8_t active_gtk_index; /**< Active GTK index */
117118
} frame_counters_t;
118119

119120
// Authenticator supplicant security key data

0 commit comments

Comments
 (0)