Skip to content

Commit 5c2fc55

Browse files
author
Mika Leppänen
committed
Corrected frame counter handling on re-discovery
Frame counters were not correctly set when key was inserted after re-discovery (where it had been removed from MAC). Now there are own values for stored and current frame counters to fix that. Also added check that frame counters are read only once from nvm.
1 parent 9307416 commit 5c2fc55

File tree

2 files changed

+28
-9
lines changed

2 files changed

+28
-9
lines changed

source/6LoWPAN/ws/ws_pae_controller.c

+26-8
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ typedef struct {
8888
bool gtks_set : 1; /**< GTKs are set */
8989
bool gtkhash_set : 1; /**< GTK hashes are set */
9090
bool key_index_set : 1; /**< NW key index is set */
91+
bool frame_counter_read : 1; /**< Frame counters has been read */
9192
} pae_controller_t;
9293

9394
typedef struct {
@@ -380,9 +381,11 @@ static int8_t ws_pae_controller_nw_key_check_and_insert(protocol_interface_info_
380381
// Read current counter from MAC
381382
uint32_t curr_frame_counter;
382383
controller->nw_frame_counter_read(controller->interface_ptr, &curr_frame_counter, i);
384+
383385
// If stored frame counter is greater than MAC counter
384386
if (controller->frame_counters.counter[i].frame_counter > curr_frame_counter) {
385-
tr_debug("Frame counter set: %i, stored %"PRIu32" current: %"PRIu32"", i, controller->frame_counters.counter[i].frame_counter, curr_frame_counter);
387+
tr_debug("Frame counter set: %i, stored %"PRIu32" current: %"PRIu32"", i,
388+
controller->frame_counters.counter[i].frame_counter, curr_frame_counter);
386389
curr_frame_counter = controller->frame_counters.counter[i].frame_counter;
387390
// Updates MAC frame counter
388391
controller->nw_frame_counter_set(controller->interface_ptr, curr_frame_counter, i);
@@ -474,6 +477,9 @@ void ws_pae_controller_nw_keys_remove(protocol_interface_info_entry_t *interface
474477
return;
475478
}
476479

480+
/* Checks if frame counters needs to be stored when keys are removed */
481+
ws_pae_controller_frame_counter_store(controller, true);
482+
477483
tr_info("NW keys remove");
478484

479485
nw_key_t *nw_key = controller->nw_key;
@@ -589,6 +595,7 @@ static void ws_pae_controller_data_init(pae_controller_t *controller)
589595
controller->gtks_set = false;
590596
controller->gtkhash_set = false;
591597
controller->key_index_set = false;
598+
controller->frame_counter_read = false;
592599
controller->gtk_index = -1;
593600
controller->network_name = NULL;
594601
controller->frame_cnt_store_timer = FRAME_COUNTER_STORE_INTERVAL;
@@ -602,6 +609,11 @@ static void ws_pae_controller_data_init(pae_controller_t *controller)
602609

603610
static void ws_pae_controller_frame_counter_read(pae_controller_t *controller)
604611
{
612+
if (controller->frame_counter_read) {
613+
return;
614+
}
615+
controller->frame_counter_read = true;
616+
605617
// Read frame counters
606618
if (ws_pae_controller_nvm_frame_counter_read(&controller->frame_counters) >= 0) {
607619
bool updated = false;
@@ -610,6 +622,8 @@ static void ws_pae_controller_frame_counter_read(pae_controller_t *controller)
610622
if (controller->frame_counters.counter[index].set) {
611623
// Increments frame counters
612624
controller->frame_counters.counter[index].frame_counter += FRAME_COUNTER_INCREMENT;
625+
controller->frame_counters.counter[index].stored_frame_counter =
626+
controller->frame_counters.counter[index].frame_counter;
613627

614628
tr_info("Read frame counter: index %i value %"PRIu32"", index, controller->frame_counters.counter[index].frame_counter);
615629

@@ -620,7 +634,6 @@ static void ws_pae_controller_frame_counter_read(pae_controller_t *controller)
620634
// Writes incremented frame counters
621635
ws_pae_nvm_store_frame_counter_tlv_create(controller->pae_nvm_buffer, &controller->frame_counters);
622636
ws_pae_controller_nvm_frame_counter_write(controller->pae_nvm_buffer);
623-
//ws_pae_controller_frame_counter_write(controller, &controller->frame_counters);
624637
}
625638
}
626639
}
@@ -630,6 +643,7 @@ static void ws_pae_controller_frame_counter_reset(frame_counters_t *frame_counte
630643
for (uint8_t index = 0; index < GTK_NUM; index++) {
631644
memset(frame_counters->counter[index].gtk, 0, GTK_LEN);
632645
frame_counters->counter[index].frame_counter = 0;
646+
frame_counters->counter[index].stored_frame_counter = 0;
633647
frame_counters->counter[index].set = false;
634648
}
635649
}
@@ -689,9 +703,6 @@ int8_t ws_pae_controller_stop(protocol_interface_info_entry_t *interface_ptr)
689703
return -1;
690704
}
691705

692-
// Stores frame counter
693-
ws_pae_controller_frame_counter_store(controller, false);
694-
695706
// Removes network keys from PAE controller and MAC
696707
ws_pae_controller_nw_keys_remove(interface_ptr);
697708

@@ -1241,18 +1252,25 @@ static void ws_pae_controller_frame_counter_store(pae_controller_t *entry, bool
12411252
// If frame counter for the network key has already been stored
12421253
if (entry->frame_counters.counter[i].set &&
12431254
memcmp(entry->nw_key[i].gtk, entry->frame_counters.counter[i].gtk, GTK_LEN) == 0) {
1255+
1256+
if (curr_frame_counter > entry->frame_counters.counter[i].frame_counter) {
1257+
entry->frame_counters.counter[i].frame_counter = curr_frame_counter;
1258+
}
1259+
uint32_t frame_counter = entry->frame_counters.counter[i].frame_counter;
1260+
12441261
// If threshold check is disabled or frame counter has advanced for the threshold value, stores the new value
12451262
if (!use_threshold ||
1246-
curr_frame_counter > entry->frame_counters.counter[i].frame_counter + FRAME_COUNTER_STORE_THRESHOLD) {
1247-
entry->frame_counters.counter[i].frame_counter = curr_frame_counter;
1263+
frame_counter > entry->frame_counters.counter[i].stored_frame_counter + FRAME_COUNTER_STORE_THRESHOLD) {
1264+
entry->frame_counters.counter[i].stored_frame_counter = frame_counter;
12481265
update_needed = true;
1249-
tr_debug("Stored updated frame counter: index %i value %"PRIu32"", i, curr_frame_counter);
1266+
tr_debug("Stored updated frame counter: index %i value %"PRIu32"", i, frame_counter);
12501267
}
12511268
} else {
12521269
// For new or modified network keys, stores the frame counter value
12531270
entry->frame_counters.counter[i].set = true;
12541271
memcpy(entry->frame_counters.counter[i].gtk, entry->nw_key[i].gtk, GTK_LEN);
12551272
entry->frame_counters.counter[i].frame_counter = curr_frame_counter;
1273+
entry->frame_counters.counter[i].stored_frame_counter = curr_frame_counter;
12561274
update_needed = true;
12571275
tr_debug("Stored new frame counter: index %i value %"PRIu32"", i, curr_frame_counter);
12581276
}

source/Security/protocols/sec_prot_keys.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ typedef struct {
102102
// Frame counter data
103103
typedef struct {
104104
uint8_t gtk[GTK_LEN]; /**< GTK of the frame counter */
105-
uint32_t frame_counter; /**< Frame counter */
105+
uint32_t frame_counter; /**< Current frame counter */
106+
uint32_t stored_frame_counter; /**< Stored Frame counter */
106107
bool set : 1; /**< Value has been set */
107108
} frame_counter_t;
108109

0 commit comments

Comments
 (0)