Skip to content

Commit 26c10a6

Browse files
author
Juha Heiskanen
committed
SW MAC / 802.15.4 Frame counter per key support Update
Implemeted missing frame counter per key support. Earlier MAC have only 1 outgoing security counter and 1 in coming counter per device. This commit enable 1 out framecounter / key and 1 framecounter in / key. That mean that node can handle many key same time without loosing frame counter synch. Wi-sun stack enable new mac feature to remove pae controller frame count init to zero. Change-Id: Iff4de96517ed0f8dd6dca63a473d0a4f63934afb
1 parent b62b120 commit 26c10a6

22 files changed

+382
-124
lines changed

nanostack/sw_mac.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ extern int ns_sw_mac_phy_statistics_start(struct mac_api_s *mac_api, struct phy_
9797
*/
9898
extern uint32_t ns_sw_mac_read_current_timestamp(struct mac_api_s *mac_api);
9999

100+
/**
101+
* @brief Enable or disable Frame counter per security key. SW MAC must be create before enable this feature!
102+
* @param mac_api MAC instance.
103+
* @param enable_feature True will allocate frame counter table for devices / key False will clear mode and free counter table.
104+
* @return 0 on success, -1 on fail.
105+
*/
106+
extern int8_t ns_sw_mac_enable_frame_counter_per_key(struct mac_api_s *mac_api, bool enable_feature);
107+
100108
#ifdef __cplusplus
101109
}
102110
#endif

source/6LoWPAN/MAC/mac_helper.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -349,12 +349,12 @@ int8_t mac_helper_security_default_recv_key_set(protocol_interface_info_entry_t
349349
return 0;
350350
}
351351

352-
int8_t mac_helper_security_auto_request_key_index_set(protocol_interface_info_entry_t *interface, uint8_t id)
352+
int8_t mac_helper_security_auto_request_key_index_set(protocol_interface_info_entry_t *interface, uint8_t key_attibute_index, uint8_t id)
353353
{
354354
if (id == 0) {
355355
return -1;
356356
}
357-
357+
interface->mac_parameters->mac_default_key_attribute_id = key_attibute_index;
358358
mac_helper_pib_8bit_set(interface, macAutoRequestKeyIndex, id);
359359
return 0;
360360
}
@@ -442,13 +442,11 @@ void mac_helper_security_key_swap_next_to_default(protocol_interface_info_entry_
442442
interface->mac_parameters->mac_prev_key_index = interface->mac_parameters->mac_default_key_index;
443443
interface->mac_parameters->mac_prev_key_attribute_id = interface->mac_parameters->mac_default_key_attribute_id;
444444

445-
interface->mac_parameters->mac_default_key_index = interface->mac_parameters->mac_next_key_index;
446-
interface->mac_parameters->mac_default_key_attribute_id = interface->mac_parameters->mac_next_key_attribute_id;
445+
mac_helper_security_auto_request_key_index_set(interface, interface->mac_parameters->mac_next_key_attribute_id, interface->mac_parameters->mac_next_key_index);
446+
447447
interface->mac_parameters->mac_next_key_index = 0;
448448
interface->mac_parameters->mac_next_key_attribute_id = prev_attribute;
449449

450-
mac_helper_pib_8bit_set(interface, macAutoRequestKeyIndex, interface->mac_parameters->mac_default_key_index);
451-
452450
}
453451

454452
void mac_helper_security_key_clean(protocol_interface_info_entry_t *interface)
@@ -841,7 +839,7 @@ int8_t mac_helper_link_frame_counter_read(int8_t interface_id, uint32_t *seq_ptr
841839
}
842840
mlme_get_t get_req;
843841
get_req.attr = macFrameCounter;
844-
get_req.attr_index = 0;
842+
get_req.attr_index = cur->mac_parameters->mac_default_key_attribute_id;
845843
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
846844
*seq_ptr = cur->mac_parameters->security_frame_counter;
847845

@@ -858,7 +856,7 @@ int8_t mac_helper_link_frame_counter_set(int8_t interface_id, uint32_t seq_ptr)
858856
}
859857
mlme_set_t set_req;
860858
set_req.attr = macFrameCounter;
861-
set_req.attr_index = 0;
859+
set_req.attr_index = cur->mac_parameters->mac_default_key_attribute_id;
862860
set_req.value_pointer = &seq_ptr;
863861
set_req.value_size = 4;
864862
cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req);

source/6LoWPAN/MAC/mac_helper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ int8_t mac_helper_security_default_key_set(struct protocol_interface_info_entry
6969

7070
int8_t mac_helper_security_default_recv_key_set(struct protocol_interface_info_entry *interface, const uint8_t *key, uint8_t id, uint8_t keyid_mode);
7171

72-
int8_t mac_helper_security_auto_request_key_index_set(struct protocol_interface_info_entry *interface, uint8_t id);
72+
int8_t mac_helper_security_auto_request_key_index_set(struct protocol_interface_info_entry *interface, uint8_t key_attibute_index, uint8_t id);
7373

7474
int8_t mac_helper_security_next_key_set(struct protocol_interface_info_entry *interface, uint8_t *key, uint8_t id, uint8_t keyid_mode);
7575

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1581,6 +1581,10 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
15811581
return -2;
15821582
}
15831583

1584+
if (ns_sw_mac_enable_frame_counter_per_key(cur->mac_api, true)) {
1585+
return -1;
1586+
}
1587+
15841588
if (!etx_storage_list_allocate(cur->id, buffer.device_decription_table_size)) {
15851589
return -1;
15861590
}
@@ -2171,7 +2175,7 @@ static void ws_bootstrap_nw_key_clear(protocol_interface_info_entry_t *cur, uint
21712175
static void ws_bootstrap_nw_key_index_set(protocol_interface_info_entry_t *cur, uint8_t index)
21722176
{
21732177
// Set send key
2174-
mac_helper_security_auto_request_key_index_set(cur, index + 1);
2178+
mac_helper_security_auto_request_key_index_set(cur, index, index + 1);
21752179
}
21762180

21772181
static void ws_bootstrap_nw_frame_counter_set(protocol_interface_info_entry_t *cur, uint32_t counter)

source/6LoWPAN/ws/ws_pae_controller.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,9 +482,12 @@ static void ws_pae_controller_nw_key_index_check_and_set(protocol_interface_info
482482
controller->gtk_index = index;
483483

484484
uint32_t frame_counter = ws_pae_controller_frame_counter_get(&controller->stored_frame_counter, index, controller->nw_key[index].hash);
485-
controller->nw_frame_counter_set(interface_ptr, frame_counter);
485+
if (frame_counter) {
486+
controller->nw_frame_counter_set(interface_ptr, frame_counter);
487+
}
486488
tr_info("NW frame counter set: %"PRIu32"", frame_counter);
487489
ws_pae_controller_frame_counter_write(controller, index, controller->nw_key[index].hash, frame_counter);
490+
488491
}
489492

490493
// Do not update PAN version for initial key index set
@@ -511,9 +514,12 @@ static void ws_pae_controller_active_nw_key_set(protocol_interface_info_entry_t
511514
// If index has changed and the key for the index is fresh get frame counter
512515
if (controller->gtk_index != index && controller->nw_key[index].fresh) {
513516
uint32_t frame_counter = ws_pae_controller_frame_counter_get(&controller->stored_frame_counter, index, controller->nw_key[index].hash);
514-
controller->nw_frame_counter_set(cur, frame_counter);
517+
if (frame_counter) {
518+
controller->nw_frame_counter_set(cur, frame_counter);
519+
}
515520
tr_info("NW frame counter set: %"PRIu32"", frame_counter);
516521
ws_pae_controller_frame_counter_write(controller, index, controller->nw_key[index].hash, frame_counter);
522+
517523
}
518524

519525
controller->gtk_index = index;

source/MAC/IEEE802_15_4/mac_defines.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -148,32 +148,26 @@ typedef struct mac_mcps_data_conf_fail_s {
148148

149149
typedef struct protocol_interface_rf_mac_setup {
150150
int8_t mac_interface_id;
151-
bool macUpState;
151+
bool macUpState: 1;
152152
bool shortAdressValid: 1; //Define Dynamic src address to mac16 when it is true
153153
bool beaconSrcAddressModeLong: 1; //This force beacon src to mac64 otherwise shortAdressValid will define type
154+
bool secFrameCounterPerKey: 1;
154155
bool mac_extension_enabled: 1;
155156
bool mac_ack_tx_active: 1;
156157
bool mac_frame_pending: 1;
157-
uint16_t mac_short_address;
158-
uint16_t pan_id;
159-
uint8_t mac64[8];
160-
uint16_t coord_short_address;
161-
uint8_t coord_long_address[8];
162158
/* MAC Capability Information */
163159
bool macCapRxOnIdle: 1;
164160
bool macCapCordinator: 1;
165161
bool macCapAssocationPermit: 1;
166162
bool macCapBatteryPowered: 1;
167163
bool macCapSecrutityCapability: 1;
168-
169164
bool macProminousMode: 1;
170165
bool macGTSPermit: 1;
171166
bool mac_security_enabled: 1;
172167
/* Let trough packet which is secured properly (MIC authenticated group key) and src address is 64-bit*/
173168
bool mac_security_bypass_unknow_device: 1;
174169
/* Load balancing need this feature */
175170
bool macAcceptAnyBeacon: 1;
176-
177171
/* TX process Flag */
178172
bool macTxProcessActive: 1;
179173
bool macTxRequestAck: 1;
@@ -188,6 +182,12 @@ typedef struct protocol_interface_rf_mac_setup {
188182
bool scan_active: 1;
189183
bool rf_csma_extension_supported: 1;
190184
bool ack_tx_possible: 1;
185+
uint16_t mac_short_address;
186+
uint16_t pan_id;
187+
uint8_t mac64[8];
188+
uint16_t coord_short_address;
189+
uint8_t coord_long_address[8];
190+
191191
/* CSMA Params */
192192
unsigned macMinBE: 4;
193193
unsigned macMaxBE: 4;
@@ -200,7 +200,6 @@ typedef struct protocol_interface_rf_mac_setup {
200200
uint8_t scan_duration; //Needed???
201201
mac_scan_type_t scan_type;
202202

203-
204203
uint8_t mac_channel;
205204
//uint8_t cca_failure;
206205

@@ -253,6 +252,7 @@ typedef struct protocol_interface_rf_mac_setup {
253252
struct mlme_device_descriptor_s *device_description_table;
254253
uint8_t device_description_table_size;
255254
struct mlme_key_descriptor_s *key_description_table;
255+
void *key_device_frame_counter_list_buffer;
256256
uint8_t key_description_table_size;
257257
uint8_t key_lookup_list_size;
258258
uint8_t key_usage_list_size;

source/MAC/IEEE802_15_4/mac_mcps_sap.c

Lines changed: 78 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,14 @@ uint32_t mac_mcps_sap_get_phy_timestamp(protocol_interface_rf_mac_setup_s *rf_ma
9090
return timestamp;
9191
}
9292

93+
static bool mac_data_counter_too_small(uint32_t current_counter, uint32_t packet_counter)
94+
{
95+
if ((current_counter - packet_counter) >= 2) {
96+
return true;
97+
}
98+
return false;
99+
}
100+
93101
static bool mac_data_request_confirmation_finnish(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
94102
{
95103
if (!buffer->asynch_request) {
@@ -583,10 +591,14 @@ static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme
583591
return MLME_UNAVAILABLE_KEY;
584592
}
585593

586-
if (b->neigh_info && neighbour_validation.frameCounter < b->neigh_info->FrameCounter) {
587-
tr_debug("MLME_COUNTER_ERROR");
588-
return MLME_COUNTER_ERROR;
594+
if (b->neigh_info) {
595+
uint32_t min_accepted_frame_counter = mac_mib_key_device_frame_counter_get(key_description, b->neigh_info, device_descriptor_handle);
596+
if (neighbour_validation.frameCounter < min_accepted_frame_counter) {
597+
tr_debug("MLME_COUNTER_ERROR");
598+
return MLME_COUNTER_ERROR;
599+
}
589600
}
601+
590602
}
591603

592604
key = key_description->Key;
@@ -620,10 +632,15 @@ static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme
620632

621633
//Update key device and key description tables
622634
if (!security_by_pass) {
623-
b->neigh_info->FrameCounter = neighbour_validation.frameCounter + 1;
635+
636+
mac_sec_mib_key_device_frame_counter_set(key_description, b->neigh_info, neighbour_validation.frameCounter + 1, device_descriptor_handle);
637+
624638
if (!key_device_description) {
625-
// Black list old used keys by this device
626-
mac_sec_mib_device_description_blacklist(rf_mac_setup, device_descriptor_handle);
639+
if (!rf_mac_setup->secFrameCounterPerKey) {
640+
// Black list old used keys by this device
641+
mac_sec_mib_device_description_blacklist(rf_mac_setup, device_descriptor_handle);
642+
}
643+
627644
key_device_description = mac_sec_mib_key_device_description_list_update(key_description);
628645
if (key_device_description) {
629646
tr_debug("Set new device user %u for key", device_descriptor_handle);
@@ -1230,21 +1247,21 @@ void mcps_sap_prebuild_frame_buffer_free(mac_pre_build_frame_t *buffer)
12301247

12311248
}
12321249

1233-
static bool mac_frame_security_parameters_init(ccm_globals_t *ccm_ptr, protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
1250+
static mlme_key_descriptor_t *mac_frame_security_key_get(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
12341251
{
12351252
/* Encrypt the packet payload if AES encyption bit is set */
12361253
mlme_security_t key_source;
12371254
key_source.KeyIdMode = buffer->aux_header.KeyIdMode;
12381255
key_source.KeyIndex = buffer->aux_header.KeyIndex;
12391256
key_source.SecurityLevel = buffer->aux_header.securityLevel;
12401257
memcpy(key_source.Keysource, buffer->aux_header.Keysource, 8);
1241-
mlme_key_descriptor_t *key_description = mac_sec_key_description_get(rf_ptr, &key_source, buffer->fcf_dsn.DstAddrMode, buffer->DstAddr, buffer->DstPANId);
1258+
return mac_sec_key_description_get(rf_ptr, &key_source, buffer->fcf_dsn.DstAddrMode, buffer->DstAddr, buffer->DstPANId);
1259+
}
12421260

1243-
if (!key_description) {
1244-
buffer->status = MLME_UNAVAILABLE_KEY;
1245-
return false;
12461261

1247-
}
1262+
static bool mac_frame_security_parameters_init(ccm_globals_t *ccm_ptr, protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer, mlme_key_descriptor_t *key_description)
1263+
{
1264+
/* Encrypt the packet payload if AES encyption bit is set */
12481265
mlme_device_descriptor_t *device_description;
12491266
uint8_t *nonce_ext_64_ptr;
12501267

@@ -1518,21 +1535,30 @@ static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_pt
15181535
mac_header_information_elements_preparation(buffer);
15191536

15201537
mcps_generic_sequence_number_allocate(rf_ptr, buffer);
1521-
1538+
mlme_key_descriptor_t *key_desc;
15221539
if (buffer->fcf_dsn.securityEnabled) {
15231540
bool increment_framecounter = false;
15241541
//Remember to update security counter here!
1525-
uint32_t new_frameCounter = mac_mlme_framecounter_get(rf_ptr);
1542+
key_desc = mac_frame_security_key_get(rf_ptr, buffer);
1543+
if (!key_desc) {
1544+
buffer->status = MLME_UNAVAILABLE_KEY;
1545+
return -2;
1546+
}
1547+
1548+
//GET Counter
1549+
uint32_t new_frameCounter = mac_sec_mib_key_outgoing_frame_counter_get(rf_ptr, key_desc);
15261550
// If buffer frame counter is set, this is FHSS channel retry, update frame counter only if something was sent after failure
1527-
if ((buffer->aux_header.frameCounter == 0xffffffff) || buffer->asynch_request || ((new_frameCounter - buffer->aux_header.frameCounter) > 1)) {
1551+
if ((buffer->aux_header.frameCounter == 0xffffffff) || buffer->asynch_request || mac_data_counter_too_small(new_frameCounter, buffer->aux_header.frameCounter)) {
15281552
buffer->aux_header.frameCounter = new_frameCounter;
15291553
increment_framecounter = true;
15301554
}
1531-
if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer)) {
1555+
1556+
if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer, key_desc)) {
15321557
return -2;
15331558
}
1559+
//Increment security counter
15341560
if (increment_framecounter) {
1535-
mac_mlme_framecounter_increment(rf_ptr);
1561+
mac_sec_mib_key_outgoing_frame_counter_increment(rf_ptr, key_desc);
15361562
}
15371563
}
15381564

@@ -1566,7 +1592,9 @@ static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_pt
15661592
tr_debug("Too Long %u, %u pa %u header %u mic %u", frame_length, mac_payload_length, buffer->mac_header_length_with_security, buffer->security_mic_len, dev_driver->phy_MTU);
15671593
buffer->status = MLME_FRAME_TOO_LONG;
15681594
//decrement security counter
1569-
mac_mlme_framecounter_decrement(rf_ptr);
1595+
if (buffer->fcf_dsn.securityEnabled) {
1596+
mac_sec_mib_key_outgoing_frame_counter_decrement(rf_ptr, key_desc);
1597+
}
15701598
return -1;
15711599
}
15721600

@@ -1680,19 +1708,24 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, bool in
16801708

16811709
ccm_globals_t ccm_ptr;
16821710
mac_pre_build_frame_t *buffer = &rf_ptr->enhanced_ack_buffer;
1683-
1711+
mlme_key_descriptor_t *key_desc;
16841712

16851713
if (buffer->fcf_dsn.securityEnabled) {
16861714
//Remember to update security counter here!
1715+
key_desc = mac_frame_security_key_get(rf_ptr, buffer);
1716+
if (!key_desc) {
1717+
buffer->status = MLME_UNAVAILABLE_KEY;
1718+
return -2;
1719+
}
16871720
if (init_build) {
1688-
buffer->aux_header.frameCounter = mac_mlme_framecounter_get(rf_ptr);
1721+
buffer->aux_header.frameCounter = mac_sec_mib_key_outgoing_frame_counter_get(rf_ptr, key_desc);
16891722
}
1690-
if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer)) {
1723+
if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer, key_desc)) {
16911724
return -2;
16921725
}
16931726
if (init_build) {
16941727
//Increment security counter
1695-
mac_mlme_framecounter_increment(rf_ptr);
1728+
mac_sec_mib_key_outgoing_frame_counter_increment(rf_ptr, key_desc);
16961729
}
16971730
}
16981731

@@ -1716,7 +1749,7 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, bool in
17161749

17171750
if (buffer->fcf_dsn.securityEnabled) {
17181751
//decrement security counter
1719-
mac_mlme_framecounter_decrement(rf_ptr);
1752+
mac_sec_mib_key_outgoing_frame_counter_decrement(rf_ptr, key_desc);
17201753
ccm_free(&ccm_ptr);
17211754
}
17221755
return -1;
@@ -1777,7 +1810,14 @@ static int8_t mcps_generic_packet_rebuild(protocol_interface_rf_mac_setup_s *rf_
17771810
}
17781811

17791812
if (buffer->fcf_dsn.securityEnabled) {
1780-
if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer)) {
1813+
1814+
mlme_key_descriptor_t *key_desc = mac_frame_security_key_get(rf_ptr, buffer);
1815+
if (!key_desc) {
1816+
buffer->status = MLME_UNAVAILABLE_KEY;
1817+
return -2;
1818+
}
1819+
1820+
if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer, key_desc)) {
17811821
return -2;
17821822
}
17831823
}
@@ -2325,3 +2365,17 @@ int mcps_packet_ingress_rate_limit_by_memory(uint8_t free_heap_percentage)
23252365

23262366
return -1;
23272367
}
2368+
2369+
void mcps_pending_packet_counter_update_check(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
2370+
{
2371+
if (buffer->fcf_dsn.securityEnabled) {
2372+
mlme_key_descriptor_t *key_desc = mac_frame_security_key_get(rf_mac_setup, buffer);
2373+
if (key_desc) {
2374+
uint32_t current_counter = mac_sec_mib_key_outgoing_frame_counter_get(rf_mac_setup, key_desc);
2375+
if (mac_data_counter_too_small(current_counter, buffer->aux_header.frameCounter)) {
2376+
buffer->aux_header.frameCounter = current_counter;
2377+
mac_sec_mib_key_outgoing_frame_counter_increment(rf_mac_setup, key_desc);
2378+
}
2379+
}
2380+
}
2381+
}

source/MAC/IEEE802_15_4/mac_mcps_sap.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,6 @@ int mcps_packet_ingress_rate_limit_by_memory(uint8_t free_heap_percentage);
140140

141141
uint32_t mac_mcps_sap_get_phy_timestamp(struct protocol_interface_rf_mac_setup *rf_mac_setup);
142142

143+
void mcps_pending_packet_counter_update_check(struct protocol_interface_rf_mac_setup *rf_mac_setup, mac_pre_build_frame_t *buffer);
144+
143145
#endif /* MAC_IEEE802_15_4_MAC_MCPS_SAP_H_ */

0 commit comments

Comments
 (0)