31
31
#include "6LoWPAN/ws/ws_pae_timers.h"
32
32
#include "6LoWPAN/ws/ws_pae_supp.h"
33
33
#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"
34
36
#include "mbedtls/sha256.h"
35
37
36
38
#ifdef HAVE_WS
37
39
38
40
#define TRACE_GROUP "wspc"
39
41
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
+
40
49
typedef int8_t ws_pae_delete (protocol_interface_info_entry_t * interface_ptr );
41
50
typedef void ws_pae_timer (uint16_t ticks );
42
51
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 {
51
60
bool fresh : 1 ; /**< Key is fresh i.e. not used on sending */
52
61
} nw_key_t ;
53
62
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
+
54
70
typedef struct {
55
71
ns_list_link_t link ; /**< Link */
56
72
uint8_t target_eui_64 [8 ]; /**< EAPOL target */
@@ -63,13 +79,16 @@ typedef struct {
63
79
sec_prot_certs_t certs ; /**< Certificates */
64
80
nw_key_t nw_key [4 ]; /**< Currently active network keys (on MAC) */
65
81
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 */
66
84
timer_settings_t timer_settings ; /**< Timer settings */
67
85
protocol_interface_info_entry_t * interface_ptr ; /**< List link entry */
68
86
ws_pae_controller_auth_completed * auth_completed ; /**< Authentication completed callback, continue bootstrap */
69
87
ws_pae_controller_nw_key_set * nw_key_set ; /**< Key set callback */
70
88
ws_pae_controller_nw_key_clear * nw_key_clear ; /**< Key clear callback */
71
89
ws_pae_controller_nw_send_key_index_set * nw_send_key_index_set ; /**< Send key index set callback */
72
90
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 */
73
92
ws_pae_controller_pan_ver_increment * pan_ver_increment ; /**< PAN version increment callback */
74
93
ws_pae_delete * pae_delete ; /**< PAE delete callback */
75
94
ws_pae_timer * pae_fast_timer ; /**< PAE fast timer callback */
@@ -85,6 +104,10 @@ typedef struct {
85
104
} pae_controller_t ;
86
105
87
106
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 );
88
111
static pae_controller_t * ws_pae_controller_get_or_create (int8_t interface_id );
89
112
static void ws_pae_controller_gtk_hash_set (protocol_interface_info_entry_t * interface_ptr , uint8_t * gtkhash );
90
113
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
93
116
static int8_t ws_pae_controller_gak_from_gtk (uint8_t * gak , uint8_t * gtk , char * network_name );
94
117
static void ws_pae_controller_nw_key_index_check_and_set (protocol_interface_info_entry_t * interface_ptr , uint8_t index );
95
118
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 ;
96
125
97
126
static NS_LIST_DEFINE (pae_controller_list , pae_controller_t , link ) ;
98
127
@@ -188,7 +217,7 @@ int8_t ws_pae_controller_authenticator_start(protocol_interface_info_entry_t *in
188
217
return 0 ;
189
218
}
190
219
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 )
192
221
{
193
222
if (!interface_ptr ) {
194
223
return -1 ;
@@ -204,6 +233,7 @@ int8_t ws_pae_controller_cb_register(protocol_interface_info_entry_t *interface_
204
233
controller -> nw_key_clear = nw_key_clear ;
205
234
controller -> nw_send_key_index_set = nw_send_key_index_set ;
206
235
controller -> nw_frame_counter_set = nw_frame_counter_set ;
236
+ controller -> nw_frame_counter_read = nw_frame_counter_read ;
207
237
controller -> pan_ver_increment = pan_ver_increment ;
208
238
209
239
return 0 ;
@@ -422,7 +452,12 @@ static void ws_pae_controller_nw_key_index_check_and_set(protocol_interface_info
422
452
if (controller -> nw_send_key_index_set ) {
423
453
tr_info ("NW send key index set: %i" , index + 1 );
424
454
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 );
426
461
}
427
462
428
463
// 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
444
479
445
480
if (controller -> nw_send_key_index_set ) {
446
481
controller -> nw_send_key_index_set (controller -> interface_ptr , index );
482
+ tr_info ("NW send key index set: %i" , index + 1 );
447
483
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
449
485
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 );
451
490
}
452
491
453
492
controller -> gtk_index = index ;
@@ -510,12 +549,58 @@ static void ws_pae_controller_data_init(pae_controller_t *controller)
510
549
controller -> key_index_set = false;
511
550
controller -> gtk_index = -1 ;
512
551
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 );
513
554
sec_prot_keys_gtks_init (& controller -> gtks );
514
555
sec_prot_keys_gtks_init (& controller -> next_gtks );
515
556
sec_prot_certs_init (& controller -> certs );
516
557
ws_pae_timers_settings_init (& controller -> timer_settings );
517
558
}
518
559
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
+
519
604
int8_t ws_pae_controller_supp_init (protocol_interface_info_entry_t * interface_ptr )
520
605
{
521
606
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
537
622
538
623
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 );
539
624
625
+ ws_pae_controller_frame_counter_read (& controller -> stored_frame_counter );
626
+
540
627
return 0 ;
541
628
}
542
629
@@ -557,15 +644,21 @@ int8_t ws_pae_controller_auth_init(protocol_interface_info_entry_t *interface_pt
557
644
controller -> pae_gtks_updated = ws_pae_auth_gtks_updated ;
558
645
controller -> pae_nw_key_index_update = ws_pae_auth_nw_key_index_update ;
559
646
647
+ ws_pae_controller_frame_counter_read (& controller -> stored_frame_counter );
648
+
560
649
return 0 ;
561
650
}
651
+
562
652
int8_t ws_pae_controller_stop (protocol_interface_info_entry_t * interface_ptr )
563
653
{
564
654
pae_controller_t * controller = ws_pae_controller_get (interface_ptr );
565
655
if (!controller ) {
566
656
return -1 ;
567
657
}
568
658
659
+ // Stores frame counter
660
+ ws_pae_controller_frame_counter_store (controller );
661
+
569
662
// If PAE has been initialized, deletes it
570
663
if (controller -> pae_delete ) {
571
664
controller -> pae_delete (interface_ptr );
@@ -959,7 +1052,70 @@ void ws_pae_controller_slow_timer(uint16_t seconds)
959
1052
if (entry -> pae_slow_timer ) {
960
1053
entry -> pae_slow_timer (seconds );
961
1054
}
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 );
962
1116
}
1117
+
1118
+ return result ;
963
1119
}
964
1120
965
1121
static pae_controller_t * ws_pae_controller_get (protocol_interface_info_entry_t * interface_ptr )
0 commit comments