Skip to content

Commit 8994bb2

Browse files
Juha Heiskanenjuhhei01
authored andcommitted
MAC Security update
Mac frame counter read and update added inside platform critical for support multi thread users. Added support to accept trough unknow devices if MIC is correct and accept TX. Added support for Send Secured Enhanced ACK's Change-Id: I2b07f190df78a295340fafce8e86bf163633d095
1 parent 4eb5567 commit 8994bb2

File tree

12 files changed

+175
-29
lines changed

12 files changed

+175
-29
lines changed

nanostack/mlme.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ typedef enum {
264264
macAutoRequestKeyIndex = 0x7b, /*<The index of the key used for automatic data*/
265265
macDefaultKeySource = 0x7c, /*<Default key source*/
266266
//NON standard extension
267+
macAcceptByPassUnknowDevice = 0xfc, /*< Accept data trough MAC if packet is data can be authenticated by group key nad MIC. Security enforsment point must be handled carefully these packets */
267268
macLoadBalancingBeaconTx = 0xfd, /*< Trig Beacon from load balance module periodic */
268269
macLoadBalancingAcceptAnyBeacon = 0xfe, /*<Beacon accept state control from other network. Value size bool, data true=Enable, false=disable .*/
269270
macThreadForceLongAddressForBeacon = 0xff /*<Thread standard force beacon source address for extended 64-bit*/

source/MAC/IEEE802_15_4/mac_defines.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ typedef struct protocol_interface_rf_mac_setup {
157157
bool macProminousMode:1;
158158
bool macGTSPermit:1;
159159
bool mac_security_enabled:1;
160+
/* Let trough packet which is secured properly (MIC authenticated group key) and src address is 64-bit*/
161+
bool mac_security_bypass_unknow_device:1;
160162
/* Load balancing need this feature */
161163
bool macAcceptAnyBeacon:1;
162164

source/MAC/IEEE802_15_4/mac_header_helper_functions.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -288,18 +288,24 @@ static uint8_t * mac_header_write_fcf_dsn(const mac_fcf_sequence_t *header, uint
288288
return ptr;
289289
}
290290

291-
void mac_header_security_components_read(mac_pre_parsed_frame_t *buffer, mlme_security_t *security_params)
291+
uint16_t mac_header_off_set_to_aux_header(const mac_fcf_sequence_t *fcf)
292292
{
293-
uint8_t *ptr = mcps_mac_security_aux_header_start_pointer_get(buffer);
294-
memset(security_params, 0, sizeof(mlme_security_t));
295-
uint8_t key_source_len = 0;
296-
if (!buffer->fcf_dsn.securityEnabled) {
297-
return;
293+
//Skip first FCF & address field
294+
uint16_t offset = mac_fcf_lenght(fcf);//Skip FCF + DSN
295+
offset += mac_dst_address_length_with_panid(fcf);
296+
offset += mac_address_length(fcf->SrcAddrMode);
297+
if (fcf->SrcPanPresents) {
298+
offset += 2; //Skip PanId
298299
}
300+
return offset;
301+
}
299302

303+
void mac_header_security_aux_header_parse(const uint8_t *ptr, mlme_security_t *security_params)
304+
{
305+
uint8_t key_source_len = 0;
300306
security_params->KeyIdMode = (*ptr >> 3);
301307
security_params->SecurityLevel = *ptr++;
302-
ptr += 4;
308+
ptr += 4; //Skip Frame counter
303309
switch (security_params->KeyIdMode) {
304310
case MAC_KEY_ID_MODE_IMPLICIT:
305311
break;
@@ -315,6 +321,17 @@ void mac_header_security_components_read(mac_pre_parsed_frame_t *buffer, mlme_se
315321
}
316322
}
317323

324+
void mac_header_security_components_read(mac_pre_parsed_frame_t *buffer, mlme_security_t *security_params)
325+
{
326+
memset(security_params, 0, sizeof(mlme_security_t));
327+
if (!buffer->fcf_dsn.securityEnabled) {
328+
return;
329+
}
330+
331+
mac_header_security_aux_header_parse(mcps_mac_security_aux_header_start_pointer_get(buffer), security_params);
332+
333+
}
334+
318335
uint16_t mac_header_get_src_panid(const mac_fcf_sequence_t *header, const uint8_t *ptr)
319336
{
320337

source/MAC/IEEE802_15_4/mac_header_helper_functions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ void mac_header_security_parameter_set(struct mac_aux_security_header_s *header,
4040
*/
4141
const uint8_t * mac_header_parse_fcf_dsn(struct mac_fcf_sequence_s *header, const uint8_t *ptr);
4242

43+
uint16_t mac_header_off_set_to_aux_header(const struct mac_fcf_sequence_s *fcf);
44+
45+
void mac_header_security_aux_header_parse(const uint8_t *ptr, struct mlme_security_s *security_params);
46+
4347
void mac_header_security_components_read(struct mac_pre_parsed_frame_s *buffer, struct mlme_security_s *security_params);
4448

4549
bool mac_header_information_elements_parse(struct mac_pre_parsed_frame_s *buffer);

source/MAC/IEEE802_15_4/mac_mcps_sap.c

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme
527527
mlme_key_device_descriptor_t *key_device_description = NULL;
528528
uint8_t device_descriptor_handle;
529529
uint8_t openPayloadLength = 0;
530+
bool security_by_pass = false;
530531
protocol_interface_rf_mac_setup_s *rf_mac_setup = (protocol_interface_rf_mac_setup_s*)b->mac_class_ptr;
531532
// mlme_security_level_descriptor_t security_level_compare;
532533

@@ -590,7 +591,12 @@ static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme
590591
} else {
591592

592593
if (!b->neigh_info) {
593-
return MLME_UNSUPPORTED_SECURITY;
594+
if (rf_mac_setup->mac_security_bypass_unknow_device && (b->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_64_BIT
595+
&& security_params->SecurityLevel > AES_SECURITY_LEVEL_ENC)) {
596+
security_by_pass = true;
597+
} else {
598+
return MLME_UNSUPPORTED_SECURITY;
599+
}
594600
}
595601

596602
device_descriptor_handle = mac_mib_device_descption_attribute_get_by_descriptor(rf_mac_setup, b->neigh_info);
@@ -611,7 +617,11 @@ static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme
611617
}
612618

613619
key = key_description->Key;
614-
memcpy(neighbour_validation.nonce_ptr, b->neigh_info->ExtAddress, 8);
620+
if (security_by_pass) {
621+
memcpy(neighbour_validation.nonce_ptr, neighbour_validation.address, 8);
622+
} else {
623+
memcpy(neighbour_validation.nonce_ptr, b->neigh_info->ExtAddress, 8);
624+
}
615625

616626
ccm_globals_t ccm_ptr;
617627

@@ -641,15 +651,16 @@ static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme
641651
}
642652

643653
//Update key device and key description tables
644-
645-
b->neigh_info->FrameCounter = neighbour_validation.frameCounter + 1;
646-
if (!key_device_description) {
647-
// Black list old used keys by this device
648-
mac_sec_mib_device_description_blacklist(rf_mac_setup, device_descriptor_handle);
649-
key_device_description = mac_sec_mib_key_device_description_list_update(key_description);
650-
if (key_device_description) {
651-
tr_debug("Set new device user %u for key", device_descriptor_handle);
652-
key_device_description->DeviceDescriptorHandle = device_descriptor_handle;
654+
if (!security_by_pass) {
655+
b->neigh_info->FrameCounter = neighbour_validation.frameCounter + 1;
656+
if (!key_device_description) {
657+
// Black list old used keys by this device
658+
mac_sec_mib_device_description_blacklist(rf_mac_setup, device_descriptor_handle);
659+
key_device_description = mac_sec_mib_key_device_description_list_update(key_description);
660+
if (key_device_description) {
661+
tr_debug("Set new device user %u for key", device_descriptor_handle);
662+
key_device_description->DeviceDescriptorHandle = device_descriptor_handle;
663+
}
653664
}
654665
}
655666

@@ -1269,8 +1280,13 @@ static bool mac_frame_security_parameters_init(ccm_globals_t *ccm_ptr, protocol_
12691280
device_description = mac_sec_mib_device_description_get(rf_ptr, buffer->DstAddr, buffer->fcf_dsn.DstAddrMode);
12701281
if (!device_description) {
12711282

1272-
buffer->status = MLME_UNAVAILABLE_KEY;
1273-
return false;
1283+
if (rf_ptr->mac_security_bypass_unknow_device && (buffer->fcf_dsn.SrcAddrMode == MAC_ADDR_MODE_64_BIT
1284+
&& buffer->aux_header.securityLevel > AES_SECURITY_LEVEL_ENC)) {
1285+
1286+
} else {
1287+
buffer->status = MLME_UNAVAILABLE_KEY;
1288+
return false;
1289+
}
12741290
}
12751291
}
12761292
nonce_ext_64_ptr = rf_ptr->mac64;
@@ -1517,12 +1533,12 @@ static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_pt
15171533

15181534
if (buffer->fcf_dsn.securityEnabled) {
15191535
//Remember to update security counter here!
1520-
buffer->aux_header.frameCounter = rf_ptr->security_frame_counter;
1536+
buffer->aux_header.frameCounter = mac_mlme_framecounter_get(rf_ptr);
15211537
if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer)) {
15221538
return -2;
15231539
}
15241540
//Increment security counter
1525-
rf_ptr->security_frame_counter++;
1541+
mac_mlme_framecounter_increment(rf_ptr);
15261542

15271543
}
15281544

@@ -1556,7 +1572,7 @@ static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_pt
15561572
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);
15571573
buffer->status = MLME_FRAME_TOO_LONG;
15581574
//decrement security counter
1559-
rf_ptr->security_frame_counter--;
1575+
mac_mlme_framecounter_decrement(rf_ptr);
15601576
return -1;
15611577
}
15621578

@@ -1587,7 +1603,7 @@ static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_pt
15871603
}
15881604

15891605

1590-
int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload, uint32_t rx_time)
1606+
int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, const mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload, uint32_t rx_time)
15911607
{
15921608
phy_device_driver_s *dev_driver = rf_ptr->dev_driver->phy_driver;
15931609
dev_driver_tx_buffer_s *tx_buf = &rf_ptr->dev_driver_tx_buffer;
@@ -1613,12 +1629,34 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, mac_fcf
16131629
}
16141630

16151631
buffer->mac_header_length_with_security += mac_header_address_length(&buffer->fcf_dsn);
1632+
16161633
buffer->DstPANId = mac_header_get_src_panid(fcf, data_ptr);
16171634
buffer->SrcPANId = mac_header_get_dst_panid(fcf, data_ptr);
16181635

16191636
mac_header_get_src_address(fcf, data_ptr, buffer->DstAddr);
16201637
mac_header_get_dst_address(fcf, data_ptr, buffer->SrcAddr);
16211638

1639+
//Security
1640+
buffer->fcf_dsn.securityEnabled = fcf->securityEnabled;
1641+
if (buffer->fcf_dsn.securityEnabled ) {
1642+
//Read Security AUX headers
1643+
const uint8_t *ptr = data_ptr;
1644+
ptr += mac_header_off_set_to_aux_header(fcf);
1645+
//Start parsing AUX header
1646+
mlme_security_t aux_parse;
1647+
mac_header_security_aux_header_parse(ptr, &aux_parse);
1648+
buffer->aux_header.KeyIdMode = aux_parse.KeyIdMode;
1649+
buffer->aux_header.KeyIndex = aux_parse.KeyIndex;
1650+
buffer->aux_header.securityLevel = aux_parse.SecurityLevel;
1651+
memcpy(buffer->aux_header.Keysource, aux_parse.Keysource, 8);
1652+
1653+
buffer->security_mic_len = mac_security_mic_length_get(buffer->aux_header.securityLevel);
1654+
buffer->fcf_dsn.frameVersion = MAC_FRAME_VERSION_2006;
1655+
buffer->mac_header_length_with_security += mac_header_security_aux_header_length(buffer->aux_header.securityLevel, buffer->aux_header.KeyIdMode);
1656+
1657+
}
1658+
1659+
16221660
//TODO Request Application data to ACK
16231661
uint16_t ie_header_length = 0;
16241662
uint16_t ie_payload_length = 0;
@@ -1645,12 +1683,12 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, mac_fcf
16451683

16461684
if (buffer->fcf_dsn.securityEnabled) {
16471685
//Remember to update security counter here!
1648-
buffer->aux_header.frameCounter = rf_ptr->security_frame_counter;
1686+
buffer->aux_header.frameCounter = mac_mlme_framecounter_get(rf_ptr);
16491687
if ( !mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer)) {
16501688
return -2;
16511689
}
16521690
//Increment security counter
1653-
rf_ptr->security_frame_counter++;
1691+
mac_mlme_framecounter_increment(rf_ptr);
16541692
}
16551693

16561694
//Calculate Payload length here with IE extension
@@ -1666,7 +1704,7 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, mac_fcf
16661704

16671705
if (buffer->fcf_dsn.securityEnabled) {
16681706
//decrement security counter
1669-
rf_ptr->security_frame_counter--;
1707+
mac_mlme_framecounter_decrement(rf_ptr);
16701708
ccm_free(&ccm_ptr);
16711709
}
16721710
return -1;

source/MAC/IEEE802_15_4/mac_mcps_sap.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,6 @@ void mcps_sap_purge_reg_handler(struct protocol_interface_rf_mac_setup *rf_mac_s
204204

205205
int8_t mcps_pd_data_rebuild(struct protocol_interface_rf_mac_setup *rf_ptr, mac_pre_build_frame_t *buffer);
206206

207-
int8_t mcps_generic_ack_build(struct protocol_interface_rf_mac_setup *rf_ptr, mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload, uint32_t rx_time);
207+
int8_t mcps_generic_ack_build(struct protocol_interface_rf_mac_setup *rf_ptr, const mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload, uint32_t rx_time);
208208

209209
#endif /* MAC_IEEE802_15_4_MAC_MCPS_SAP_H_ */

source/MAC/IEEE802_15_4/mac_mlme.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,9 @@ static int8_t mac_mlme_boolean_set(protocol_interface_rf_mac_setup_s *rf_mac_set
510510
rf_mac_setup->dev_driver->phy_driver->extension(PHY_EXTENSION_ACCEPT_ANY_BEACON, (uint8_t*)&value);
511511
}
512512
break;
513+
case macAcceptByPassUnknowDevice:
514+
rf_mac_setup->mac_security_bypass_unknow_device = value;
515+
break;
513516

514517
default:
515518
return -1;
@@ -609,7 +612,9 @@ static int8_t mac_mlme_32bit_set(protocol_interface_rf_mac_setup_s *rf_mac_setup
609612
(void) value;
610613
switch (attribute) {
611614
case macFrameCounter:
615+
platform_enter_critical();
612616
rf_mac_setup->security_frame_counter = value;
617+
platform_exit_critical();
613618
break;
614619

615620
default:
@@ -720,6 +725,30 @@ int8_t mac_mlme_set_req(protocol_interface_rf_mac_setup_s *rf_mac_setup,const ml
720725
}
721726
}
722727

728+
uint32_t mac_mlme_framecounter_get(struct protocol_interface_rf_mac_setup *rf_mac_setup)
729+
{
730+
uint32_t value;
731+
platform_enter_critical();
732+
value = rf_mac_setup->security_frame_counter;
733+
platform_exit_critical();
734+
return value;
735+
}
736+
737+
void mac_mlme_framecounter_increment(struct protocol_interface_rf_mac_setup *rf_mac_setup)
738+
{
739+
platform_enter_critical();
740+
rf_mac_setup->security_frame_counter++;
741+
platform_exit_critical();
742+
}
743+
744+
void mac_mlme_framecounter_decrement(struct protocol_interface_rf_mac_setup *rf_mac_setup)
745+
{
746+
platform_enter_critical();
747+
rf_mac_setup->security_frame_counter--;
748+
platform_exit_critical();
749+
}
750+
751+
723752
int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_get_conf_t *get_req)
724753
{
725754
if (!get_req || !rf_mac_setup ) {
@@ -742,7 +771,9 @@ int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, ml
742771
break;
743772

744773
case macFrameCounter:
774+
platform_enter_critical();
745775
get_req->value_pointer = &rf_mac_setup->security_frame_counter;
776+
platform_exit_critical();
746777
get_req->value_size = 4;
747778
break;
748779

source/MAC/IEEE802_15_4/mac_mlme.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, st
6565

6666
void mac_extended_mac_set(struct protocol_interface_rf_mac_setup *rf_mac_setup, const uint8_t *mac64);
6767

68+
uint32_t mac_mlme_framecounter_get(struct protocol_interface_rf_mac_setup *rf_mac_setup);
69+
70+
void mac_mlme_framecounter_increment(struct protocol_interface_rf_mac_setup *rf_mac_setup);
71+
void mac_mlme_framecounter_decrement(struct protocol_interface_rf_mac_setup *rf_mac_setup);
72+
6873
/**
6974
* MLME Poll Request
7075
*

source/MAC/IEEE802_15_4/mac_pd_sap.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,14 @@ static void mac_sap_no_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr) {
319319
}
320320
}
321321

322+
static bool mac_data_counter_too_small(uint32_t current_counter, uint32_t packet_counter)
323+
{
324+
if((current_counter - packet_counter) >= 2) {
325+
return true;
326+
}
327+
return false;
328+
}
329+
322330

323331
static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *rf_ptr, phy_link_tx_status_e status, uint8_t cca_retry, uint8_t tx_retry)
324332
{
@@ -372,6 +380,15 @@ static int8_t mac_data_interface_tx_done_cb(protocol_interface_rf_mac_setup_s *r
372380
if (rf_ptr->mac_ack_tx_active) {
373381
rf_ptr->mac_ack_tx_active = false;
374382
if (rf_ptr->active_pd_data_request) {
383+
384+
if (rf_ptr->active_pd_data_request->fcf_dsn.securityEnabled) {
385+
uint32_t current_counter = mac_mlme_framecounter_get(rf_ptr);
386+
if (mac_data_counter_too_small(current_counter, rf_ptr->active_pd_data_request->aux_header.frameCounter)) {
387+
tr_debug("HOXS counter %u < ack counter %u", rf_ptr->active_pd_data_request->aux_header.frameCounter, rf_ptr->security_frame_counter);
388+
rf_ptr->active_pd_data_request->aux_header.frameCounter = current_counter;
389+
mac_mlme_framecounter_increment(rf_ptr);
390+
}
391+
}
375392
//GEN TX failure
376393
mac_sap_cca_fail_cb(rf_ptr);
377394
}

test/nanostack/unittest/stub/mac_header_helper_functions_stub.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,22 @@ void mac_header_security_components_read(mac_pre_parsed_frame_t *buffer, mlme_se
6868
}
6969
}
7070

71+
void mac_header_security_aux_header_parse(const uint8_t *ptr, mlme_security_t *security_params)
72+
{
73+
if (security_params) {
74+
security_params->KeyIdMode = mac_header_helper_functions_stub.security_header.KeyIdMode;
75+
security_params->KeyIndex = mac_header_helper_functions_stub.security_header.KeyIndex;
76+
security_params->SecurityLevel = mac_header_helper_functions_stub.security_header.securityLevel;
77+
memcpy(security_params->Keysource, mac_header_helper_functions_stub.security_header.Keysource, 8);
78+
79+
}
80+
}
81+
82+
uint16_t mac_header_off_set_to_aux_header(const mac_fcf_sequence_t *fcf)
83+
{
84+
return 0;
85+
}
86+
7187
uint16_t mac_header_get_src_panid(const mac_fcf_sequence_t *header, const uint8_t *ptr)
7288
{
7389
return mac_header_helper_functions_stub.pan_src;

test/nanostack/unittest/stub/mac_mcps_sap_stub.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ int8_t mcps_pd_data_rebuild(struct protocol_interface_rf_mac_setup *rf_ptr, mac_
160160
return mac_mcps_sap_stub.int8_value;
161161
}
162162

163-
int8_t mcps_generic_ack_build(struct protocol_interface_rf_mac_setup *rf_ptr, mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload, uint32_t rx_time)
163+
int8_t mcps_generic_ack_build(struct protocol_interface_rf_mac_setup *rf_ptr, const mac_fcf_sequence_t *fcf, const uint8_t *data_ptr, const mcps_ack_data_payload_t *ack_payload, uint32_t rx_time)
164164
{
165165
return 0;
166166
}

0 commit comments

Comments
 (0)