Skip to content

Commit cf18063

Browse files
author
Mika Leppänen
committed
Added storing of MAC frame counter to NVM
Frame counter is stored to NVM with key index and GTK hash so that it can be matched on start up to GTK keys indicated by the network. MAC frame counter value is checked once a minute. If it has increased by threshold (800 frames) it is stored to NVM. The threshold is checked also on if down. On if up, frame counter is read from NVM, increased (1000 frames), and stored with increased value to NVM. When key index changes, new frame counter is stored to NVM (with value of zero).
1 parent 68adb36 commit cf18063

File tree

8 files changed

+268
-10
lines changed

8 files changed

+268
-10
lines changed

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ static void ws_bootstrap_nw_key_set(protocol_interface_info_entry_t *cur, uint8_
9090
static void ws_bootstrap_nw_key_clear(protocol_interface_info_entry_t *cur, uint8_t slot);
9191
static void ws_bootstrap_nw_key_index_set(protocol_interface_info_entry_t *cur, uint8_t index);
9292
static void ws_bootstrap_nw_frame_counter_set(protocol_interface_info_entry_t *cur, uint32_t counter);
93+
static void ws_bootstrap_nw_frame_counter_read(protocol_interface_info_entry_t *cur, uint32_t *counter);
9394
static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_t *cur, bool success);
9495
static void ws_bootstrap_pan_version_increment(protocol_interface_info_entry_t *cur);
9596
static ws_nud_table_entry_t *ws_nud_entry_discover(protocol_interface_info_entry_t *cur, void *neighbor);
@@ -1554,7 +1555,7 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
15541555
ret_val = -4;
15551556
goto init_fail;
15561557
}
1557-
if (ws_pae_controller_cb_register(cur, &ws_bootstrap_authentication_completed, &ws_bootstrap_nw_key_set, &ws_bootstrap_nw_key_clear, &ws_bootstrap_nw_key_index_set, &ws_bootstrap_nw_frame_counter_set, &ws_bootstrap_pan_version_increment) < 0) {
1558+
if (ws_pae_controller_cb_register(cur, &ws_bootstrap_authentication_completed, &ws_bootstrap_nw_key_set, &ws_bootstrap_nw_key_clear, &ws_bootstrap_nw_key_index_set, &ws_bootstrap_nw_frame_counter_set, &ws_bootstrap_nw_frame_counter_read, &ws_bootstrap_pan_version_increment) < 0) {
15581559
ret_val = -4;
15591560
goto init_fail;
15601561
}
@@ -2024,6 +2025,12 @@ static void ws_bootstrap_nw_frame_counter_set(protocol_interface_info_entry_t *c
20242025
mac_helper_link_frame_counter_set(cur->id, counter);
20252026
}
20262027

2028+
static void ws_bootstrap_nw_frame_counter_read(protocol_interface_info_entry_t *cur, uint32_t *counter)
2029+
{
2030+
// Read frame counter
2031+
mac_helper_link_frame_counter_read(cur->id, counter);
2032+
}
2033+
20272034
static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_t *cur, bool success)
20282035
{
20292036
if (success) {

source/6LoWPAN/ws/ws_pae_controller.c

Lines changed: 160 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,21 @@
3131
#include "6LoWPAN/ws/ws_pae_timers.h"
3232
#include "6LoWPAN/ws/ws_pae_supp.h"
3333
#include "6LoWPAN/ws/ws_pae_auth.h"
34+
#include "6LoWPAN/ws/ws_pae_nvm_store.h"
35+
#include "6LoWPAN/ws/ws_pae_nvm_data.h"
3436
#include "mbedtls/sha256.h"
3537

3638
#ifdef HAVE_WS
3739

3840
#define TRACE_GROUP "wspc"
3941

42+
// Time interval (on seconds) between frame counter store operations
43+
#define FRAME_COUNTER_STORE_INTERVAL 60
44+
// How much frame counter is incremented on start up
45+
#define FRAME_COUNTER_INCREMENT 1000
46+
// How much frame counter must increment before it is stored
47+
#define FRAME_COUNTER_STORE_THRESHOLD 800
48+
4049
typedef int8_t ws_pae_delete(protocol_interface_info_entry_t *interface_ptr);
4150
typedef void ws_pae_timer(uint16_t ticks);
4251
typedef int8_t ws_pae_br_addr_write(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64);
@@ -51,6 +60,13 @@ typedef struct {
5160
bool fresh : 1; /**< Key is fresh i.e. not used on sending */
5261
} nw_key_t;
5362

63+
typedef struct {
64+
uint8_t hash[8]; /**< GTK hash for the frame counter */
65+
uint32_t frame_counter; /**< Frame counter */
66+
uint8_t index; /**< Index */
67+
bool set : 1; /**< Value has been set */
68+
} stored_frame_counter_t;
69+
5470
typedef struct {
5571
ns_list_link_t link; /**< Link */
5672
uint8_t target_eui_64[8]; /**< EAPOL target */
@@ -63,13 +79,16 @@ typedef struct {
6379
sec_prot_certs_t certs; /**< Certificates */
6480
nw_key_t nw_key[4]; /**< Currently active network keys (on MAC) */
6581
char *network_name; /**< Network name for GAK generation */
82+
uint16_t frame_cnt_store_timer; /**< Timer for storing frame counter value */
83+
stored_frame_counter_t stored_frame_counter; /**< Stored frame counter */
6684
timer_settings_t timer_settings; /**< Timer settings */
6785
protocol_interface_info_entry_t *interface_ptr; /**< List link entry */
6886
ws_pae_controller_auth_completed *auth_completed; /**< Authentication completed callback, continue bootstrap */
6987
ws_pae_controller_nw_key_set *nw_key_set; /**< Key set callback */
7088
ws_pae_controller_nw_key_clear *nw_key_clear; /**< Key clear callback */
7189
ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set; /**< Send key index set callback */
7290
ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set; /**< Frame counter set callback */
91+
ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read; /**< Frame counter read callback */
7392
ws_pae_controller_pan_ver_increment *pan_ver_increment; /**< PAN version increment callback */
7493
ws_pae_delete *pae_delete; /**< PAE delete callback */
7594
ws_pae_timer *pae_fast_timer; /**< PAE fast timer callback */
@@ -85,6 +104,10 @@ typedef struct {
85104
} pae_controller_t;
86105

87106
static pae_controller_t *ws_pae_controller_get(protocol_interface_info_entry_t *interface_ptr);
107+
static void ws_pae_controller_frame_counter_timer(uint16_t seconds, pae_controller_t *entry);
108+
static void ws_pae_controller_frame_counter_store(pae_controller_t *entry);
109+
static int8_t ws_pae_controller_nvm_frame_counter_write(uint8_t index, uint8_t *hash, uint32_t frame_counter);
110+
static int8_t ws_pae_controller_nvm_frame_counter_read(uint8_t *index, uint8_t *hash, uint32_t *frame_counter);
88111
static pae_controller_t *ws_pae_controller_get_or_create(int8_t interface_id);
89112
static void ws_pae_controller_gtk_hash_set(protocol_interface_info_entry_t *interface_ptr, uint8_t *gtkhash);
90113
static int8_t ws_pae_controller_nw_key_check_and_insert(protocol_interface_info_entry_t *interface_ptr, sec_prot_gtk_keys_t *gtks);
@@ -93,6 +116,12 @@ static void ws_pae_controller_active_nw_key_set(protocol_interface_info_entry_t
93116
static int8_t ws_pae_controller_gak_from_gtk(uint8_t *gak, uint8_t *gtk, char *network_name);
94117
static void ws_pae_controller_nw_key_index_check_and_set(protocol_interface_info_entry_t *interface_ptr, uint8_t index);
95118
static void ws_pae_controller_data_init(pae_controller_t *controller);
119+
static void ws_pae_controller_frame_counter_read(stored_frame_counter_t *counter);
120+
static void ws_pae_controller_frame_counter_reset(stored_frame_counter_t *counter);
121+
static uint32_t ws_pae_controller_frame_counter_get(stored_frame_counter_t *counter, uint8_t index, uint8_t *key_hash);
122+
static void ws_pae_controller_frame_counter_write(stored_frame_counter_t *counter, uint8_t index, uint8_t *key_hash, uint32_t curr_counter);
123+
124+
static const char *FRAME_COUNTER_FILE = FRAME_COUNTER_FILE_NAME;
96125

97126
static NS_LIST_DEFINE(pae_controller_list, pae_controller_t, link);
98127

@@ -188,7 +217,7 @@ int8_t ws_pae_controller_authenticator_start(protocol_interface_info_entry_t *in
188217
return 0;
189218
}
190219

191-
int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_controller_auth_completed *completed, ws_pae_controller_nw_key_set *nw_key_set, ws_pae_controller_nw_key_clear *nw_key_clear, ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set, ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set, ws_pae_controller_pan_ver_increment *pan_ver_increment)
220+
int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_controller_auth_completed *completed, ws_pae_controller_nw_key_set *nw_key_set, ws_pae_controller_nw_key_clear *nw_key_clear, ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set, ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set, ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read, ws_pae_controller_pan_ver_increment *pan_ver_increment)
192221
{
193222
if (!interface_ptr) {
194223
return -1;
@@ -204,6 +233,7 @@ int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_
204233
controller->nw_key_clear = nw_key_clear;
205234
controller->nw_send_key_index_set = nw_send_key_index_set;
206235
controller->nw_frame_counter_set = nw_frame_counter_set;
236+
controller->nw_frame_counter_read = nw_frame_counter_read;
207237
controller->pan_ver_increment = pan_ver_increment;
208238

209239
return 0;
@@ -422,7 +452,12 @@ static void ws_pae_controller_nw_key_index_check_and_set(protocol_interface_info
422452
if (controller->nw_send_key_index_set) {
423453
tr_info("NW send key index set: %i", index + 1);
424454
controller->nw_send_key_index_set(interface_ptr, index);
425-
controller->nw_frame_counter_set(interface_ptr, 0);
455+
controller->gtk_index = index;
456+
457+
uint32_t frame_counter = ws_pae_controller_frame_counter_get(&controller->stored_frame_counter, index, controller->nw_key[index].hash);
458+
controller->nw_frame_counter_set(interface_ptr, frame_counter);
459+
tr_info("NW frame counter set: %i", frame_counter);
460+
ws_pae_controller_frame_counter_write(&controller->stored_frame_counter, index, controller->nw_key[index].hash, frame_counter);
426461
}
427462

428463
// Do not update PAN version for initial key index set
@@ -444,10 +479,14 @@ static void ws_pae_controller_active_nw_key_set(protocol_interface_info_entry_t
444479

445480
if (controller->nw_send_key_index_set) {
446481
controller->nw_send_key_index_set(controller->interface_ptr, index);
482+
tr_info("NW send key index set: %i", index + 1);
447483

448-
// If index has changed and the key for the index is fresh reset frame counter
484+
// If index has changed and the key for the index is fresh get frame counter
449485
if (controller->gtk_index != index && controller->nw_key[index].fresh) {
450-
controller->nw_frame_counter_set(cur, 0);
486+
uint32_t frame_counter = ws_pae_controller_frame_counter_get(&controller->stored_frame_counter, index, controller->nw_key[index].hash);
487+
controller->nw_frame_counter_set(cur, frame_counter);
488+
tr_info("NW frame counter set: %i", frame_counter);
489+
ws_pae_controller_frame_counter_write(&controller->stored_frame_counter, index, controller->nw_key[index].hash, frame_counter);
451490
}
452491

453492
controller->gtk_index = index;
@@ -510,12 +549,58 @@ static void ws_pae_controller_data_init(pae_controller_t *controller)
510549
controller->key_index_set = false;
511550
controller->gtk_index = -1;
512551
controller->network_name = NULL;
552+
controller->frame_cnt_store_timer = FRAME_COUNTER_STORE_INTERVAL;
553+
ws_pae_controller_frame_counter_reset(&controller->stored_frame_counter);
513554
sec_prot_keys_gtks_init(&controller->gtks);
514555
sec_prot_keys_gtks_init(&controller->next_gtks);
515556
sec_prot_certs_init(&controller->certs);
516557
ws_pae_timers_settings_init(&controller->timer_settings);
517558
}
518559

560+
static void ws_pae_controller_frame_counter_read(stored_frame_counter_t *counter)
561+
{
562+
// If not already, read frame counter and check if index and hash matches
563+
if (!counter->set && ws_pae_controller_nvm_frame_counter_read(&counter->index, counter->hash, &counter->frame_counter) >= 0) {
564+
counter->frame_counter += FRAME_COUNTER_INCREMENT;
565+
counter->set = true;
566+
tr_debug("Read frame counter: %"PRIu32", index %i, hash %s, system time: %"PRIu32"", counter->frame_counter, counter->index, trace_array(counter->hash, 8), protocol_core_monotonic_time / 10);
567+
// Write incremented frame counter
568+
ws_pae_controller_nvm_frame_counter_write(counter->index, counter->hash, counter->frame_counter);
569+
}
570+
}
571+
572+
static void ws_pae_controller_frame_counter_reset(stored_frame_counter_t *counter)
573+
{
574+
memset(counter->hash, 0, GTK_HASH_LEN);
575+
counter->frame_counter = 0;
576+
counter->index = -1;
577+
counter->set = false;
578+
}
579+
580+
static uint32_t ws_pae_controller_frame_counter_get(stored_frame_counter_t *counter, uint8_t index, uint8_t *key_hash)
581+
{
582+
uint32_t frame_counter = 0;
583+
// If both index and hash matches uses the stored frame counter
584+
if (counter->set && counter->index == index && memcmp(counter->hash, key_hash, GTK_HASH_LEN) == 0) {
585+
frame_counter = counter->frame_counter;
586+
}
587+
588+
return frame_counter;
589+
}
590+
591+
static void ws_pae_controller_frame_counter_write(stored_frame_counter_t *counter, uint8_t index, uint8_t *key_hash, uint32_t curr_frame_counter)
592+
{
593+
// If index or hash changes, or frame counter has been incremented by the threshold updates frame counter
594+
if (!counter->set || counter->index != index || memcmp(key_hash, counter->hash, 8) != 0 || curr_frame_counter > counter->frame_counter + FRAME_COUNTER_STORE_THRESHOLD) {
595+
ws_pae_controller_nvm_frame_counter_write(index, key_hash, curr_frame_counter);
596+
counter->index = index;
597+
counter->frame_counter = curr_frame_counter;
598+
memcpy(counter->hash, key_hash, GTK_HASH_LEN);
599+
counter->set = true;
600+
tr_debug("Stored frame counter: %"PRIu32", index %i, hash %s, system time: %"PRIu32"", curr_frame_counter, index, trace_array(key_hash, 8), protocol_core_monotonic_time / 10);
601+
}
602+
}
603+
519604
int8_t ws_pae_controller_supp_init(protocol_interface_info_entry_t *interface_ptr)
520605
{
521606
pae_controller_t *controller = ws_pae_controller_get(interface_ptr);
@@ -537,6 +622,8 @@ int8_t ws_pae_controller_supp_init(protocol_interface_info_entry_t *interface_pt
537622

538623
ws_pae_supp_cb_register(controller->interface_ptr, controller->auth_completed, ws_pae_controller_nw_key_check_and_insert, ws_pae_controller_active_nw_key_set);
539624

625+
ws_pae_controller_frame_counter_read(&controller->stored_frame_counter);
626+
540627
return 0;
541628
}
542629

@@ -557,15 +644,21 @@ int8_t ws_pae_controller_auth_init(protocol_interface_info_entry_t *interface_pt
557644
controller->pae_gtks_updated = ws_pae_auth_gtks_updated;
558645
controller->pae_nw_key_index_update = ws_pae_auth_nw_key_index_update;
559646

647+
ws_pae_controller_frame_counter_read(&controller->stored_frame_counter);
648+
560649
return 0;
561650
}
651+
562652
int8_t ws_pae_controller_stop(protocol_interface_info_entry_t *interface_ptr)
563653
{
564654
pae_controller_t *controller = ws_pae_controller_get(interface_ptr);
565655
if (!controller) {
566656
return -1;
567657
}
568658

659+
// Stores frame counter
660+
ws_pae_controller_frame_counter_store(controller);
661+
569662
// If PAE has been initialized, deletes it
570663
if (controller->pae_delete) {
571664
controller->pae_delete(interface_ptr);
@@ -959,7 +1052,70 @@ void ws_pae_controller_slow_timer(uint16_t seconds)
9591052
if (entry->pae_slow_timer) {
9601053
entry->pae_slow_timer(seconds);
9611054
}
1055+
1056+
ws_pae_controller_frame_counter_timer(seconds, entry);
1057+
}
1058+
}
1059+
1060+
static void ws_pae_controller_frame_counter_timer(uint16_t seconds, pae_controller_t *entry)
1061+
{
1062+
if (entry->frame_cnt_store_timer > seconds) {
1063+
entry->frame_cnt_store_timer -= seconds;
1064+
} else {
1065+
entry->frame_cnt_store_timer = FRAME_COUNTER_STORE_INTERVAL;
1066+
ws_pae_controller_frame_counter_store(entry);
1067+
}
1068+
}
1069+
1070+
static void ws_pae_controller_frame_counter_store(pae_controller_t *entry)
1071+
{
1072+
// Gets index of active GTK
1073+
int8_t active_index = entry->gtk_index;
1074+
1075+
if (active_index >= 0) {
1076+
// Gets hash of the key
1077+
uint8_t *hash = entry->nw_key[active_index].hash;
1078+
1079+
uint32_t curr_frame_counter;
1080+
entry->nw_frame_counter_read(entry->interface_ptr, &curr_frame_counter);
1081+
ws_pae_controller_frame_counter_write(&entry->stored_frame_counter, active_index, hash, curr_frame_counter);
1082+
}
1083+
}
1084+
1085+
static int8_t ws_pae_controller_nvm_frame_counter_write(uint8_t index, uint8_t *hash, uint32_t frame_counter)
1086+
{
1087+
nvm_tlv_list_t tlv_list;
1088+
ns_list_init(&tlv_list);
1089+
1090+
nvm_tlv_entry_t *tlv_entry = ws_pae_nvm_store_frame_counter_tlv_create(index, hash, frame_counter);
1091+
ns_list_add_to_end(&tlv_list, tlv_entry);
1092+
1093+
ws_pae_nvm_store_tlv_file_write(FRAME_COUNTER_FILE, &tlv_list);
1094+
ns_list_remove(&tlv_list, tlv_entry);
1095+
ns_dyn_mem_free(tlv_entry);
1096+
1097+
return 0;
1098+
}
1099+
1100+
static int8_t ws_pae_controller_nvm_frame_counter_read(uint8_t *index, uint8_t *hash, uint32_t *frame_counter)
1101+
{
1102+
nvm_tlv_list_t tlv_list;
1103+
ns_list_init(&tlv_list);
1104+
1105+
if (ws_pae_nvm_store_tlv_file_read(FRAME_COUNTER_FILE, &tlv_list) < 0) {
1106+
return -1;
1107+
}
1108+
1109+
int8_t result = -1;
1110+
ns_list_foreach_safe(nvm_tlv_entry_t, entry, &tlv_list) {
1111+
if (ws_pae_nvm_store_frame_counter_tlv_read(entry, index, hash, frame_counter) >= 0) {
1112+
result = 0;
1113+
}
1114+
ns_list_remove(&tlv_list, entry);
1115+
ns_dyn_mem_free(entry);
9621116
}
1117+
1118+
return result;
9631119
}
9641120

9651121
static pae_controller_t *ws_pae_controller_get(protocol_interface_info_entry_t *interface_ptr)

source/6LoWPAN/ws/ws_pae_controller.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,15 @@ typedef void ws_pae_controller_nw_send_key_index_set(protocol_interface_info_ent
384384
*/
385385
typedef void ws_pae_controller_nw_frame_counter_set(protocol_interface_info_entry_t *interface_ptr, uint32_t counter);
386386

387+
/**
388+
* ws_pae_controller_nw_frame_counter_read network frame counter read callback
389+
*
390+
* \param interface_ptr interface
391+
* \param counter frame counter
392+
*
393+
*/
394+
typedef void ws_pae_controller_nw_frame_counter_read(protocol_interface_info_entry_t *interface_ptr, uint32_t *counter);
395+
387396
/**
388397
* ws_pae_controller_auth_completed authentication completed callback
389398
*
@@ -410,13 +419,14 @@ typedef void ws_pae_controller_pan_ver_increment(protocol_interface_info_entry_t
410419
* \param nw_key_clear network key clear callback
411420
* \param nw_send_key_index_set network send key index set callback
412421
* \param nw_frame_counter_set network frame counter set callback
422+
* \param nw_frame_counter_read network frame counter read callback
413423
* \param pan_ver_increment PAN version increment callback
414424
*
415425
* \return < 0 failure
416426
* \return >= 0 success
417427
*
418428
*/
419-
int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_controller_auth_completed *completed, ws_pae_controller_nw_key_set *nw_key_set, ws_pae_controller_nw_key_clear *nw_key_clear, ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set, ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set, ws_pae_controller_pan_ver_increment *pan_ver_increment);
429+
int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_ptr, ws_pae_controller_auth_completed *completed, ws_pae_controller_nw_key_set *nw_key_set, ws_pae_controller_nw_key_clear *nw_key_clear, ws_pae_controller_nw_send_key_index_set *nw_send_key_index_set, ws_pae_controller_nw_frame_counter_set *nw_frame_counter_set, ws_pae_controller_nw_frame_counter_read *nw_frame_counter_read, ws_pae_controller_pan_ver_increment *pan_ver_increment);
420430

421431
/**
422432
* ws_pae_controller_fast_timer PAE controller fast timer call

0 commit comments

Comments
 (0)