mirror of https://github.com/ARMmbed/mbed-os.git
Squashed 'features/nanostack/sal-stack-nanostack/' changes from c473148..0824752
0824752 Merge branch 'release_internal' into release_external f598339 Merge branch 'master' into release_internal 678e0fd Removed unicast RX flag set. it was affecting that we remove neighbor too early. a4317fc Corrected coding style cd2848e Added support for calculating the length of the TLS send message buffer f255931 Removed UDP echo msg data print and added source address print. adcca3d RPL dio config advertisment update 6db1f31 Merge pull request #2198 from ARMmbed/IOTTHD-3691 ad244d1 MAC: changed CCA and TX fail trace level to debug 496074a RPL parent select update: 32e22d3 MAC: Added trace to when CCA fails and packet TX is canceled 47b2e03 Corrected GKH initiation on supplicant c83423a PAE controller now removes keys from MAC on stop (ifdown) a6f98b7 Flagged extended key usage call with mbedTLS flags 0675a89 Added dynamic setting to enable certificate validation ff531d3 Added IDevID and LDevID certificate validation b30635f Merge pull request #2191 from ARMmbed/IOTTHD-3693 88019ec Updated message generated traces ea15b0e Remove all instances when domain is disbaled and clear EAPOL relay. dce25d3 Corrected security protocols init and security message routing 7b39e25 Do not trig Renew again after RPL parent registration done state. 3cad7bd DHCPv6 renew and transaction id update c5b6df3 DHCPv6 client update dea0d53 DHCPv6 client API update 5eaad10 Added missing address active flag init. 34c751b Corrected triggering of next GTK handshake on authenticator 4fad826 Corrected export keys callback parameters 26c10a6 SW MAC / 802.15.4 Frame counter per key support Update b62b120 Added robustness on DAO-ACK handling dfcebef Added support for new certificate modification functions fd4b2e9 WS ARO handler update e2d46b9 wi-sun neagtive ARO missing ACK update 443f03f Merge pull request #2181 from ARMmbed/IOTTHD-3530_2 f36da31 MAC: Update frame counter for asynch frames 3260fa1 Merge pull request #2177 from ARMmbed/IOTTHD-3530 f18052a MAC: Initialize frame counter with 0xffffffff 5453e5b MAC: Do not increment framecounter if security param init fails 5bd19c4 MAC: Do not update framecounter for fhss channel retry git-subtree-dir: features/nanostack/sal-stack-nanostack git-subtree-split: 082475205bb4eedfbbf5c0c824f2ccf8a73b37edpull/11639/head
parent
396dae52ab
commit
3e6cb31659
|
@ -217,6 +217,16 @@ void dhcp_service_update_server_address(uint32_t msg_tr_id, uint8_t *server_addr
|
|||
*/
|
||||
void dhcp_service_req_remove(uint32_t msg_tr_id);
|
||||
|
||||
/**
|
||||
* \brief Stops transactions for a messages (retransmissions).
|
||||
*
|
||||
* Clears off sending retransmissions for a particular message transaction by finding it via its message class pointer.
|
||||
*
|
||||
* \param msg_class_ptr The message class pointer.
|
||||
*
|
||||
*/
|
||||
void dhcp_service_req_remove_all(void *msg_class_ptr);
|
||||
|
||||
/**
|
||||
* \brief Timer tick function for retransmissions.
|
||||
*
|
||||
|
|
|
@ -97,6 +97,14 @@ extern int ns_sw_mac_phy_statistics_start(struct mac_api_s *mac_api, struct phy_
|
|||
*/
|
||||
extern uint32_t ns_sw_mac_read_current_timestamp(struct mac_api_s *mac_api);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable Frame counter per security key. SW MAC must be create before enable this feature!
|
||||
* @param mac_api MAC instance.
|
||||
* @param enable_feature True will allocate frame counter table for devices / key False will clear mode and free counter table.
|
||||
* @return 0 on success, -1 on fail.
|
||||
*/
|
||||
extern int8_t ns_sw_mac_enable_frame_counter_per_key(struct mac_api_s *mac_api, bool enable_feature);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -140,4 +140,26 @@ int ws_bbr_node_access_revoke_start(int8_t interface_id);
|
|||
*/
|
||||
int ws_bbr_eapol_node_limit_set(int8_t interface_id, uint16_t limit);
|
||||
|
||||
/**
|
||||
* Extended certificate validation
|
||||
*/
|
||||
#define BBR_CRT_EXT_VALID_NONE 0x00 /**< Do not make extended validations */
|
||||
#define BBR_CRT_EXT_VALID_WISUN 0x01 /**< Validate Wi-SUN specific fields */
|
||||
|
||||
/**
|
||||
* Sets extended certificate validation setting
|
||||
*
|
||||
* Sets extended certificate validation setting on border router. Function can be used
|
||||
* to set which fields on client certificate are validated.
|
||||
*
|
||||
* \param interface_id Network interface ID
|
||||
* \param validation Extended Certificate validation setting
|
||||
* BBR_CRT_EXT_VALID_NONE Do not make extended validations
|
||||
* BBR_CRT_EXT_VALID_WISUN Validate Wi-SUN specific fields
|
||||
*
|
||||
* \return 0 Validation setting was set
|
||||
* \return <0 Setting set failed
|
||||
*/
|
||||
int ws_bbr_ext_certificate_validation_set(int8_t interface_id, uint8_t validation);
|
||||
|
||||
#endif /* WS_BBR_API_H_ */
|
||||
|
|
|
@ -349,12 +349,12 @@ int8_t mac_helper_security_default_recv_key_set(protocol_interface_info_entry_t
|
|||
return 0;
|
||||
}
|
||||
|
||||
int8_t mac_helper_security_auto_request_key_index_set(protocol_interface_info_entry_t *interface, uint8_t id)
|
||||
int8_t mac_helper_security_auto_request_key_index_set(protocol_interface_info_entry_t *interface, uint8_t key_attibute_index, uint8_t id)
|
||||
{
|
||||
if (id == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
interface->mac_parameters->mac_default_key_attribute_id = key_attibute_index;
|
||||
mac_helper_pib_8bit_set(interface, macAutoRequestKeyIndex, id);
|
||||
return 0;
|
||||
}
|
||||
|
@ -442,13 +442,11 @@ void mac_helper_security_key_swap_next_to_default(protocol_interface_info_entry_
|
|||
interface->mac_parameters->mac_prev_key_index = interface->mac_parameters->mac_default_key_index;
|
||||
interface->mac_parameters->mac_prev_key_attribute_id = interface->mac_parameters->mac_default_key_attribute_id;
|
||||
|
||||
interface->mac_parameters->mac_default_key_index = interface->mac_parameters->mac_next_key_index;
|
||||
interface->mac_parameters->mac_default_key_attribute_id = interface->mac_parameters->mac_next_key_attribute_id;
|
||||
mac_helper_security_auto_request_key_index_set(interface, interface->mac_parameters->mac_next_key_attribute_id, interface->mac_parameters->mac_next_key_index);
|
||||
|
||||
interface->mac_parameters->mac_next_key_index = 0;
|
||||
interface->mac_parameters->mac_next_key_attribute_id = prev_attribute;
|
||||
|
||||
mac_helper_pib_8bit_set(interface, macAutoRequestKeyIndex, interface->mac_parameters->mac_default_key_index);
|
||||
|
||||
}
|
||||
|
||||
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
|
|||
}
|
||||
mlme_get_t get_req;
|
||||
get_req.attr = macFrameCounter;
|
||||
get_req.attr_index = 0;
|
||||
get_req.attr_index = cur->mac_parameters->mac_default_key_attribute_id;
|
||||
cur->mac_api->mlme_req(cur->mac_api, MLME_GET, &get_req);
|
||||
*seq_ptr = cur->mac_parameters->security_frame_counter;
|
||||
|
||||
|
@ -858,7 +856,7 @@ int8_t mac_helper_link_frame_counter_set(int8_t interface_id, uint32_t seq_ptr)
|
|||
}
|
||||
mlme_set_t set_req;
|
||||
set_req.attr = macFrameCounter;
|
||||
set_req.attr_index = 0;
|
||||
set_req.attr_index = cur->mac_parameters->mac_default_key_attribute_id;
|
||||
set_req.value_pointer = &seq_ptr;
|
||||
set_req.value_size = 4;
|
||||
cur->mac_api->mlme_req(cur->mac_api, MLME_SET, &set_req);
|
||||
|
|
|
@ -69,7 +69,7 @@ int8_t mac_helper_security_default_key_set(struct protocol_interface_info_entry
|
|||
|
||||
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);
|
||||
|
||||
int8_t mac_helper_security_auto_request_key_index_set(struct protocol_interface_info_entry *interface, uint8_t id);
|
||||
int8_t mac_helper_security_auto_request_key_index_set(struct protocol_interface_info_entry *interface, uint8_t key_attibute_index, uint8_t id);
|
||||
|
||||
int8_t mac_helper_security_next_key_set(struct protocol_interface_info_entry *interface, uint8_t *key, uint8_t id, uint8_t keyid_mode);
|
||||
|
||||
|
|
|
@ -636,3 +636,18 @@ int ws_bbr_eapol_node_limit_set(int8_t interface_id, uint16_t limit)
|
|||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ws_bbr_ext_certificate_validation_set(int8_t interface_id, uint8_t validation)
|
||||
{
|
||||
(void) interface_id;
|
||||
#ifdef HAVE_WS_BORDER_ROUTER
|
||||
bool enabled = false;
|
||||
if (validation & BBR_CRT_EXT_VALID_WISUN) {
|
||||
enabled = true;
|
||||
}
|
||||
return ws_pae_controller_ext_certificate_validation_set(interface_id, enabled);
|
||||
#else
|
||||
(void) validation;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1371,7 +1371,7 @@ static void ws_bootstrap_neighbor_table_clean(struct protocol_interface_info_ent
|
|||
//Read current timestamp
|
||||
uint32_t time_from_last_unicast_shedule = ws_time_from_last_unicast_traffic(current_time_stamp, ws_neighbor);
|
||||
|
||||
if (time_from_last_unicast_shedule > WS_NEIGHBOR_TEMPORARY_LINK_MIN_TIMEOUT || !ws_neighbor->unicast_data_rx) {
|
||||
if (time_from_last_unicast_shedule > WS_NEIGHBOR_TEMPORARY_LINK_MIN_TIMEOUT) {
|
||||
//Accept only Enough Old Device
|
||||
if (!neighbor_entry_ptr) {
|
||||
//Accept first compare
|
||||
|
@ -1581,6 +1581,10 @@ int ws_bootstrap_init(int8_t interface_id, net_6lowpan_mode_e bootstrap_mode)
|
|||
return -2;
|
||||
}
|
||||
|
||||
if (ns_sw_mac_enable_frame_counter_per_key(cur->mac_api, true)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!etx_storage_list_allocate(cur->id, buffer.device_decription_table_size)) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1940,6 +1944,9 @@ static void ws_dhcp_client_global_adress_cb(int8_t interface, uint8_t dhcp_addr[
|
|||
if (cur) {
|
||||
rpl_control_register_address(cur, prefix);
|
||||
}
|
||||
} else {
|
||||
//Delete dhcpv6 client
|
||||
dhcp_client_global_address_delete(interface, dhcp_addr, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2055,6 +2062,9 @@ static void ws_bootstrap_rpl_activate(protocol_interface_info_entry_t *cur)
|
|||
// If i am router I Do this
|
||||
rpl_control_force_leaf(protocol_6lowpan_rpl_domain, leaf);
|
||||
rpl_control_request_parent_link_confirmation(true);
|
||||
rpl_control_set_dio_multicast_min_config_advertisment_count(WS_MIN_DIO_MULTICAST_CONFIG_ADVERTISMENT_COUNT);
|
||||
rpl_control_set_dao_retry_count(WS_MAX_DAO_RETRIES);
|
||||
rpl_control_set_initial_dao_ack_wait(WS_MAX_DAO_INITIAL_TIMEOUT);
|
||||
|
||||
cur->ws_info->rpl_state = 0xff; // Set invalid state and learn from event
|
||||
}
|
||||
|
@ -2107,7 +2117,9 @@ static void ws_bootstrap_start_discovery(protocol_interface_info_entry_t *cur)
|
|||
ws_bootstrap_neighbor_list_clean(cur);
|
||||
|
||||
// Clear RPL information
|
||||
rpl_control_remove_domain_from_interface(cur);
|
||||
rpl_control_free_domain_instances_from_interface(cur);
|
||||
// Clear EAPOL relay address
|
||||
ws_eapol_relay_delete(cur);
|
||||
|
||||
// Clear ip stack from old information
|
||||
ws_bootstrap_ip_stack_reset(cur);
|
||||
|
@ -2169,7 +2181,7 @@ static void ws_bootstrap_nw_key_clear(protocol_interface_info_entry_t *cur, uint
|
|||
static void ws_bootstrap_nw_key_index_set(protocol_interface_info_entry_t *cur, uint8_t index)
|
||||
{
|
||||
// Set send key
|
||||
mac_helper_security_auto_request_key_index_set(cur, index + 1);
|
||||
mac_helper_security_auto_request_key_index_set(cur, index, index + 1);
|
||||
}
|
||||
|
||||
static void ws_bootstrap_nw_frame_counter_set(protocol_interface_info_entry_t *cur, uint32_t counter)
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "Service_Libs/etx/etx.h"
|
||||
#include "Service_Libs/mac_neighbor_table/mac_neighbor_table.h"
|
||||
#include "Service_Libs/blacklist/blacklist.h"
|
||||
#include "RPL/rpl_protocol.h"
|
||||
#include "RPL/rpl_control.h"
|
||||
#include "ws_management_api.h"
|
||||
#include "mac_api.h"
|
||||
|
||||
|
@ -404,6 +406,13 @@ bool ws_common_allow_child_registration(protocol_interface_info_entry_t *interfa
|
|||
return true;
|
||||
}
|
||||
|
||||
//Verify that we have Selected Parent
|
||||
if (interface->bootsrap_mode != ARM_NWK_BOOTSRAP_MODE_6LoWPAN_BORDER_ROUTER && !rpl_control_parent_candidate_list_size(interface, true)) {
|
||||
tr_info("Do not accept new ARO child: no selected parent");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
ns_list_foreach_safe(mac_neighbor_table_entry_t, cur, &mac_neighbor_info(interface)->neighbour_list) {
|
||||
|
||||
if (ipv6_neighbour_has_registered_by_eui64(&interface->ipv6_neighbour_cache, cur->mac64)) {
|
||||
|
|
|
@ -133,4 +133,12 @@ extern uint8_t DEVICE_MIN_SENS;
|
|||
#define FRAME_COUNTER_INCREMENT 1000 // How much frame counter is incremented on start up
|
||||
#define FRAME_COUNTER_STORE_THRESHOLD 800 // How much frame counter must increment before it is stored
|
||||
|
||||
|
||||
/*
|
||||
* RPL Configuration parameters
|
||||
*/
|
||||
#define WS_MAX_DAO_RETRIES 3 // With 40s, 80s, 160s, 320s, 640s
|
||||
#define WS_MAX_DAO_INITIAL_TIMEOUT 400 // With 40s initial value exponentially increasing
|
||||
#define WS_MIN_DIO_MULTICAST_CONFIG_ADVERTISMENT_COUNT 10 // Define 10 multicast advertisment when learn config or learn config update
|
||||
|
||||
#endif /* WS_CONFIG_H_ */
|
||||
|
|
|
@ -919,12 +919,12 @@ static void ws_pae_auth_next_kmp_trigger(pae_auth_t *pae_auth, supp_entry_t *sup
|
|||
|
||||
kmp_api_t *api = ws_pae_lib_kmp_list_type_get(&supp_entry->kmp_list, next_type);
|
||||
if (api != NULL) {
|
||||
/* For other types than GTK, only one ongoing negotiation at the same time,
|
||||
for GTK there can be previous terminating and the new one for next key index */
|
||||
if (next_type != IEEE_802_11_GKH) {
|
||||
tr_info("KMP already ongoing; ignored, eui-64: %s", trace_array(supp_entry->addr.eui_64, 8));
|
||||
return;
|
||||
}
|
||||
// Delete KMP
|
||||
ws_pae_lib_kmp_list_delete(&supp_entry->kmp_list, api);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
uint16_t node_limit; /**< Max number of stored supplicants */
|
||||
bool node_limit_set : 1; /**< Node limit set */
|
||||
bool ext_cert_valid_enabled : 1; /**< Extended certificate validation enabled */
|
||||
} pae_controller_config_t;
|
||||
|
||||
static pae_controller_t *ws_pae_controller_get(protocol_interface_info_entry_t *interface_ptr);
|
||||
|
@ -126,7 +127,8 @@ static NS_LIST_DEFINE(pae_controller_list, pae_controller_t, link);
|
|||
|
||||
pae_controller_config_t pae_controller_config = {
|
||||
.node_limit = 0,
|
||||
.node_limit_set = false
|
||||
.node_limit_set = false,
|
||||
.ext_cert_valid_enabled = false
|
||||
};
|
||||
|
||||
#if !defined(HAVE_PAE_SUPP) && !defined(HAVE_PAE_AUTH)
|
||||
|
@ -482,9 +484,12 @@ static void ws_pae_controller_nw_key_index_check_and_set(protocol_interface_info
|
|||
controller->gtk_index = index;
|
||||
|
||||
uint32_t frame_counter = ws_pae_controller_frame_counter_get(&controller->stored_frame_counter, index, controller->nw_key[index].hash);
|
||||
controller->nw_frame_counter_set(interface_ptr, frame_counter);
|
||||
if (frame_counter) {
|
||||
controller->nw_frame_counter_set(interface_ptr, frame_counter);
|
||||
}
|
||||
tr_info("NW frame counter set: %"PRIu32"", frame_counter);
|
||||
ws_pae_controller_frame_counter_write(controller, index, controller->nw_key[index].hash, frame_counter);
|
||||
|
||||
}
|
||||
|
||||
// Do not update PAN version for initial key index set
|
||||
|
@ -511,9 +516,12 @@ static void ws_pae_controller_active_nw_key_set(protocol_interface_info_entry_t
|
|||
// If index has changed and the key for the index is fresh get frame counter
|
||||
if (controller->gtk_index != index && controller->nw_key[index].fresh) {
|
||||
uint32_t frame_counter = ws_pae_controller_frame_counter_get(&controller->stored_frame_counter, index, controller->nw_key[index].hash);
|
||||
controller->nw_frame_counter_set(cur, frame_counter);
|
||||
if (frame_counter) {
|
||||
controller->nw_frame_counter_set(cur, frame_counter);
|
||||
}
|
||||
tr_info("NW frame counter set: %"PRIu32"", frame_counter);
|
||||
ws_pae_controller_frame_counter_write(controller, index, controller->nw_key[index].hash, frame_counter);
|
||||
|
||||
}
|
||||
|
||||
controller->gtk_index = index;
|
||||
|
@ -586,6 +594,7 @@ static void ws_pae_controller_data_init(pae_controller_t *controller)
|
|||
sec_prot_keys_gtks_init(&controller->gtks);
|
||||
sec_prot_keys_gtks_init(&controller->next_gtks);
|
||||
sec_prot_certs_init(&controller->certs);
|
||||
sec_prot_certs_ext_certificate_validation_set(&controller->certs, pae_controller_config.ext_cert_valid_enabled);
|
||||
ws_pae_timers_settings_init(&controller->timer_settings);
|
||||
}
|
||||
|
||||
|
@ -695,6 +704,9 @@ int8_t ws_pae_controller_stop(protocol_interface_info_entry_t *interface_ptr)
|
|||
// Stores frame counter
|
||||
ws_pae_controller_frame_counter_store(controller);
|
||||
|
||||
// Removes network keys from PAE controller and MAC
|
||||
ws_pae_controller_nw_keys_remove(interface_ptr);
|
||||
|
||||
// If PAE has been initialized, deletes it
|
||||
if (controller->pae_delete) {
|
||||
controller->pae_delete(interface_ptr);
|
||||
|
@ -764,6 +776,46 @@ int8_t ws_pae_controller_certificate_chain_set(const arm_certificate_chain_entry
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the length of own certificates
|
||||
entry->certs.own_cert_chain_len = sec_prot_certs_cert_chain_entry_len_get(&entry->certs.own_cert_chain);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t ws_pae_controller_own_certificate_add(const arm_certificate_entry_s *cert)
|
||||
{
|
||||
if (!cert) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int8_t ret = -1;
|
||||
|
||||
ns_list_foreach(pae_controller_t, entry, &pae_controller_list) {
|
||||
for (uint8_t i = 0; i < SEC_PROT_CERT_CHAIN_DEPTH; i++) {
|
||||
if (entry->certs.own_cert_chain.cert[i] == NULL) {
|
||||
sec_prot_certs_cert_set(&entry->certs.own_cert_chain, i, (uint8_t *) cert->cert, cert->cert_len);
|
||||
// Set private key if set for the certificate that is added
|
||||
if (cert->key && cert->key_len > 0) {
|
||||
sec_prot_certs_priv_key_set(&entry->certs.own_cert_chain, (uint8_t *) cert->key, cert->key_len);
|
||||
}
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Updates the length of own certificates
|
||||
entry->certs.own_cert_chain_len = sec_prot_certs_cert_chain_entry_len_get(&entry->certs.own_cert_chain);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int8_t ws_pae_controller_own_certificates_remove(void)
|
||||
{
|
||||
ns_list_foreach(pae_controller_t, entry, &pae_controller_list) {
|
||||
sec_prot_certs_chain_entry_init(&entry->certs.own_cert_chain);
|
||||
entry->certs.own_cert_chain_len = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -816,6 +868,15 @@ int8_t ws_pae_controller_trusted_certificate_remove(const arm_certificate_entry_
|
|||
return ret;
|
||||
}
|
||||
|
||||
int8_t ws_pae_controller_trusted_certificates_remove(void)
|
||||
{
|
||||
ns_list_foreach(pae_controller_t, entry, &pae_controller_list) {
|
||||
sec_prot_certs_chain_list_delete(&entry->certs.trusted_cert_chain_list);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t ws_pae_controller_certificate_revocation_list_add(const arm_cert_revocation_list_entry_s *crl)
|
||||
{
|
||||
if (!crl) {
|
||||
|
@ -1051,6 +1112,26 @@ int8_t ws_pae_controller_node_limit_set(int8_t interface_id, uint16_t limit)
|
|||
#endif
|
||||
}
|
||||
|
||||
int8_t ws_pae_controller_ext_certificate_validation_set(int8_t interface_id, bool enabled)
|
||||
{
|
||||
#ifdef HAVE_PAE_AUTH
|
||||
pae_controller_config.ext_cert_valid_enabled = enabled;
|
||||
|
||||
pae_controller_t *controller = ws_pae_controller_get_or_create(interface_id);
|
||||
if (!controller) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
sec_prot_certs_ext_certificate_validation_set(&controller->certs, enabled);
|
||||
|
||||
return 0;
|
||||
#else
|
||||
(void) interface_id;
|
||||
(void) enabled;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ws_pae_controller_forced_gc(bool full_gc)
|
||||
{
|
||||
/* Purge only when on critical limit since node limit should handle limiting
|
||||
|
|
|
@ -158,6 +158,26 @@ int8_t ws_pae_controller_timing_adjust(uint8_t timing);
|
|||
*/
|
||||
int8_t ws_pae_controller_certificate_chain_set(const arm_certificate_chain_entry_s *chain);
|
||||
|
||||
/**
|
||||
* ws_pae_controller_own_certificate_add add own certificate to certificate chain
|
||||
*
|
||||
* \param cert own certificate
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t ws_pae_controller_own_certificate_add(const arm_certificate_entry_s *cert);
|
||||
|
||||
/**
|
||||
* ws_pae_controller_own_certificates_remove removes own certificates
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t ws_pae_controller_own_certificates_remove(void);
|
||||
|
||||
/**
|
||||
* ws_pae_controller_trusted_certificate_add add trusted certificate
|
||||
*
|
||||
|
@ -180,6 +200,15 @@ int8_t ws_pae_controller_trusted_certificate_add(const arm_certificate_entry_s *
|
|||
*/
|
||||
int8_t ws_pae_controller_trusted_certificate_remove(const arm_certificate_entry_s *cert);
|
||||
|
||||
/**
|
||||
* ws_pae_controller_trusted_certificates_remove removes trusted certificates
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t ws_pae_controller_trusted_certificates_remove(void);
|
||||
|
||||
/**
|
||||
* ws_pae_controller_certificate_revocation_list_add add certification revocation list
|
||||
*
|
||||
|
@ -338,6 +367,18 @@ int8_t ws_pae_controller_node_access_revoke_start(int8_t interface_id);
|
|||
*/
|
||||
int8_t ws_pae_controller_node_limit_set(int8_t interface_id, uint16_t limit);
|
||||
|
||||
/**
|
||||
* ws_pae_controller_ext_certificate_validation_set enable or disable extended certificate validation
|
||||
*
|
||||
* \param interface_ptr interface
|
||||
* \param enabled true to enable extended validation, false to disable
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t ws_pae_controller_ext_certificate_validation_set(int8_t interface_id, bool enabled);
|
||||
|
||||
/**
|
||||
* ws_pae_controller_active_key_update update active key (test interface)
|
||||
*
|
||||
|
|
|
@ -76,13 +76,21 @@ int8_t ws_pae_lib_kmp_list_delete(kmp_list_t *kmp_list, kmp_api_t *kmp)
|
|||
|
||||
kmp_api_t *ws_pae_lib_kmp_list_type_get(kmp_list_t *kmp_list, kmp_type_e type)
|
||||
{
|
||||
kmp_api_t *kmp = NULL;
|
||||
|
||||
ns_list_foreach(kmp_entry_t, cur, kmp_list) {
|
||||
// If kmp type matches
|
||||
if (kmp_api_type_get(cur->kmp) == type) {
|
||||
return cur->kmp;
|
||||
/* If receiving of messages has not been disabled for the kmp (kmp is not
|
||||
in terminating phase) prioritizes that kmp */
|
||||
if (!kmp_api_receive_disable(cur->kmp)) {
|
||||
return cur->kmp;
|
||||
}
|
||||
// Otherwise returns any kmp that matches
|
||||
kmp = cur->kmp;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return kmp;
|
||||
}
|
||||
|
||||
void ws_pae_lib_kmp_list_free(kmp_list_t *kmp_list)
|
||||
|
|
|
@ -588,6 +588,7 @@ int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const se
|
|||
pae_supp->timer_running = false;
|
||||
pae_supp->new_br_eui_64_set = false;
|
||||
pae_supp->new_br_eui_64_fresh = false;
|
||||
pae_supp->entry_address_active = false;
|
||||
|
||||
ws_pae_lib_supp_init(&pae_supp->entry);
|
||||
|
||||
|
@ -1010,7 +1011,13 @@ static kmp_api_t *ws_pae_supp_kmp_incoming_ind(kmp_service_t *service, kmp_type_
|
|||
|
||||
// Check if ongoing
|
||||
kmp_api_t *kmp = ws_pae_lib_kmp_list_type_get(&pae_supp->entry.kmp_list, type);
|
||||
if (kmp) {
|
||||
/* If kmp receiving is enabled or it is not GKH, routes message to existing KMP.
|
||||
|
||||
For GKH creates an instance to handle message. If message is not valid (e.g. repeated
|
||||
message counter), GKH ignores message and waits for timeout. All further messages
|
||||
are routed to that instance. If valid message arrives, GKH instance handles the
|
||||
message, replies to authenticator and terminates. */
|
||||
if (kmp && (!kmp_api_receive_disable(kmp) || type != IEEE_802_11_GKH)) {
|
||||
return kmp;
|
||||
}
|
||||
|
||||
|
|
|
@ -1388,6 +1388,9 @@ static void icmpv6_aro_cb(buffer_t *buf, uint8_t status)
|
|||
ll_address[8] ^= 2;
|
||||
}
|
||||
rpl_control_address_register_done(buf->interface, ll_address, status);
|
||||
if (status != SOCKET_TX_DONE) {
|
||||
ws_common_aro_failure(buf->interface, ll_address);
|
||||
}
|
||||
}
|
||||
|
||||
buffer_t *icmpv6_build_ns(protocol_interface_info_entry_t *cur, const uint8_t target_addr[16], const uint8_t *prompting_src_addr, bool unicast, bool unspecified_source, const aro_t *aro)
|
||||
|
@ -1603,8 +1606,6 @@ buffer_t *icmpv6_build_na(protocol_interface_info_entry_t *cur, bool solicited,
|
|||
uint8_t *ptr;
|
||||
uint8_t flags;
|
||||
|
||||
tr_debug("Build NA");
|
||||
|
||||
/* Check if ARO response and status == success, then sending can be omitted with flag */
|
||||
if (aro && cur->ipv6_neighbour_cache.omit_na_aro_success && aro->status == ARO_SUCCESS) {
|
||||
tr_debug("Omit NA ARO success");
|
||||
|
@ -1712,6 +1713,8 @@ buffer_t *icmpv6_build_na(protocol_interface_info_entry_t *cur, bool solicited,
|
|||
buf->info = (buffer_info_t)(B_DIR_DOWN | B_FROM_ICMP | B_TO_ICMP);
|
||||
buf->interface = cur;
|
||||
|
||||
tr_debug("Build NA");
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
|
|
@ -146,12 +146,7 @@ buffer_t *udp_up(buffer_t *buf)
|
|||
|
||||
if (buf->dst_sa.port == UDP_PORT_ECHO && buf->src_sa.port != UDP_PORT_ECHO) {
|
||||
protocol_interface_info_entry_t *cur;
|
||||
tr_debug("UDP echo msg [%"PRIi16"]: %s%s",
|
||||
buffer_data_length(buf),
|
||||
trace_array(
|
||||
buffer_data_pointer(buf),
|
||||
(buffer_data_length(buf) > 64 ? 64 : buffer_data_length(buf))),
|
||||
(buffer_data_length(buf) > 64 ? "..." : ""));
|
||||
tr_debug("UDP echo msg from %s", trace_ipv6(buf->src_sa.address));
|
||||
|
||||
cur = buf->interface;
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ void dhcp_client_delete(int8_t interface)
|
|||
if (srv_data_ptr != NULL) {
|
||||
tr_debug("Free DHCPv6 Client\n");
|
||||
memcpy(temporary_address, srv_data_ptr->iaNontemporalAddress.addressPrefix, 16);
|
||||
dhcp_service_req_remove(srv_data_ptr->transActionId);// remove all pending retransmissions
|
||||
dhcp_service_req_remove_all(srv_data_ptr);// remove all pending retransmissions
|
||||
libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr);
|
||||
addr_delete(cur, temporary_address);
|
||||
|
||||
|
@ -144,13 +144,18 @@ int dhcp_solicit_resp_cb(uint16_t instance_id, void *ptr, uint8_t msg_name, uin
|
|||
dhcpv6_client_server_data_t *srv_data_ptr = NULL;
|
||||
(void)instance_id;
|
||||
|
||||
srv_data_ptr = ptr;
|
||||
//Validate that started TR ID class is still at list
|
||||
srv_data_ptr = libdhcpv6_nonTemporal_validate_class_pointer(ptr);
|
||||
|
||||
|
||||
if (srv_data_ptr == NULL) {
|
||||
tr_error("server data not found");
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
//Clear Active Transaction state
|
||||
srv_data_ptr->transActionId = 0;
|
||||
|
||||
// Validate message
|
||||
if (msg_name != DHCPV6_REPLY_TYPE) {
|
||||
tr_error("invalid response");
|
||||
|
@ -158,7 +163,7 @@ int dhcp_solicit_resp_cb(uint16_t instance_id, void *ptr, uint8_t msg_name, uin
|
|||
}
|
||||
|
||||
if (libdhcpv6_reply_message_option_validate(&clientId, &serverId, &dhcp_ia_non_temporal_params, msg_ptr, msg_len) != 0) {
|
||||
tr_error("Sol Not include all Options");
|
||||
tr_error("Reply Not include all Options");
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
|
@ -330,7 +335,7 @@ int dhcp_client_server_address_update(int8_t interface, uint8_t *prefix, uint8_t
|
|||
}
|
||||
|
||||
memcpy(srv_data_ptr->server_address, server_address, 16);
|
||||
if (!srv_data_ptr->iaNonTemporalStructValid) {
|
||||
if (srv_data_ptr->transActionId) {
|
||||
dhcp_service_update_server_address(srv_data_ptr->transActionId, server_address);
|
||||
}
|
||||
return 0;
|
||||
|
@ -357,7 +362,7 @@ void dhcp_client_global_address_delete(int8_t interface, uint8_t *dhcp_addr, uin
|
|||
return;
|
||||
}
|
||||
|
||||
dhcp_service_req_remove(srv_data_ptr->transActionId);// remove all pending retransmissions
|
||||
dhcp_service_req_remove_all(srv_data_ptr);// remove all pending retransmissions
|
||||
if (dhcp_client.one_instance_interface) {
|
||||
addr_deprecate(cur, srv_data_ptr->iaNontemporalAddress.addressPrefix);
|
||||
} else {
|
||||
|
@ -384,7 +389,7 @@ void dhcpv6_renew(protocol_interface_info_entry_t *interface, if_address_entry_t
|
|||
return;
|
||||
}
|
||||
if (reason == ADDR_CALLBACK_INVALIDATED) {
|
||||
dhcp_service_req_remove(srv_data_ptr->transActionId);//stop retransmissions of renew
|
||||
dhcp_service_req_remove_all(srv_data_ptr);// remove all pending retransmissions
|
||||
libdhcvp6_nontemporalAddress_server_data_free(srv_data_ptr);
|
||||
tr_warn("Dhcp address lost");
|
||||
return;
|
||||
|
@ -394,6 +399,12 @@ void dhcpv6_renew(protocol_interface_info_entry_t *interface, if_address_entry_t
|
|||
return;
|
||||
}
|
||||
|
||||
if (srv_data_ptr->transActionId) {
|
||||
//Do not trig new Renew process
|
||||
tr_warn("Do not trig new pending renew request");
|
||||
return;
|
||||
}
|
||||
|
||||
payload_len = libdhcpv6_address_request_message_len(srv_data_ptr->clientLinkIdType, srv_data_ptr->serverLinkType, 0, !dhcp_client.no_address_hint);
|
||||
payload_ptr = ns_dyn_mem_temporary_alloc(payload_len);
|
||||
if (payload_ptr == NULL) {
|
||||
|
|
|
@ -148,24 +148,19 @@ typedef struct mac_mcps_data_conf_fail_s {
|
|||
|
||||
typedef struct protocol_interface_rf_mac_setup {
|
||||
int8_t mac_interface_id;
|
||||
bool macUpState;
|
||||
bool macUpState: 1;
|
||||
bool shortAdressValid: 1; //Define Dynamic src address to mac16 when it is true
|
||||
bool beaconSrcAddressModeLong: 1; //This force beacon src to mac64 otherwise shortAdressValid will define type
|
||||
bool secFrameCounterPerKey: 1;
|
||||
bool mac_extension_enabled: 1;
|
||||
bool mac_ack_tx_active: 1;
|
||||
bool mac_frame_pending: 1;
|
||||
uint16_t mac_short_address;
|
||||
uint16_t pan_id;
|
||||
uint8_t mac64[8];
|
||||
uint16_t coord_short_address;
|
||||
uint8_t coord_long_address[8];
|
||||
/* MAC Capability Information */
|
||||
bool macCapRxOnIdle: 1;
|
||||
bool macCapCordinator: 1;
|
||||
bool macCapAssocationPermit: 1;
|
||||
bool macCapBatteryPowered: 1;
|
||||
bool macCapSecrutityCapability: 1;
|
||||
|
||||
bool macProminousMode: 1;
|
||||
bool macGTSPermit: 1;
|
||||
bool mac_security_enabled: 1;
|
||||
|
@ -173,7 +168,6 @@ typedef struct protocol_interface_rf_mac_setup {
|
|||
bool mac_security_bypass_unknow_device: 1;
|
||||
/* Load balancing need this feature */
|
||||
bool macAcceptAnyBeacon: 1;
|
||||
|
||||
/* TX process Flag */
|
||||
bool macTxProcessActive: 1;
|
||||
bool macTxRequestAck: 1;
|
||||
|
@ -188,6 +182,12 @@ typedef struct protocol_interface_rf_mac_setup {
|
|||
bool scan_active: 1;
|
||||
bool rf_csma_extension_supported: 1;
|
||||
bool ack_tx_possible: 1;
|
||||
uint16_t mac_short_address;
|
||||
uint16_t pan_id;
|
||||
uint8_t mac64[8];
|
||||
uint16_t coord_short_address;
|
||||
uint8_t coord_long_address[8];
|
||||
|
||||
/* CSMA Params */
|
||||
unsigned macMinBE: 4;
|
||||
unsigned macMaxBE: 4;
|
||||
|
@ -200,7 +200,6 @@ typedef struct protocol_interface_rf_mac_setup {
|
|||
uint8_t scan_duration; //Needed???
|
||||
mac_scan_type_t scan_type;
|
||||
|
||||
|
||||
uint8_t mac_channel;
|
||||
//uint8_t cca_failure;
|
||||
|
||||
|
@ -253,6 +252,7 @@ typedef struct protocol_interface_rf_mac_setup {
|
|||
struct mlme_device_descriptor_s *device_description_table;
|
||||
uint8_t device_description_table_size;
|
||||
struct mlme_key_descriptor_s *key_description_table;
|
||||
void *key_device_frame_counter_list_buffer;
|
||||
uint8_t key_description_table_size;
|
||||
uint8_t key_lookup_list_size;
|
||||
uint8_t key_usage_list_size;
|
||||
|
|
|
@ -90,6 +90,14 @@ uint32_t mac_mcps_sap_get_phy_timestamp(protocol_interface_rf_mac_setup_s *rf_ma
|
|||
return timestamp;
|
||||
}
|
||||
|
||||
static bool mac_data_counter_too_small(uint32_t current_counter, uint32_t packet_counter)
|
||||
{
|
||||
if ((current_counter - packet_counter) >= 2) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool mac_data_request_confirmation_finnish(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
|
||||
{
|
||||
if (!buffer->asynch_request) {
|
||||
|
@ -583,10 +591,14 @@ static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme
|
|||
return MLME_UNAVAILABLE_KEY;
|
||||
}
|
||||
|
||||
if (b->neigh_info && neighbour_validation.frameCounter < b->neigh_info->FrameCounter) {
|
||||
tr_debug("MLME_COUNTER_ERROR");
|
||||
return MLME_COUNTER_ERROR;
|
||||
if (b->neigh_info) {
|
||||
uint32_t min_accepted_frame_counter = mac_mib_key_device_frame_counter_get(key_description, b->neigh_info, device_descriptor_handle);
|
||||
if (neighbour_validation.frameCounter < min_accepted_frame_counter) {
|
||||
tr_debug("MLME_COUNTER_ERROR");
|
||||
return MLME_COUNTER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
key = key_description->Key;
|
||||
|
@ -620,10 +632,15 @@ static uint8_t mac_data_interface_decrypt_packet(mac_pre_parsed_frame_t *b, mlme
|
|||
|
||||
//Update key device and key description tables
|
||||
if (!security_by_pass) {
|
||||
b->neigh_info->FrameCounter = neighbour_validation.frameCounter + 1;
|
||||
|
||||
mac_sec_mib_key_device_frame_counter_set(key_description, b->neigh_info, neighbour_validation.frameCounter + 1, device_descriptor_handle);
|
||||
|
||||
if (!key_device_description) {
|
||||
// Black list old used keys by this device
|
||||
mac_sec_mib_device_description_blacklist(rf_mac_setup, device_descriptor_handle);
|
||||
if (!rf_mac_setup->secFrameCounterPerKey) {
|
||||
// Black list old used keys by this device
|
||||
mac_sec_mib_device_description_blacklist(rf_mac_setup, device_descriptor_handle);
|
||||
}
|
||||
|
||||
key_device_description = mac_sec_mib_key_device_description_list_update(key_description);
|
||||
if (key_device_description) {
|
||||
tr_debug("Set new device user %u for key", device_descriptor_handle);
|
||||
|
@ -1199,6 +1216,7 @@ mac_pre_build_frame_t *mcps_sap_prebuild_frame_buffer_get(uint16_t payload_size)
|
|||
return NULL;
|
||||
}
|
||||
memset(buffer, 0, sizeof(mac_pre_build_frame_t));
|
||||
buffer->aux_header.frameCounter = 0xffffffff;
|
||||
if (payload_size) {
|
||||
//Mac interlnal payload allocate
|
||||
buffer->mac_payload = ns_dyn_mem_temporary_alloc(payload_size);
|
||||
|
@ -1229,7 +1247,7 @@ void mcps_sap_prebuild_frame_buffer_free(mac_pre_build_frame_t *buffer)
|
|||
|
||||
}
|
||||
|
||||
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)
|
||||
static mlme_key_descriptor_t *mac_frame_security_key_get(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *buffer)
|
||||
{
|
||||
/* Encrypt the packet payload if AES encyption bit is set */
|
||||
mlme_security_t key_source;
|
||||
|
@ -1237,13 +1255,13 @@ static bool mac_frame_security_parameters_init(ccm_globals_t *ccm_ptr, protocol_
|
|||
key_source.KeyIndex = buffer->aux_header.KeyIndex;
|
||||
key_source.SecurityLevel = buffer->aux_header.securityLevel;
|
||||
memcpy(key_source.Keysource, buffer->aux_header.Keysource, 8);
|
||||
mlme_key_descriptor_t *key_description = mac_sec_key_description_get(rf_ptr, &key_source, buffer->fcf_dsn.DstAddrMode, buffer->DstAddr, buffer->DstPANId);
|
||||
return mac_sec_key_description_get(rf_ptr, &key_source, buffer->fcf_dsn.DstAddrMode, buffer->DstAddr, buffer->DstPANId);
|
||||
}
|
||||
|
||||
if (!key_description) {
|
||||
buffer->status = MLME_UNAVAILABLE_KEY;
|
||||
return false;
|
||||
|
||||
}
|
||||
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)
|
||||
{
|
||||
/* Encrypt the packet payload if AES encyption bit is set */
|
||||
mlme_device_descriptor_t *device_description;
|
||||
uint8_t *nonce_ext_64_ptr;
|
||||
|
||||
|
@ -1298,6 +1316,7 @@ static void mac_common_data_confirmation_handle(protocol_interface_rf_mac_setup_
|
|||
timer_mac_stop(rf_mac_setup);
|
||||
if (m_event == MAC_CCA_FAIL) {
|
||||
sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_CCA_FAIL, 0);
|
||||
tr_debug("MAC CCA fail");
|
||||
/* CCA fail */
|
||||
//rf_mac_setup->cca_failure++;
|
||||
buf->status = MLME_BUSY_CHAN;
|
||||
|
@ -1305,7 +1324,7 @@ static void mac_common_data_confirmation_handle(protocol_interface_rf_mac_setup_
|
|||
sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_COUNT, buf->mac_payload_length);
|
||||
if (m_event == MAC_TX_FAIL) {
|
||||
sw_mac_stats_update(rf_mac_setup, STAT_MAC_TX_FAIL, 0);
|
||||
tr_error("MAC tx fail");
|
||||
tr_debug("MAC tx fail");
|
||||
buf->status = MLME_TX_NO_ACK;
|
||||
} else if (m_event == MAC_TX_DONE) {
|
||||
if (mac_is_ack_request_set(buf) == false) {
|
||||
|
@ -1517,16 +1536,31 @@ static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_pt
|
|||
mac_header_information_elements_preparation(buffer);
|
||||
|
||||
mcps_generic_sequence_number_allocate(rf_ptr, buffer);
|
||||
|
||||
mlme_key_descriptor_t *key_desc;
|
||||
if (buffer->fcf_dsn.securityEnabled) {
|
||||
bool increment_framecounter = false;
|
||||
//Remember to update security counter here!
|
||||
buffer->aux_header.frameCounter = mac_mlme_framecounter_get(rf_ptr);
|
||||
if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer)) {
|
||||
key_desc = mac_frame_security_key_get(rf_ptr, buffer);
|
||||
if (!key_desc) {
|
||||
buffer->status = MLME_UNAVAILABLE_KEY;
|
||||
return -2;
|
||||
}
|
||||
|
||||
//GET Counter
|
||||
uint32_t new_frameCounter = mac_sec_mib_key_outgoing_frame_counter_get(rf_ptr, key_desc);
|
||||
// If buffer frame counter is set, this is FHSS channel retry, update frame counter only if something was sent after failure
|
||||
if ((buffer->aux_header.frameCounter == 0xffffffff) || buffer->asynch_request || mac_data_counter_too_small(new_frameCounter, buffer->aux_header.frameCounter)) {
|
||||
buffer->aux_header.frameCounter = new_frameCounter;
|
||||
increment_framecounter = true;
|
||||
}
|
||||
|
||||
if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer, key_desc)) {
|
||||
return -2;
|
||||
}
|
||||
//Increment security counter
|
||||
mac_mlme_framecounter_increment(rf_ptr);
|
||||
|
||||
if (increment_framecounter) {
|
||||
mac_sec_mib_key_outgoing_frame_counter_increment(rf_ptr, key_desc);
|
||||
}
|
||||
}
|
||||
|
||||
//Calculate Payload length here with IE extension
|
||||
|
@ -1559,7 +1593,9 @@ static int8_t mcps_generic_packet_build(protocol_interface_rf_mac_setup_s *rf_pt
|
|||
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);
|
||||
buffer->status = MLME_FRAME_TOO_LONG;
|
||||
//decrement security counter
|
||||
mac_mlme_framecounter_decrement(rf_ptr);
|
||||
if (buffer->fcf_dsn.securityEnabled) {
|
||||
mac_sec_mib_key_outgoing_frame_counter_decrement(rf_ptr, key_desc);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1673,19 +1709,24 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, bool in
|
|||
|
||||
ccm_globals_t ccm_ptr;
|
||||
mac_pre_build_frame_t *buffer = &rf_ptr->enhanced_ack_buffer;
|
||||
|
||||
mlme_key_descriptor_t *key_desc;
|
||||
|
||||
if (buffer->fcf_dsn.securityEnabled) {
|
||||
//Remember to update security counter here!
|
||||
if (init_build) {
|
||||
buffer->aux_header.frameCounter = mac_mlme_framecounter_get(rf_ptr);
|
||||
key_desc = mac_frame_security_key_get(rf_ptr, buffer);
|
||||
if (!key_desc) {
|
||||
buffer->status = MLME_UNAVAILABLE_KEY;
|
||||
return -2;
|
||||
}
|
||||
if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer)) {
|
||||
if (init_build) {
|
||||
buffer->aux_header.frameCounter = mac_sec_mib_key_outgoing_frame_counter_get(rf_ptr, key_desc);
|
||||
}
|
||||
if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer, key_desc)) {
|
||||
return -2;
|
||||
}
|
||||
if (init_build) {
|
||||
//Increment security counter
|
||||
mac_mlme_framecounter_increment(rf_ptr);
|
||||
mac_sec_mib_key_outgoing_frame_counter_increment(rf_ptr, key_desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1709,7 +1750,7 @@ int8_t mcps_generic_ack_build(protocol_interface_rf_mac_setup_s *rf_ptr, bool in
|
|||
|
||||
if (buffer->fcf_dsn.securityEnabled) {
|
||||
//decrement security counter
|
||||
mac_mlme_framecounter_decrement(rf_ptr);
|
||||
mac_sec_mib_key_outgoing_frame_counter_decrement(rf_ptr, key_desc);
|
||||
ccm_free(&ccm_ptr);
|
||||
}
|
||||
return -1;
|
||||
|
@ -1770,7 +1811,14 @@ static int8_t mcps_generic_packet_rebuild(protocol_interface_rf_mac_setup_s *rf_
|
|||
}
|
||||
|
||||
if (buffer->fcf_dsn.securityEnabled) {
|
||||
if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer)) {
|
||||
|
||||
mlme_key_descriptor_t *key_desc = mac_frame_security_key_get(rf_ptr, buffer);
|
||||
if (!key_desc) {
|
||||
buffer->status = MLME_UNAVAILABLE_KEY;
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (!mac_frame_security_parameters_init(&ccm_ptr, rf_ptr, buffer, key_desc)) {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
@ -2318,3 +2366,17 @@ int mcps_packet_ingress_rate_limit_by_memory(uint8_t free_heap_percentage)
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void mcps_pending_packet_counter_update_check(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_pre_build_frame_t *buffer)
|
||||
{
|
||||
if (buffer->fcf_dsn.securityEnabled) {
|
||||
mlme_key_descriptor_t *key_desc = mac_frame_security_key_get(rf_mac_setup, buffer);
|
||||
if (key_desc) {
|
||||
uint32_t current_counter = mac_sec_mib_key_outgoing_frame_counter_get(rf_mac_setup, key_desc);
|
||||
if (mac_data_counter_too_small(current_counter, buffer->aux_header.frameCounter)) {
|
||||
buffer->aux_header.frameCounter = current_counter;
|
||||
mac_sec_mib_key_outgoing_frame_counter_increment(rf_mac_setup, key_desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,4 +140,6 @@ int mcps_packet_ingress_rate_limit_by_memory(uint8_t free_heap_percentage);
|
|||
|
||||
uint32_t mac_mcps_sap_get_phy_timestamp(struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
||||
|
||||
void mcps_pending_packet_counter_update_check(struct protocol_interface_rf_mac_setup *rf_mac_setup, mac_pre_build_frame_t *buffer);
|
||||
|
||||
#endif /* MAC_IEEE802_15_4_MAC_MCPS_SAP_H_ */
|
||||
|
|
|
@ -606,15 +606,21 @@ static int8_t mac_mlme_8bit_set(protocol_interface_rf_mac_setup_s *rf_mac_setup,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int8_t mac_mlme_32bit_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_attr_t attribute, uint32_t value)
|
||||
static int8_t mac_mlme_32bit_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_attr_t attribute, uint8_t index, uint32_t value)
|
||||
{
|
||||
(void)rf_mac_setup;
|
||||
(void) value;
|
||||
|
||||
switch (attribute) {
|
||||
case macFrameCounter:
|
||||
platform_enter_critical();
|
||||
rf_mac_setup->security_frame_counter = value;
|
||||
platform_exit_critical();
|
||||
if (rf_mac_setup->secFrameCounterPerKey) {
|
||||
mlme_key_descriptor_t *key_desc = mac_sec_key_description_get_by_attribute(rf_mac_setup, index);
|
||||
if (!key_desc) {
|
||||
return -1;
|
||||
}
|
||||
mac_sec_mib_key_outgoing_frame_counter_set(rf_mac_setup, key_desc, value);
|
||||
} else {
|
||||
mac_sec_mib_key_outgoing_frame_counter_set(rf_mac_setup, NULL, value);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -718,7 +724,7 @@ static int8_t mac_mlme_handle_set_values(protocol_interface_rf_mac_setup_s *rf_m
|
|||
return mac_mlme_16bit_set(rf_mac_setup, set_req->attr, *pu16);
|
||||
} else if (set_req->value_size == 4) {
|
||||
const uint32_t *pu32 = set_req->value_pointer;
|
||||
return mac_mlme_32bit_set(rf_mac_setup, set_req->attr, *pu32);
|
||||
return mac_mlme_32bit_set(rf_mac_setup, set_req->attr, set_req->attr_index, *pu32);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -787,30 +793,6 @@ int8_t mac_mlme_set_req(protocol_interface_rf_mac_setup_s *rf_mac_setup, const m
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t mac_mlme_framecounter_get(struct protocol_interface_rf_mac_setup *rf_mac_setup)
|
||||
{
|
||||
uint32_t value;
|
||||
platform_enter_critical();
|
||||
value = rf_mac_setup->security_frame_counter;
|
||||
platform_exit_critical();
|
||||
return value;
|
||||
}
|
||||
|
||||
void mac_mlme_framecounter_increment(struct protocol_interface_rf_mac_setup *rf_mac_setup)
|
||||
{
|
||||
platform_enter_critical();
|
||||
rf_mac_setup->security_frame_counter++;
|
||||
platform_exit_critical();
|
||||
}
|
||||
|
||||
void mac_mlme_framecounter_decrement(struct protocol_interface_rf_mac_setup *rf_mac_setup)
|
||||
{
|
||||
platform_enter_critical();
|
||||
rf_mac_setup->security_frame_counter--;
|
||||
platform_exit_critical();
|
||||
}
|
||||
|
||||
|
||||
int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_get_conf_t *get_req)
|
||||
{
|
||||
if (!get_req || !rf_mac_setup) {
|
||||
|
@ -833,9 +815,16 @@ int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, ml
|
|||
break;
|
||||
|
||||
case macFrameCounter:
|
||||
platform_enter_critical();
|
||||
get_req->value_pointer = &rf_mac_setup->security_frame_counter;
|
||||
platform_exit_critical();
|
||||
if (rf_mac_setup->secFrameCounterPerKey) {
|
||||
mlme_key_descriptor_t *key_desc = mac_sec_key_description_get_by_attribute(rf_mac_setup, get_req->attr_index);
|
||||
if (!key_desc) {
|
||||
return -1;
|
||||
}
|
||||
get_req->value_pointer = &key_desc->KeyFrameCounter;
|
||||
} else {
|
||||
get_req->value_pointer = &rf_mac_setup->security_frame_counter;
|
||||
}
|
||||
|
||||
get_req->value_size = 4;
|
||||
break;
|
||||
|
||||
|
@ -1344,8 +1333,6 @@ int mac_mlme_beacon_notify(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme
|
|||
mac->mlme_ind_cb(mac, MLME_BEACON_NOTIFY, data);
|
||||
}
|
||||
|
||||
tr_debug("Beacon Notify: %s", trace_array(data->beacon_data, data->beacon_data_length));
|
||||
|
||||
if (rf_mac_setup->mac_mlme_scan_resp) {
|
||||
mlme_scan_conf_t *conf = rf_mac_setup->mac_mlme_scan_resp;
|
||||
update_beacon = add_or_update_beacon(conf, data, rf_mac_setup->fhss_api);
|
||||
|
|
|
@ -65,11 +65,6 @@ int8_t mac_mlme_get_req(struct protocol_interface_rf_mac_setup *rf_mac_setup, st
|
|||
|
||||
void mac_extended_mac_set(struct protocol_interface_rf_mac_setup *rf_mac_setup, const uint8_t *mac64);
|
||||
|
||||
uint32_t mac_mlme_framecounter_get(struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
||||
|
||||
void mac_mlme_framecounter_increment(struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
||||
void mac_mlme_framecounter_decrement(struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
||||
|
||||
/**
|
||||
* MLME Poll Request
|
||||
*
|
||||
|
|
|
@ -387,14 +387,6 @@ static void mac_sap_no_ack_cb(protocol_interface_rf_mac_setup_s *rf_ptr)
|
|||
}
|
||||
}
|
||||
|
||||
static bool mac_data_counter_too_small(uint32_t current_counter, uint32_t packet_counter)
|
||||
{
|
||||
if ((current_counter - packet_counter) >= 2) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool mac_data_asynch_channel_switch(protocol_interface_rf_mac_setup_s *rf_ptr, mac_pre_build_frame_t *active_buf)
|
||||
{
|
||||
|
@ -420,13 +412,7 @@ static void mac_data_ack_tx_finish(protocol_interface_rf_mac_setup_s *rf_ptr)
|
|||
}
|
||||
if (rf_ptr->active_pd_data_request) {
|
||||
|
||||
if (rf_ptr->active_pd_data_request->fcf_dsn.securityEnabled) {
|
||||
uint32_t current_counter = mac_mlme_framecounter_get(rf_ptr);
|
||||
if (mac_data_counter_too_small(current_counter, rf_ptr->active_pd_data_request->aux_header.frameCounter)) {
|
||||
rf_ptr->active_pd_data_request->aux_header.frameCounter = current_counter;
|
||||
mac_mlme_framecounter_increment(rf_ptr);
|
||||
}
|
||||
}
|
||||
mcps_pending_packet_counter_update_check(rf_ptr, rf_ptr->active_pd_data_request);
|
||||
//GEN TX failure
|
||||
mac_sap_cca_fail_cb(rf_ptr);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "ns_types.h"
|
||||
#include "ns_trace.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "platform/arm_hal_interrupt.h"
|
||||
#include "mac_api.h"
|
||||
#include "sw_mac.h"
|
||||
#include "mac_common_defines.h"
|
||||
|
@ -78,6 +79,42 @@ static mlme_key_id_lookup_descriptor_t *mac_sec_mib_key_lookup_table_allocate(ui
|
|||
return table_ptr;
|
||||
}
|
||||
|
||||
static int mac_sec_mib_frame_counter_key_buffer_allocate(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint16_t list_size, uint16_t device_count)
|
||||
{
|
||||
rf_mac_setup->key_device_frame_counter_list_buffer = ns_dyn_mem_alloc(sizeof(uint32_t) * list_size * device_count);
|
||||
if (!rf_mac_setup->key_device_frame_counter_list_buffer) {
|
||||
return -1;
|
||||
}
|
||||
memset(rf_mac_setup->key_device_frame_counter_list_buffer, 0, (sizeof(uint32_t) * list_size * device_count));
|
||||
rf_mac_setup->secFrameCounterPerKey = true;
|
||||
mlme_key_descriptor_t *key_descriptor_list = rf_mac_setup->key_description_table;
|
||||
uint32_t *frame_counter_pointer = rf_mac_setup->key_device_frame_counter_list_buffer;
|
||||
for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
|
||||
key_descriptor_list->KeyDeviceFrameCouterList = frame_counter_pointer;
|
||||
key_descriptor_list->KeyFrameCounterPerKey = true;
|
||||
key_descriptor_list->KeyFrameCounter = 0;
|
||||
//Update Pointers
|
||||
key_descriptor_list++;
|
||||
frame_counter_pointer += device_count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mac_sec_mib_frame_counter_key_buffer_free(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||
{
|
||||
mlme_key_descriptor_t *key_descriptor_list = rf_mac_setup->key_description_table;
|
||||
for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
|
||||
key_descriptor_list->KeyDeviceFrameCouterList = NULL;
|
||||
key_descriptor_list->KeyFrameCounterPerKey = false;
|
||||
//Update Pointers
|
||||
key_descriptor_list++;
|
||||
}
|
||||
ns_dyn_mem_free(rf_mac_setup->key_device_frame_counter_list_buffer);
|
||||
rf_mac_setup->key_device_frame_counter_list_buffer = NULL;
|
||||
rf_mac_setup->secFrameCounterPerKey = false;
|
||||
}
|
||||
|
||||
static mlme_device_descriptor_t *mac_sec_mib_device_description_get_by_mac16(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint16_t mac16)
|
||||
{
|
||||
|
||||
|
@ -134,6 +171,11 @@ static void mac_sec_mib_key_device_description_remove_from_list(mlme_key_descrip
|
|||
|
||||
if (removed_entry) {
|
||||
key_descpription_table->KeyDeviceListEntries--;
|
||||
//Clear Also frame counter per key if it its enabled
|
||||
if (key_descpription_table->KeyFrameCounterPerKey) {
|
||||
//SET frame counter to 0
|
||||
mac_sec_mib_key_device_frame_counter_set(key_descpription_table, NULL, 0, device_descriptor_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,7 +276,6 @@ int8_t mac_sec_mib_device_description_set(uint8_t atribute_index, mlme_device_de
|
|||
|
||||
//validate index to list size
|
||||
if (!rf_mac_setup || !device_descriptor || atribute_index >= rf_mac_setup->device_description_table_size) {
|
||||
tr_debug("Too many Devices");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -302,6 +343,17 @@ int8_t mac_sec_mib_key_description_set(uint8_t atribute_index, mlme_key_descript
|
|||
memcpy(key_ptr->KeyUsageList, key_descriptor->KeyUsageList, sizeof(mlme_key_usage_descriptor_t) * key_ptr->KeyUsageListEntries);
|
||||
}
|
||||
|
||||
if (key_ptr->KeyFrameCounterPerKey) {
|
||||
key_ptr->KeyFrameCounter = 0;
|
||||
if (key_ptr->KeyDeviceListEntries == 0) {
|
||||
//Clear all frame counters from old possible user's
|
||||
uint32_t *counter_ptr = key_ptr->KeyDeviceFrameCouterList;
|
||||
for (int i = 0; i < rf_mac_setup->device_description_table_size; i++) {
|
||||
*counter_ptr++ = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -414,6 +466,17 @@ mlme_key_descriptor_t *mac_sec_key_description_get(protocol_interface_rf_mac_set
|
|||
return NULL;
|
||||
}
|
||||
|
||||
mlme_key_descriptor_t *mac_sec_key_description_get_by_attribute(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t atribute_index)
|
||||
{
|
||||
//validate index to list size
|
||||
if (atribute_index >= rf_mac_setup->key_description_table_size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
return rf_mac_setup->key_description_table + atribute_index;
|
||||
}
|
||||
|
||||
int8_t mac_sec_mib_init(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_description_storage_size_t *storage_sizes)
|
||||
{
|
||||
|
||||
|
@ -434,16 +497,102 @@ int8_t mac_sec_mib_init(protocol_interface_rf_mac_setup_s *rf_mac_setup, mac_des
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int8_t mac_sec_mib_frame_counter_per_key_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, bool enabled)
|
||||
{
|
||||
if (enabled) {
|
||||
if (rf_mac_setup->key_device_frame_counter_list_buffer) {
|
||||
return 0;
|
||||
}
|
||||
return mac_sec_mib_frame_counter_key_buffer_allocate(rf_mac_setup, rf_mac_setup->key_description_table_size, rf_mac_setup->device_description_table_size);
|
||||
}
|
||||
|
||||
//Clear Key Descriptors
|
||||
|
||||
//Free current list
|
||||
mac_sec_mib_frame_counter_key_buffer_free(rf_mac_setup);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void mac_sec_mib_deinit(protocol_interface_rf_mac_setup_s *rf_mac_setup)
|
||||
{
|
||||
if (!rf_mac_setup) {
|
||||
return;
|
||||
}
|
||||
mac_sec_mib_frame_counter_key_buffer_free(rf_mac_setup);
|
||||
mac_sec_mib_device_description_table_deinit(rf_mac_setup);
|
||||
mac_sec_mib_key_description_table_deinit(rf_mac_setup);
|
||||
|
||||
}
|
||||
|
||||
uint32_t mac_sec_mib_key_outgoing_frame_counter_get(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_key_descriptor_t *key_descpription)
|
||||
{
|
||||
uint32_t value;
|
||||
platform_enter_critical();
|
||||
if (key_descpription && key_descpription->KeyFrameCounterPerKey) {
|
||||
value = key_descpription->KeyFrameCounter;
|
||||
} else {
|
||||
value = rf_mac_setup->security_frame_counter;
|
||||
}
|
||||
platform_exit_critical();
|
||||
return value;
|
||||
}
|
||||
|
||||
void mac_sec_mib_key_outgoing_frame_counter_set(protocol_interface_rf_mac_setup_s *rf_mac_setup, mlme_key_descriptor_t *key_descpription, uint32_t value)
|
||||
{
|
||||
platform_enter_critical();
|
||||
if (key_descpription && key_descpription->KeyFrameCounterPerKey) {
|
||||
key_descpription->KeyFrameCounter = value;
|
||||
} else {
|
||||
rf_mac_setup->security_frame_counter = value;
|
||||
}
|
||||
platform_exit_critical();
|
||||
}
|
||||
|
||||
void mac_sec_mib_key_outgoing_frame_counter_increment(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_key_descriptor_t *key_descpription)
|
||||
{
|
||||
platform_enter_critical();
|
||||
if (key_descpription && key_descpription->KeyFrameCounterPerKey) {
|
||||
key_descpription->KeyFrameCounter++;
|
||||
} else {
|
||||
rf_mac_setup->security_frame_counter++;
|
||||
}
|
||||
platform_exit_critical();
|
||||
}
|
||||
|
||||
void mac_sec_mib_key_outgoing_frame_counter_decrement(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_key_descriptor_t *key_descpription)
|
||||
{
|
||||
platform_enter_critical();
|
||||
if (key_descpription && key_descpription->KeyFrameCounterPerKey) {
|
||||
key_descpription->KeyFrameCounter--;
|
||||
} else {
|
||||
rf_mac_setup->security_frame_counter--;
|
||||
}
|
||||
platform_exit_critical();
|
||||
}
|
||||
|
||||
|
||||
void mac_sec_mib_key_device_frame_counter_set(mlme_key_descriptor_t *key_descpription_table, mlme_device_descriptor_t *device_info, uint32_t frame_counter, uint8_t attribute_index)
|
||||
{
|
||||
if (key_descpription_table->KeyFrameCounterPerKey) {
|
||||
uint32_t *counter_ptr = key_descpription_table->KeyDeviceFrameCouterList + attribute_index;
|
||||
*counter_ptr = frame_counter;
|
||||
} else {
|
||||
device_info->FrameCounter = frame_counter;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t mac_mib_key_device_frame_counter_get(mlme_key_descriptor_t *key_descpription_table, mlme_device_descriptor_t *device_info, uint8_t attribute_index)
|
||||
{
|
||||
if (key_descpription_table->KeyFrameCounterPerKey) {
|
||||
uint32_t *counter_ptr = key_descpription_table->KeyDeviceFrameCouterList + attribute_index;
|
||||
return *counter_ptr;
|
||||
}
|
||||
return device_info->FrameCounter;
|
||||
}
|
||||
|
||||
|
||||
//allocate new entry and update entries size
|
||||
mlme_key_device_descriptor_t *mac_sec_mib_key_device_description_list_update(mlme_key_descriptor_t *key_descpription_table)
|
||||
{
|
||||
|
@ -477,7 +626,6 @@ mlme_key_device_descriptor_t *mac_sec_mib_key_device_description_discover_from_l
|
|||
|
||||
void mac_sec_mib_device_description_blacklist(protocol_interface_rf_mac_setup_s *rf_mac_setup, uint8_t device_handle)
|
||||
{
|
||||
|
||||
if (!rf_mac_setup) {
|
||||
return;
|
||||
}
|
||||
|
@ -485,7 +633,6 @@ void mac_sec_mib_device_description_blacklist(protocol_interface_rf_mac_setup_s
|
|||
for (uint8_t i = 0; i < rf_mac_setup->key_description_table_size; i++) {
|
||||
descriptor = mac_sec_mib_key_device_description_discover_from_list(&rf_mac_setup->key_description_table[i], device_handle);
|
||||
if (descriptor) {
|
||||
tr_debug("Black listed device %u", device_handle);
|
||||
descriptor->Blacklisted = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,21 +25,26 @@ struct mac_description_storage_size_s;
|
|||
|
||||
typedef struct mlme_key_descriptor_s {
|
||||
mlme_key_id_lookup_descriptor_t *KeyIdLookupList;
|
||||
uint8_t KeyIdLookupListEntries;
|
||||
mlme_key_device_descriptor_t *KeyDeviceList;
|
||||
mlme_key_usage_descriptor_t *KeyUsageList;
|
||||
uint32_t *KeyDeviceFrameCouterList;
|
||||
uint32_t KeyFrameCounter;
|
||||
uint8_t Key[16];
|
||||
uint8_t KeyDeviceListSize;
|
||||
uint8_t KeyDeviceListEntries;
|
||||
mlme_key_usage_descriptor_t *KeyUsageList;
|
||||
uint8_t KeyIdLookupListEntries;
|
||||
uint8_t KeyUsageListEntries;
|
||||
uint8_t KeyUsageListSize;
|
||||
uint8_t Key[16];
|
||||
bool unique_key_descriptor;
|
||||
bool unique_key_descriptor: 1;
|
||||
bool KeyFrameCounterPerKey: 1;
|
||||
} mlme_key_descriptor_t;
|
||||
|
||||
int8_t mac_sec_mib_init(struct protocol_interface_rf_mac_setup *rf_mac_setup, struct mac_description_storage_size_s *storage_sizes);
|
||||
|
||||
void mac_sec_mib_deinit(struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
||||
|
||||
int8_t mac_sec_mib_frame_counter_per_key_set(struct protocol_interface_rf_mac_setup *rf_mac_setup, bool enabled);
|
||||
|
||||
int8_t mac_sec_mib_device_description_set(uint8_t atribute_index, mlme_device_descriptor_t *device_descriptor, struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
||||
|
||||
int8_t mac_sec_mib_key_description_set(uint8_t atribute_index, mlme_key_descriptor_entry_t *key_descriptor, struct protocol_interface_rf_mac_setup *rf_mac_setup);
|
||||
|
@ -52,10 +57,24 @@ uint8_t mac_mib_device_descption_attribute_get_by_descriptor(struct protocol_int
|
|||
|
||||
mlme_key_descriptor_t *mac_sec_key_description_get(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_security_t *key_source, uint8_t address_mode, uint8_t *address_ptr, uint16_t pan_id);
|
||||
|
||||
mlme_key_descriptor_t *mac_sec_key_description_get_by_attribute(struct protocol_interface_rf_mac_setup *rf_mac_setup, uint8_t atribute_index);
|
||||
|
||||
mlme_key_device_descriptor_t *mac_sec_mib_key_device_description_list_update(mlme_key_descriptor_t *key_descpription_table);
|
||||
|
||||
mlme_key_device_descriptor_t *mac_sec_mib_key_device_description_discover_from_list(mlme_key_descriptor_t *key_descpription_table, uint8_t device_descriptor_handle);
|
||||
|
||||
void mac_sec_mib_device_description_blacklist(struct protocol_interface_rf_mac_setup *rf_mac_setup, uint8_t device_handle);
|
||||
|
||||
void mac_sec_mib_key_device_frame_counter_set(mlme_key_descriptor_t *key_descpription_table, mlme_device_descriptor_t *device_info, uint32_t frame_counter, uint8_t attribute_index);
|
||||
|
||||
uint32_t mac_mib_key_device_frame_counter_get(mlme_key_descriptor_t *key_descpription_table, mlme_device_descriptor_t *device_info, uint8_t attribute_index);
|
||||
|
||||
uint32_t mac_sec_mib_key_outgoing_frame_counter_get(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_key_descriptor_t *key_descpription);
|
||||
|
||||
void mac_sec_mib_key_outgoing_frame_counter_set(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_key_descriptor_t *key_descpription, uint32_t value);
|
||||
|
||||
void mac_sec_mib_key_outgoing_frame_counter_increment(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_key_descriptor_t *key_descpription);
|
||||
|
||||
void mac_sec_mib_key_outgoing_frame_counter_decrement(struct protocol_interface_rf_mac_setup *rf_mac_setup, mlme_key_descriptor_t *key_descpription);
|
||||
|
||||
#endif /* MAC_SECURITY_MIB_H_ */
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "MAC/IEEE802_15_4/mac_defines.h"
|
||||
#include "MAC/IEEE802_15_4/mac_mcps_sap.h"
|
||||
#include "MAC/IEEE802_15_4/mac_pd_sap.h"
|
||||
#include "MAC/IEEE802_15_4/mac_security_mib.h"
|
||||
#include "MAC/rf_driver_storage.h"
|
||||
#include "MAC/virtual_rf/virtual_rf_defines.h"
|
||||
#include "mac_fhss_callbacks.h"
|
||||
|
@ -123,6 +124,14 @@ mac_api_t *ns_sw_mac_create(int8_t rf_driver_id, mac_description_storage_size_t
|
|||
return this;
|
||||
}
|
||||
|
||||
int8_t ns_sw_mac_enable_frame_counter_per_key(struct mac_api_s *mac_api_s, bool enable_feature)
|
||||
{
|
||||
if (!mac_api_s || mac_api_s != mac_store.mac_api) {
|
||||
return -1;
|
||||
}
|
||||
return mac_sec_mib_frame_counter_per_key_set(mac_store.setup, enable_feature);
|
||||
}
|
||||
|
||||
int8_t ns_sw_mac_virtual_client_register(mac_api_t *api, int8_t virtual_driver_id)
|
||||
{
|
||||
if (!api || api != mac_store.mac_api) {
|
||||
|
|
|
@ -176,6 +176,21 @@ void rpl_control_request_parent_link_confirmation(bool requested)
|
|||
rpl_policy_set_parent_confirmation_request(requested);
|
||||
}
|
||||
|
||||
void rpl_control_set_dio_multicast_min_config_advertisment_count(uint8_t min_count)
|
||||
{
|
||||
rpl_policy_set_dio_multicast_config_advertisment_min_count(min_count);
|
||||
}
|
||||
|
||||
void rpl_control_set_dao_retry_count(uint8_t count)
|
||||
{
|
||||
rpl_policy_set_dao_retry_count(count);
|
||||
}
|
||||
|
||||
void rpl_control_set_initial_dao_ack_wait(uint16_t timeout_in_ms)
|
||||
{
|
||||
rpl_policy_set_initial_dao_ack_wait(timeout_in_ms);
|
||||
}
|
||||
|
||||
/* Send address registration to either specified address, or to non-registered address */
|
||||
void rpl_control_register_address(protocol_interface_info_entry_t *interface, const uint8_t addr[16])
|
||||
{
|
||||
|
@ -340,16 +355,24 @@ void rpl_control_delete_domain(rpl_domain_t *domain)
|
|||
rpl_free(domain, sizeof * domain);
|
||||
}
|
||||
|
||||
static void rpl_control_remove_interface_from_domain(protocol_interface_info_entry_t *cur, rpl_domain_t *domain)
|
||||
static void rpl_control_remove_interface_from_domain(protocol_interface_info_entry_t *cur, rpl_domain_t *domain, bool free_instances)
|
||||
{
|
||||
ns_list_foreach(rpl_instance_t, instance, &domain->instances) {
|
||||
rpl_instance_remove_interface(instance, cur->id);
|
||||
}
|
||||
|
||||
ns_list_foreach(if_address_entry_t, addr, &cur->ip_addresses) {
|
||||
if (!addr_is_ipv6_link_local(addr->address)) {
|
||||
rpl_control_unpublish_address(domain, addr->address);
|
||||
}
|
||||
}
|
||||
|
||||
if (free_instances) {
|
||||
ns_list_foreach_safe(rpl_instance_t, instance, &domain->instances) {
|
||||
rpl_delete_instance(instance);
|
||||
}
|
||||
}
|
||||
|
||||
if (domain->non_storing_downstream_interface == cur->id) {
|
||||
domain->non_storing_downstream_interface = -1;
|
||||
}
|
||||
|
@ -374,7 +397,16 @@ void rpl_control_set_domain_on_interface(protocol_interface_info_entry_t *cur, r
|
|||
void rpl_control_remove_domain_from_interface(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
if (cur->rpl_domain) {
|
||||
rpl_control_remove_interface_from_domain(cur, cur->rpl_domain);
|
||||
rpl_control_remove_interface_from_domain(cur, cur->rpl_domain, false);
|
||||
addr_delete_group(cur, ADDR_LINK_LOCAL_ALL_RPL_NODES);
|
||||
cur->rpl_domain = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void rpl_control_free_domain_instances_from_interface(protocol_interface_info_entry_t *cur)
|
||||
{
|
||||
if (cur->rpl_domain) {
|
||||
rpl_control_remove_interface_from_domain(cur, cur->rpl_domain, true);
|
||||
addr_delete_group(cur, ADDR_LINK_LOCAL_ALL_RPL_NODES);
|
||||
cur->rpl_domain = NULL;
|
||||
}
|
||||
|
@ -1368,6 +1400,7 @@ void rpl_control_transmit_dis(rpl_domain_t *domain, protocol_interface_info_entr
|
|||
|
||||
buffer_data_end_set(buf, ptr);
|
||||
rpl_control_transmit(domain, cur, ICMPV6_CODE_RPL_DIS, buf, dst);
|
||||
tr_info("Transmit DIS");
|
||||
}
|
||||
|
||||
#ifdef HAVE_RPL_DAO_HANDLING
|
||||
|
|
|
@ -145,6 +145,7 @@ rpl_domain_t *rpl_control_create_domain(void);
|
|||
void rpl_control_delete_domain(rpl_domain_t *domain);
|
||||
void rpl_control_set_domain_on_interface(struct protocol_interface_info_entry *cur, rpl_domain_t *domain, bool downstream);
|
||||
void rpl_control_remove_domain_from_interface(struct protocol_interface_info_entry *cur);
|
||||
void rpl_control_free_domain_instances_from_interface(struct protocol_interface_info_entry *cur);
|
||||
void rpl_control_set_callback(rpl_domain_t *domain, rpl_domain_callback_t callback, rpl_prefix_callback_t prefix_learn_cb, rpl_new_parent_callback_t new_parent_add, void *cb_handle);
|
||||
|
||||
/* Target publishing */
|
||||
|
@ -156,6 +157,9 @@ uint16_t rpl_control_parent_candidate_list_size(struct protocol_interface_info_e
|
|||
void rpl_control_neighbor_delete(struct protocol_interface_info_entry *interface, const uint8_t ll_addr[16]);
|
||||
/* Parent link confirmation API extension */
|
||||
void rpl_control_request_parent_link_confirmation(bool requested);
|
||||
void rpl_control_set_dio_multicast_min_config_advertisment_count(uint8_t min_count);
|
||||
void rpl_control_set_dao_retry_count(uint8_t count);
|
||||
void rpl_control_set_initial_dao_ack_wait(uint16_t timeout_in_ms);
|
||||
void rpl_control_register_address(struct protocol_interface_info_entry *interface, const uint8_t addr[16]);
|
||||
void rpl_control_address_register_done(struct protocol_interface_info_entry *interface, const uint8_t ll_addr[16], uint8_t status);
|
||||
|
||||
|
@ -178,6 +182,7 @@ uint16_t rpl_control_current_rank(const struct rpl_instance *instance);
|
|||
#define rpl_control_fast_timer(ticks) ((void) 0)
|
||||
#define rpl_control_slow_timer(seconds) ((void) 0)
|
||||
#define rpl_control_remove_domain_from_interface(cur) ((void) 0)
|
||||
#define rpl_control_free_domain_instances_from_interface(cur) ((void) 0)
|
||||
#define rpl_control_register_address(interface, addr) ((void) 0)
|
||||
#define rpl_control_address_register_done(interface, ll_addr, status) ((void) 0)
|
||||
|
||||
|
|
|
@ -712,6 +712,21 @@ void rpl_instance_send_dao_update(rpl_instance_t *instance)
|
|||
return;
|
||||
}
|
||||
|
||||
if (rpl_policy_dao_retry_count() > 0 && instance->dao_attempt >= rpl_policy_dao_retry_count()) {
|
||||
// Check if recovery logic is started
|
||||
// after half the retries are done we remove the primary parent
|
||||
tr_info("DAO remove primary parent");
|
||||
rpl_neighbour_t *neighbour = ns_list_get_first(&instance->candidate_neighbours);
|
||||
if (neighbour) {
|
||||
rpl_delete_neighbour(instance, neighbour);
|
||||
}
|
||||
// Set parameters to restart
|
||||
instance->dao_in_transit = false;
|
||||
instance->dao_attempt = 0;
|
||||
instance->dao_retry_timer = 0;
|
||||
instance->delay_dao_timer = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Which parent this DAO will be for if storing */
|
||||
rpl_neighbour_t *parent = NULL;
|
||||
|
@ -847,6 +862,15 @@ void rpl_instance_send_dao_update(rpl_instance_t *instance)
|
|||
cur = NULL;
|
||||
}
|
||||
|
||||
if (instance->dao_attempt > 0) {
|
||||
// Start informing problem in routing. This will cause us to select secondary routes when sending the DAO
|
||||
tr_info("DAO reachability problem");
|
||||
protocol_interface_info_entry_t *interface = protocol_stack_interface_info_get_by_rpl_domain(instance->domain, -1);
|
||||
if (interface) {
|
||||
ipv6_neighbour_reachability_problem(dst, interface->id);
|
||||
}
|
||||
}
|
||||
|
||||
bool need_ack = rpl_control_transmit_dao(instance->domain, cur, instance, instance->id, instance->dao_sequence, dodag->id, opts, ptr - opts, dst);
|
||||
ns_dyn_mem_free(opts);
|
||||
|
||||
|
@ -1859,7 +1883,7 @@ void rpl_instance_address_registration_done(protocol_interface_info_entry_t *int
|
|||
if (status == SOCKET_TX_DONE) {
|
||||
/* State_timer is 1/10 s. Set renewal to 75-85% of lifetime */
|
||||
if_address_entry_t *address = rpl_interface_addr_get(interface, dao_target->prefix);
|
||||
if (address) {
|
||||
if (address && address->source != ADDR_SOURCE_DHCP) {
|
||||
address->state_timer = (address->preferred_lifetime * randLIB_get_random_in_range(75, 85) / 10);
|
||||
}
|
||||
neighbour->confirmed = true;
|
||||
|
|
|
@ -35,6 +35,11 @@
|
|||
#define TRACE_GROUP "RPLy"
|
||||
|
||||
static bool rpl_policy_parent_confirmation_req = false;
|
||||
static int8_t rpl_policy_dao_retry_count_conf = 0;
|
||||
static int16_t rpl_policy_dao_initial_timeout_conf = 20; // Default is 2 seconds 100ms ticks
|
||||
static uint16_t rpl_policy_dio_validity_period_hysteresis = 0x0180; //Fixed Point 1.5
|
||||
static uint8_t rpl_policy_multicast_config_min_advertisment_count = 0;
|
||||
|
||||
|
||||
/* TODO - application API to control when to join new instances / DODAGs
|
||||
*
|
||||
|
@ -105,6 +110,11 @@ bool rpl_policy_request_dao_acks(const rpl_domain_t *domain, uint8_t mop)
|
|||
return true;
|
||||
}
|
||||
|
||||
void rpl_policy_set_initial_dao_ack_wait(uint16_t timeout_in_ms)
|
||||
{
|
||||
rpl_policy_dao_initial_timeout_conf = timeout_in_ms;
|
||||
}
|
||||
|
||||
uint16_t rpl_policy_initial_dao_ack_wait(const rpl_domain_t *domain, uint8_t mop)
|
||||
{
|
||||
(void)mop;
|
||||
|
@ -120,7 +130,18 @@ uint16_t rpl_policy_initial_dao_ack_wait(const rpl_domain_t *domain, uint8_t mop
|
|||
}
|
||||
}
|
||||
|
||||
return 20; /* *100ms ticks = 2s */
|
||||
return rpl_policy_dao_initial_timeout_conf;
|
||||
}
|
||||
|
||||
|
||||
void rpl_policy_set_dao_retry_count(uint8_t count)
|
||||
{
|
||||
rpl_policy_dao_retry_count_conf = count;
|
||||
}
|
||||
|
||||
int8_t rpl_policy_dao_retry_count()
|
||||
{
|
||||
return rpl_policy_dao_retry_count_conf;
|
||||
}
|
||||
|
||||
/* Given the next-hop address from a source routing header, which interface,
|
||||
|
@ -192,6 +213,20 @@ uint16_t rpl_policy_etx_hysteresis(rpl_domain_t *domain)
|
|||
return 0x0080; /* 8.8 fixed-point, so 0.5 */
|
||||
}
|
||||
|
||||
uint16_t rpl_policy_dio_validity_period(rpl_domain_t *domain)
|
||||
{
|
||||
(void)domain;
|
||||
|
||||
return rpl_policy_dio_validity_period_hysteresis; /* Fixed Point */
|
||||
}
|
||||
|
||||
void rpl_policy_set_dio_validity_period(rpl_domain_t *domain, uint16_t fixed_point)
|
||||
{
|
||||
(void)domain;
|
||||
|
||||
rpl_policy_dio_validity_period_hysteresis = fixed_point; /* Fixed Point */
|
||||
}
|
||||
|
||||
uint16_t rpl_policy_etx_change_parent_selection_delay(rpl_domain_t *domain)
|
||||
{
|
||||
(void)domain;
|
||||
|
@ -331,6 +366,16 @@ bool rpl_policy_parent_confirmation_requested(void)
|
|||
return rpl_policy_parent_confirmation_req;
|
||||
}
|
||||
|
||||
uint8_t rpl_policy_dio_multicast_config_advertisment_min_count(void)
|
||||
{
|
||||
return rpl_policy_multicast_config_min_advertisment_count;
|
||||
}
|
||||
|
||||
void rpl_policy_set_dio_multicast_config_advertisment_min_count(uint8_t min_count)
|
||||
{
|
||||
rpl_policy_multicast_config_min_advertisment_count = min_count;
|
||||
}
|
||||
|
||||
|
||||
#ifdef RPL_STRUCTURES_H_
|
||||
#error "rpl_structures.h should not be included by rpl_policy.c"
|
||||
|
|
|
@ -27,11 +27,20 @@ bool rpl_policy_join_config(rpl_domain_t *domain, const rpl_dodag_conf_t *conf,
|
|||
|
||||
bool rpl_policy_request_dao_acks(const rpl_domain_t *domain, uint8_t mop);
|
||||
uint16_t rpl_policy_initial_dao_ack_wait(const rpl_domain_t *domain, uint8_t mop);
|
||||
void rpl_policy_set_initial_dao_ack_wait(uint16_t timeout_in_ms);
|
||||
|
||||
void rpl_policy_set_dao_retry_count(uint8_t count);
|
||||
int8_t rpl_policy_dao_retry_count();
|
||||
|
||||
int8_t rpl_policy_srh_next_hop_interface(rpl_domain_t *domain, int8_t if_id, const uint8_t *next_hop);
|
||||
uint16_t rpl_policy_modify_downward_cost_to_root_neighbour(rpl_domain_t *domain, int8_t if_id, const uint8_t *next_hop, uint16_t cost);
|
||||
|
||||
uint16_t rpl_policy_parent_selection_period(rpl_domain_t *domain);
|
||||
uint16_t rpl_policy_etx_hysteresis(rpl_domain_t *domain);
|
||||
//Return Fixed point multiple which base 1.0 is 0x0100
|
||||
uint16_t rpl_policy_dio_validity_period(rpl_domain_t *domain);
|
||||
//Fixed point must 1.0 is 0x0100
|
||||
void rpl_policy_set_dio_validity_period(rpl_domain_t *domain, uint16_t fixed_point);
|
||||
uint16_t rpl_policy_etx_change_parent_selection_delay(rpl_domain_t *domain);
|
||||
uint16_t rpl_policy_dio_parent_selection_delay(rpl_domain_t *domain);
|
||||
|
||||
|
@ -56,5 +65,7 @@ uint16_t rpl_policy_mrhof_parent_switch_threshold(const rpl_domain_t *domain);
|
|||
uint16_t rpl_policy_mrhof_max_rank_stretch_for_extra_parents(const rpl_domain_t *domain);
|
||||
bool rpl_policy_parent_confirmation_requested(void);
|
||||
void rpl_policy_set_parent_confirmation_request(bool confirmation_requested);
|
||||
uint8_t rpl_policy_dio_multicast_config_advertisment_min_count(void);
|
||||
void rpl_policy_set_dio_multicast_config_advertisment_min_count(uint8_t min_count);
|
||||
|
||||
#endif /* RPL_POLICY_H_ */
|
||||
|
|
|
@ -90,6 +90,7 @@ struct rpl_dodag {
|
|||
bool leaf: 1; /* We are a leaf in this DODAG (by policy) */
|
||||
bool have_config: 1; /* We have the config */
|
||||
bool used: 1; /* We have ever been a member of this DODAG? */
|
||||
uint8_t new_config_advertisment_count; /* We have advertiment new config at multicasti DIO */
|
||||
NS_LIST_HEAD(rpl_dodag_version_t, link) versions; /* List of DODAG versions (newest first) */
|
||||
prefix_list_t prefixes; /* Prefixes advertised in DIO PIOs */
|
||||
rpl_dio_route_list_t routes; /* Routes advertised in DIO RIOs*/
|
||||
|
|
|
@ -635,6 +635,7 @@ rpl_dodag_t *rpl_create_dodag(rpl_instance_t *instance, const uint8_t *dodagid,
|
|||
dodag->have_config = false;
|
||||
dodag->used = false;
|
||||
dodag->g_mop_prf = g_mop_prf;
|
||||
dodag->new_config_advertisment_count = 0;
|
||||
// Default timer parameters and trickle start should never normally
|
||||
// be used - we would set the parameters from the DODAG Config and start
|
||||
// as we join a version. But initialising here catches odd cases where
|
||||
|
@ -728,6 +729,7 @@ bool rpl_dodag_update_config(rpl_dodag_t *dodag, const rpl_dodag_conf_t *conf, c
|
|||
/* They've changed the timing parameters for our currently-in-use trickle timer! */
|
||||
tr_warn("Trickle parameters changed");
|
||||
trickle_start(&dodag->instance->dio_timer, &dodag->dio_timer_params);
|
||||
dodag->new_config_advertisment_count = 0;
|
||||
}
|
||||
dodag->instance->of = rpl_objective_lookup(conf->objective_code_point);
|
||||
/* We could be a leaf of an unknown OCP. Still need an OF to choose parents */
|
||||
|
@ -1355,6 +1357,11 @@ static void trace_info_print(const char *fmt, ...)
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
static uint32_t rpl_dio_imax_time_calculate(uint16_t Imax, uint16_t fixed_point)
|
||||
{
|
||||
return (((uint32_t)Imax * fixed_point) / 0x0100);
|
||||
}
|
||||
|
||||
|
||||
void rpl_instance_run_parent_selection(rpl_instance_t *instance)
|
||||
{
|
||||
|
@ -1438,6 +1445,15 @@ void rpl_instance_run_parent_selection(rpl_instance_t *instance)
|
|||
if (preferred_parent) {
|
||||
// Always stop repair if we find a parent
|
||||
rpl_instance_set_local_repair(instance, false);
|
||||
//Validate time from last DIO
|
||||
|
||||
uint32_t time_between_parent = protocol_core_monotonic_time - preferred_parent->dio_timestamp;
|
||||
uint32_t accepted_time = rpl_dio_imax_time_calculate(instance->current_dodag_version->dodag->dio_timer_params.Imax, rpl_policy_dio_validity_period(instance->domain));
|
||||
|
||||
if (accepted_time < time_between_parent) {
|
||||
rpl_control_transmit_dis(instance->domain, NULL, RPL_SOLINFO_PRED_INSTANCEID, instance->id, NULL, 0, preferred_parent->ll_address);
|
||||
}
|
||||
|
||||
} else if (original_preferred) {
|
||||
// Only start repair if we just lost a parent
|
||||
rpl_instance_set_local_repair(instance, true);
|
||||
|
@ -1533,7 +1549,15 @@ void rpl_instance_dio_trigger(rpl_instance_t *instance, protocol_interface_info_
|
|||
}
|
||||
|
||||
// Always send config in unicasts (as required), never in multicasts (optional)
|
||||
rpl_dodag_conf_t *conf = addr ? &dodag->config : NULL;
|
||||
rpl_dodag_conf_t *conf;
|
||||
if (addr) {
|
||||
conf = &dodag->config;
|
||||
} else if (dodag->new_config_advertisment_count < rpl_policy_dio_multicast_config_advertisment_min_count()) {
|
||||
conf = &dodag->config;
|
||||
dodag->new_config_advertisment_count++;
|
||||
} else {
|
||||
conf = NULL;
|
||||
}
|
||||
|
||||
rpl_control_transmit_dio(instance->domain, cur, instance->id, dodag_version->number, rank, dodag->g_mop_prf, instance->dtsn, dodag, dodag->id, conf, addr);
|
||||
|
||||
|
@ -1921,7 +1945,7 @@ bool rpl_upward_accept_prefix_update(const rpl_dodag_t *dodag_info, const rpl_ne
|
|||
//Calculate Time between from last dio from parent and this neighbour
|
||||
//neighbour dio_timestamp >= pref_parent's, because it's a newly-received message
|
||||
uint32_t time_between_parent = neighbour->dio_timestamp - pref_parent->dio_timestamp;
|
||||
uint32_t accepted_time = (uint32_t)dodag_info->dio_timer_params.Imax * 2;
|
||||
uint32_t accepted_time = rpl_dio_imax_time_calculate(dodag_info->dio_timer_params.Imax, 0x0200);
|
||||
//Accept prefix Update If Time from last DIO is more than 2 x Max
|
||||
if (accepted_time < time_between_parent) {
|
||||
return true;
|
||||
|
|
|
@ -314,6 +314,11 @@ kmp_type_e kmp_api_type_get(kmp_api_t *kmp)
|
|||
return kmp->type;
|
||||
}
|
||||
|
||||
bool kmp_api_receive_disable(kmp_api_t *kmp)
|
||||
{
|
||||
return kmp->receive_disable;
|
||||
}
|
||||
|
||||
kmp_type_e kmp_api_type_from_id_get(uint8_t kmp_id)
|
||||
{
|
||||
switch (kmp_id) {
|
||||
|
|
|
@ -152,6 +152,16 @@ void kmp_api_delete(kmp_api_t *kmp);
|
|||
*/
|
||||
kmp_type_e kmp_api_type_get(kmp_api_t *kmp);
|
||||
|
||||
/**
|
||||
* kmp_api_type_get get receive disabled status
|
||||
*
|
||||
* \param kmp instance
|
||||
*
|
||||
* \return true/false true when receiving has been disabled
|
||||
*
|
||||
*/
|
||||
bool kmp_api_receive_disable(kmp_api_t *kmp);
|
||||
|
||||
/**
|
||||
* kmp_api_type_from_id_get get KMP type from KMP id
|
||||
*
|
||||
|
|
|
@ -98,7 +98,7 @@ static int8_t auth_eap_tls_sec_prot_message_handle(sec_prot_t *prot);
|
|||
static int8_t auth_eap_tls_sec_prot_message_send(sec_prot_t *prot, uint8_t eap_code, uint8_t eap_type, uint8_t tls_state);
|
||||
|
||||
static void auth_eap_tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks);
|
||||
static void auth_eap_tls_sec_prot_init_tls(sec_prot_t *prot);
|
||||
static int8_t auth_eap_tls_sec_prot_init_tls(sec_prot_t *prot);
|
||||
static void auth_eap_tls_sec_prot_delete_tls(sec_prot_t *prot);
|
||||
|
||||
static void auth_eap_tls_sec_prot_seq_id_update(sec_prot_t *prot);
|
||||
|
@ -348,16 +348,16 @@ static int8_t auth_eap_tls_sec_prot_tls_send(sec_prot_t *tls_prot, void *pdu, ui
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void auth_eap_tls_sec_prot_init_tls(sec_prot_t *prot)
|
||||
static int8_t auth_eap_tls_sec_prot_init_tls(sec_prot_t *prot)
|
||||
{
|
||||
eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
|
||||
if (data->tls_prot) {
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->tls_prot = prot->type_get(prot, SEC_PROT_TYPE_TLS);
|
||||
if (!data->tls_prot) {
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->tls_prot->header_size = TLS_HEAD_LEN;
|
||||
|
@ -369,6 +369,8 @@ static void auth_eap_tls_sec_prot_init_tls(sec_prot_t *prot)
|
|||
data->tls_prot->send = auth_eap_tls_sec_prot_tls_send;
|
||||
|
||||
data->tls_ongoing = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void auth_eap_tls_sec_prot_delete_tls(sec_prot_t *prot)
|
||||
|
@ -388,14 +390,17 @@ static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
|
|||
// EAP-TLS authenticator state machine
|
||||
switch (sec_prot_state_get(&data->common)) {
|
||||
case EAP_TLS_STATE_INIT:
|
||||
tr_info("EAP-TLS init");
|
||||
sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_CREATE_REQ);
|
||||
prot->timer_start(prot);
|
||||
break;
|
||||
|
||||
// Wait KMP-CREATE.request
|
||||
case EAP_TLS_STATE_CREATE_REQ:
|
||||
tr_info("EAP-TLS start, eui-64: %s", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
|
||||
|
||||
prot->timer_start(prot);
|
||||
// Set default timeout for the total maximum length of the negotiation
|
||||
sec_prot_default_timeout_set(&data->common);
|
||||
|
||||
// KMP-CREATE.confirm
|
||||
prot->create_conf(prot, SEC_RESULT_OK);
|
||||
|
@ -469,8 +474,11 @@ static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
|
|||
|
||||
// All fragments received for a message
|
||||
if (result == EAP_TLS_MSG_RECEIVE_DONE) {
|
||||
auth_eap_tls_sec_prot_init_tls(prot);
|
||||
|
||||
// Initialize TLS protocol
|
||||
if (auth_eap_tls_sec_prot_init_tls(prot) < 0) {
|
||||
tr_error("TLS init failed");
|
||||
return;
|
||||
}
|
||||
if (data->tls_ongoing) {
|
||||
// Call TLS
|
||||
data->tls_prot->receive(data->tls_prot, data->tls_recv.data, data->tls_recv.total_len);
|
||||
|
@ -538,12 +546,14 @@ static void auth_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
|
|||
sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_FINISHED);
|
||||
break;
|
||||
|
||||
case EAP_TLS_STATE_FINISHED:
|
||||
case EAP_TLS_STATE_FINISHED: {
|
||||
uint8_t *remote_eui_64 = sec_prot_remote_eui_64_addr_get(prot);
|
||||
tr_info("EAP-TLS finished, eui-64: %s", remote_eui_64 ? trace_array(sec_prot_remote_eui_64_addr_get(prot), 8) : "not set");
|
||||
auth_eap_tls_sec_prot_delete_tls(prot);
|
||||
prot->timer_stop(prot);
|
||||
prot->finished(prot);
|
||||
break;
|
||||
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,23 @@ int8_t eap_tls_sec_prot_lib_message_allocate(tls_data_t *data, uint8_t head_len,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int8_t eap_tls_sec_prot_lib_message_realloc(tls_data_t *data, uint8_t head_len, uint16_t new_len)
|
||||
{
|
||||
tls_data_t new_tls_send;
|
||||
|
||||
eap_tls_sec_prot_lib_message_init(&new_tls_send);
|
||||
if (eap_tls_sec_prot_lib_message_allocate(&new_tls_send, head_len, new_len) < 0) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(new_tls_send.data + head_len, data->data + head_len, data->handled_len);
|
||||
new_tls_send.handled_len = data->handled_len;
|
||||
eap_tls_sec_prot_lib_message_free(data);
|
||||
|
||||
*data = new_tls_send;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void eap_tls_sec_prot_lib_message_free(tls_data_t *data)
|
||||
{
|
||||
ns_dyn_mem_free(data->data);
|
||||
|
|
|
@ -72,6 +72,19 @@ extern const uint8_t eap_msg_trace[4][10];
|
|||
*/
|
||||
int8_t eap_tls_sec_prot_lib_message_allocate(tls_data_t *data, uint8_t head_len, uint16_t len);
|
||||
|
||||
/**
|
||||
* eap_tls_sec_prot_lib_message_realloc allocates larger message buffer and copies existing data to it
|
||||
*
|
||||
* \param data data buffer which length is increased
|
||||
* \param head_len header length
|
||||
* \param new_len new length for the buffer
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t eap_tls_sec_prot_lib_message_realloc(tls_data_t *data, uint8_t head_len, uint16_t new_len);
|
||||
|
||||
/**
|
||||
* eap_tls_sec_prot_lib_message_free free message buffer
|
||||
*
|
||||
|
|
|
@ -90,7 +90,7 @@ static int8_t supp_eap_tls_sec_prot_message_handle(sec_prot_t *prot);
|
|||
static int8_t supp_eap_tls_sec_prot_message_send(sec_prot_t *prot, uint8_t eap_code, uint8_t eap_type, uint8_t tls_state);
|
||||
|
||||
static void supp_eap_tls_sec_prot_timer_timeout(sec_prot_t *prot, uint16_t ticks);
|
||||
static void supp_eap_tls_sec_prot_init_tls(sec_prot_t *prot);
|
||||
static int8_t supp_eap_tls_sec_prot_init_tls(sec_prot_t *prot);
|
||||
static void supp_eap_tls_sec_prot_delete_tls(sec_prot_t *prot);
|
||||
|
||||
static void supp_eap_tls_sec_prot_seq_id_update(sec_prot_t *prot);
|
||||
|
@ -360,16 +360,16 @@ static int8_t supp_eap_tls_sec_prot_tls_send(sec_prot_t *tls_prot, void *pdu, ui
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void supp_eap_tls_sec_prot_init_tls(sec_prot_t *prot)
|
||||
static int8_t supp_eap_tls_sec_prot_init_tls(sec_prot_t *prot)
|
||||
{
|
||||
eap_tls_sec_prot_int_t *data = eap_tls_sec_prot_get(prot);
|
||||
if (data->tls_prot) {
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
data->tls_prot = prot->type_get(prot, SEC_PROT_TYPE_TLS);
|
||||
if (!data->tls_prot) {
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->tls_prot->header_size = TLS_HEAD_LEN;
|
||||
|
@ -381,6 +381,8 @@ static void supp_eap_tls_sec_prot_init_tls(sec_prot_t *prot)
|
|||
data->tls_prot->send = supp_eap_tls_sec_prot_tls_send;
|
||||
|
||||
data->tls_ongoing = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void supp_eap_tls_sec_prot_delete_tls(sec_prot_t *prot)
|
||||
|
@ -400,7 +402,9 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
|
|||
// EAP-TLS supplicant state machine
|
||||
switch (sec_prot_state_get(&data->common)) {
|
||||
case EAP_TLS_STATE_INIT:
|
||||
tr_info("EAP-TLS init");
|
||||
sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_REQUEST_ID);
|
||||
prot->timer_start(prot);
|
||||
break;
|
||||
|
||||
// Wait EAP request, Identity (starts handshake on supplicant)
|
||||
|
@ -411,13 +415,14 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
|
|||
return;
|
||||
}
|
||||
|
||||
// Set default timeout for the total maximum length of the negotiation
|
||||
sec_prot_default_timeout_set(&data->common);
|
||||
|
||||
// Store sequence ID
|
||||
supp_eap_tls_sec_prot_seq_id_update(prot);
|
||||
|
||||
tr_info("EAP-TLS start");
|
||||
|
||||
prot->timer_start(prot);
|
||||
|
||||
// Send KMP-CREATE.indication
|
||||
prot->create_ind(prot);
|
||||
sec_prot_state_set(prot, &data->common, EAP_TLS_STATE_CREATE_RESP);
|
||||
|
@ -459,7 +464,10 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
|
|||
data->common.ticks = retry_timeout;
|
||||
|
||||
// Initialize TLS protocol
|
||||
supp_eap_tls_sec_prot_init_tls(prot);
|
||||
if (supp_eap_tls_sec_prot_init_tls(prot) < 0) {
|
||||
tr_error("TLS init failed");
|
||||
return;
|
||||
}
|
||||
// Request TLS to start (send client hello)
|
||||
data->tls_prot->create_req(data->tls_prot, prot->sec_keys);
|
||||
break;
|
||||
|
@ -523,6 +531,7 @@ static void supp_eap_tls_sec_prot_state_machine(sec_prot_t *prot)
|
|||
break;
|
||||
|
||||
case EAP_TLS_STATE_FINISHED:
|
||||
tr_info("EAP-TLS finished");
|
||||
supp_eap_tls_sec_prot_delete_tls(prot);
|
||||
prot->timer_stop(prot);
|
||||
prot->finished(prot);
|
||||
|
|
|
@ -341,6 +341,7 @@ static void auth_fwh_sec_prot_state_machine(sec_prot_t *prot)
|
|||
// 4WH authenticator state machine
|
||||
switch (sec_prot_state_get(&data->common)) {
|
||||
case FWH_STATE_INIT:
|
||||
tr_info("4WH: init");
|
||||
prot->timer_start(prot);
|
||||
sec_prot_state_set(prot, &data->common, FWH_STATE_CREATE_REQ);
|
||||
break;
|
||||
|
@ -349,6 +350,9 @@ static void auth_fwh_sec_prot_state_machine(sec_prot_t *prot)
|
|||
case FWH_STATE_CREATE_REQ:
|
||||
tr_info("4WH: start, eui-64: %s", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
|
||||
|
||||
// Set default timeout for the total maximum length of the negotiation
|
||||
sec_prot_default_timeout_set(&data->common);
|
||||
|
||||
uint8_t *pmk = sec_prot_keys_pmk_get(prot->sec_keys);
|
||||
if (!pmk) { // If PMK is not set fails
|
||||
prot->create_conf(prot, SEC_RESULT_ERROR);
|
||||
|
@ -429,10 +433,13 @@ static void auth_fwh_sec_prot_state_machine(sec_prot_t *prot)
|
|||
sec_prot_state_set(prot, &data->common, FWH_STATE_FINISHED);
|
||||
break;
|
||||
|
||||
case FWH_STATE_FINISHED:
|
||||
case FWH_STATE_FINISHED: {
|
||||
uint8_t *remote_eui_64 = sec_prot_remote_eui_64_addr_get(prot);
|
||||
tr_info("4WH: finished, eui-64: %s", remote_eui_64 ? trace_array(sec_prot_remote_eui_64_addr_get(prot), 8) : "not set");
|
||||
prot->timer_stop(prot);
|
||||
prot->finished(prot);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -310,6 +310,7 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot)
|
|||
// 4WH supplicant state machine
|
||||
switch (sec_prot_state_get(&data->common)) {
|
||||
case FWH_STATE_INIT:
|
||||
tr_info("4WH: init");
|
||||
prot->timer_start(prot);
|
||||
sec_prot_state_set(prot, &data->common, FWH_STATE_MESSAGE_1);
|
||||
break;
|
||||
|
@ -325,6 +326,9 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot)
|
|||
return;
|
||||
}
|
||||
|
||||
// Set default timeout for the total maximum length of the negotiation
|
||||
sec_prot_default_timeout_set(&data->common);
|
||||
|
||||
tr_info("4WH: start");
|
||||
|
||||
// Store authenticator nonce for check when 4WH Message 3 is received
|
||||
|
@ -467,6 +471,7 @@ static void supp_fwh_sec_prot_state_machine(sec_prot_t *prot)
|
|||
break;
|
||||
|
||||
case FWH_STATE_FINISHED:
|
||||
tr_info("4WH: finished");
|
||||
prot->timer_stop(prot);
|
||||
prot->finished(prot);
|
||||
break;
|
||||
|
|
|
@ -293,14 +293,17 @@ static void auth_gkh_sec_prot_state_machine(sec_prot_t *prot)
|
|||
// GKH authenticator state machine
|
||||
switch (sec_prot_state_get(&data->common)) {
|
||||
case GKH_STATE_INIT:
|
||||
tr_info("GKH init");
|
||||
sec_prot_state_set(prot, &data->common, GKH_STATE_CREATE_REQ);
|
||||
prot->timer_start(prot);
|
||||
break;
|
||||
|
||||
// Wait KMP-CREATE.request
|
||||
case GKH_STATE_CREATE_REQ:
|
||||
tr_info("GKH start, eui-64: %s", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
|
||||
|
||||
prot->timer_start(prot);
|
||||
// Set default timeout for the total maximum length of the negotiation
|
||||
sec_prot_default_timeout_set(&data->common);
|
||||
|
||||
// KMP-CREATE.confirm
|
||||
prot->create_conf(prot, SEC_RESULT_OK);
|
||||
|
@ -340,10 +343,13 @@ static void auth_gkh_sec_prot_state_machine(sec_prot_t *prot)
|
|||
sec_prot_state_set(prot, &data->common, GKH_STATE_FINISHED);
|
||||
break;
|
||||
|
||||
case GKH_STATE_FINISHED:
|
||||
case GKH_STATE_FINISHED: {
|
||||
uint8_t *remote_eui_64 = sec_prot_remote_eui_64_addr_get(prot);
|
||||
tr_info("GKH finished, eui-64: %s", remote_eui_64 ? trace_array(sec_prot_remote_eui_64_addr_get(prot), 8) : "not set");
|
||||
prot->timer_stop(prot);
|
||||
prot->finished(prot);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -230,7 +230,9 @@ static void supp_gkh_sec_prot_state_machine(sec_prot_t *prot)
|
|||
// GKH supplicant state machine
|
||||
switch (sec_prot_state_get(&data->common)) {
|
||||
case GKH_STATE_INIT:
|
||||
tr_info("GKH init");
|
||||
sec_prot_state_set(prot, &data->common, GKH_STATE_MESSAGE_1);
|
||||
prot->timer_start(prot);
|
||||
break;
|
||||
|
||||
// Wait GKH message 1 (starts handshake on supplicant)
|
||||
|
@ -243,11 +245,12 @@ static void supp_gkh_sec_prot_state_machine(sec_prot_t *prot)
|
|||
return;
|
||||
}
|
||||
|
||||
// Set default timeout for the total maximum length of the negotiation
|
||||
sec_prot_default_timeout_set(&data->common);
|
||||
|
||||
supp_gkh_sec_prot_security_replay_counter_update(prot);
|
||||
|
||||
tr_debug("GKH start");
|
||||
|
||||
prot->timer_start(prot);
|
||||
tr_info("GKH start");
|
||||
|
||||
// Send KMP-CREATE.indication
|
||||
prot->create_ind(prot);
|
||||
|
@ -267,7 +270,7 @@ static void supp_gkh_sec_prot_state_machine(sec_prot_t *prot)
|
|||
break;
|
||||
|
||||
case GKH_STATE_FINISH:
|
||||
tr_debug("GKH finish");
|
||||
tr_info("GKH finish");
|
||||
|
||||
// KMP-FINISHED.indication,
|
||||
prot->finished_ind(prot, sec_prot_result_get(&data->common), prot->sec_keys);
|
||||
|
@ -275,6 +278,7 @@ static void supp_gkh_sec_prot_state_machine(sec_prot_t *prot)
|
|||
break;
|
||||
|
||||
case GKH_STATE_FINISHED:
|
||||
tr_info("GKH finished");
|
||||
prot->timer_stop(prot);
|
||||
prot->finished(prot);
|
||||
break;
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
|
||||
#define TRACE_GROUP "spce"
|
||||
|
||||
// Length for PEM coded certificate's begin and end certificate text strings
|
||||
#define SEC_PROT_CERT_PEM_HEADER_FOOTER_LEN 52
|
||||
#define SEC_PROT_CERT_PEM_HEADER_STR "-----BEGIN CERTIFICATE-----"
|
||||
|
||||
int8_t sec_prot_certs_init(sec_prot_certs_t *certs)
|
||||
{
|
||||
if (!certs) {
|
||||
|
@ -41,6 +45,8 @@ int8_t sec_prot_certs_init(sec_prot_certs_t *certs)
|
|||
sec_prot_certs_chain_entry_init(&certs->own_cert_chain);
|
||||
ns_list_init(&certs->trusted_cert_chain_list);
|
||||
ns_list_init(&certs->cert_revocat_lists);
|
||||
certs->own_cert_chain_len = 0;
|
||||
certs->ext_cert_valid_enabled = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -56,6 +62,27 @@ void sec_prot_certs_delete(sec_prot_certs_t *certs)
|
|||
sec_prot_certs_revocat_lists_delete(&certs->cert_revocat_lists);
|
||||
}
|
||||
|
||||
int8_t sec_prot_certs_ext_certificate_validation_set(sec_prot_certs_t *certs, bool enabled)
|
||||
{
|
||||
if (!certs) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
certs->ext_cert_valid_enabled = enabled;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool sec_prot_certs_ext_certificate_validation_get(const sec_prot_certs_t *certs)
|
||||
{
|
||||
return certs->ext_cert_valid_enabled;
|
||||
}
|
||||
|
||||
uint16_t sec_prot_certs_own_cert_chain_len_get(const sec_prot_certs_t *certs)
|
||||
{
|
||||
return certs->own_cert_chain_len;
|
||||
}
|
||||
|
||||
cert_chain_entry_t *sec_prot_certs_chain_entry_create(void)
|
||||
{
|
||||
cert_chain_entry_t *entry = ns_dyn_mem_alloc(sizeof(cert_chain_entry_t));
|
||||
|
@ -98,6 +125,28 @@ uint8_t *sec_prot_certs_cert_get(const cert_chain_entry_t *entry, uint8_t index,
|
|||
return entry->cert[index];
|
||||
}
|
||||
|
||||
uint16_t sec_prot_certs_cert_chain_entry_len_get(const cert_chain_entry_t *entry)
|
||||
{
|
||||
uint16_t chain_length = 0;
|
||||
for (uint8_t index = 0; index < SEC_PROT_CERT_CHAIN_DEPTH; index++) {
|
||||
if (entry->cert[index]) {
|
||||
uint16_t cert_length = entry->cert_len[index];
|
||||
// Checks if certificate is in PEM base64 format
|
||||
if (cert_length > SEC_PROT_CERT_PEM_HEADER_FOOTER_LEN &&
|
||||
entry->cert[index][cert_length - 1] == '\0' &&
|
||||
strstr((const char *)entry->cert[index], SEC_PROT_CERT_PEM_HEADER_STR) != NULL) {
|
||||
cert_length -= SEC_PROT_CERT_PEM_HEADER_FOOTER_LEN;
|
||||
/* 4 base64 chars encode 3 bytes (ignores line endings and possible paddings in the
|
||||
calculation i.e they are counted to length) */
|
||||
chain_length += (cert_length / 4) * 3;
|
||||
} else {
|
||||
chain_length += cert_length;
|
||||
}
|
||||
}
|
||||
}
|
||||
return chain_length;
|
||||
}
|
||||
|
||||
int8_t sec_prot_certs_priv_key_set(cert_chain_entry_t *entry, uint8_t *key, uint8_t key_len)
|
||||
{
|
||||
if (!entry) {
|
||||
|
|
|
@ -58,6 +58,8 @@ typedef struct {
|
|||
cert_chain_entry_t own_cert_chain; /**< Own certificate chain */
|
||||
cert_chain_list_t trusted_cert_chain_list; /**< Trusted certificate chain lists */
|
||||
cert_revocat_lists_t cert_revocat_lists; /**< Certificate Revocation Lists */
|
||||
uint16_t own_cert_chain_len; /**< Own certificate chain certificates length */
|
||||
bool ext_cert_valid_enabled : 1; /**< Extended certificate validation enabled */
|
||||
} sec_prot_certs_t;
|
||||
|
||||
/**
|
||||
|
@ -78,6 +80,37 @@ int8_t sec_prot_certs_init(sec_prot_certs_t *certs);
|
|||
*/
|
||||
void sec_prot_certs_delete(sec_prot_certs_t *certs);
|
||||
|
||||
/**
|
||||
* sec_prot_certs_ext_certificate_validation_set enable or disable extended certificate validation
|
||||
*
|
||||
* \param certs certificate information
|
||||
* \param enabled true to enable extended validation, false to disable
|
||||
*
|
||||
* \return < 0 failure
|
||||
* \return >= 0 success
|
||||
*
|
||||
*/
|
||||
int8_t sec_prot_certs_ext_certificate_validation_set(sec_prot_certs_t *certs, bool enabled);
|
||||
|
||||
/**
|
||||
* sec_prot_certs_ext_certificate_validation_get get extended certificate validation setting
|
||||
*
|
||||
* \param certs certificate information
|
||||
*
|
||||
* \return true/false enabled or not
|
||||
*
|
||||
*/
|
||||
bool sec_prot_certs_ext_certificate_validation_get(const sec_prot_certs_t *certs);
|
||||
|
||||
/**
|
||||
* sec_prot_certs_own_cert_chain_len_get get length of own certificate chain
|
||||
*
|
||||
* \param certs certificate information
|
||||
*
|
||||
* \return length of all the certificates in the own certificate chain
|
||||
*/
|
||||
uint16_t sec_prot_certs_own_cert_chain_len_get(const sec_prot_certs_t *certs);
|
||||
|
||||
/**
|
||||
* sec_prot_certs_chain_entry_create allocate memory for certificate chain entry
|
||||
*
|
||||
|
@ -123,6 +156,15 @@ int8_t sec_prot_certs_cert_set(cert_chain_entry_t *entry, uint8_t index, uint8_t
|
|||
*/
|
||||
uint8_t *sec_prot_certs_cert_get(const cert_chain_entry_t *entry, uint8_t index, uint16_t *cert_len);
|
||||
|
||||
/**
|
||||
* sec_prot_certs_cert_chain_entry_len_get get length of certificate chain on cert chain entry
|
||||
*
|
||||
* \param entry certificate chain entry
|
||||
*
|
||||
* \return total length of all the certificates in the entry
|
||||
*/
|
||||
uint16_t sec_prot_certs_cert_chain_entry_len_get(const cert_chain_entry_t *entry);
|
||||
|
||||
/**
|
||||
* sec_prot_certs_priv_key_set set certificate (chain) private key
|
||||
*
|
||||
|
|
|
@ -48,7 +48,7 @@ void sec_prot_init(sec_prot_common_t *data)
|
|||
{
|
||||
data->state = SEC_STATE_INIT;
|
||||
data->result = SEC_RESULT_OK;
|
||||
data->ticks = SEC_TOTAL_TIMEOUT;
|
||||
data->ticks = SEC_INIT_TIMEOUT;
|
||||
data->trickle_running = false;
|
||||
}
|
||||
|
||||
|
@ -73,10 +73,14 @@ void sec_prot_timer_timeout_handle(sec_prot_t *prot, sec_prot_common_t *data, co
|
|||
if (data->ticks > ticks) {
|
||||
data->ticks -= ticks;
|
||||
} else {
|
||||
tr_debug("prot timeout");
|
||||
tr_debug("prot timeout, state: %i", data->state);
|
||||
data->ticks = 0;
|
||||
sec_prot_result_set(data, SEC_RESULT_TIMEOUT);
|
||||
sec_prot_state_set(prot, data, SEC_STATE_FINISH);
|
||||
if (data->state == SEC_STATE_INIT) {
|
||||
sec_prot_state_set(prot, data, SEC_STATE_FINISHED);
|
||||
} else {
|
||||
sec_prot_state_set(prot, data, SEC_STATE_FINISH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,6 +171,11 @@ bool sec_prot_result_ok_check(sec_prot_common_t *data)
|
|||
return false;
|
||||
}
|
||||
|
||||
void sec_prot_default_timeout_set(sec_prot_common_t *data)
|
||||
{
|
||||
data->ticks = SEC_TOTAL_TIMEOUT;
|
||||
}
|
||||
|
||||
void sec_prot_lib_nonce_generate(uint8_t *nonce)
|
||||
{
|
||||
// Use randlib
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#define FWH_NONCE_LENGTH 32
|
||||
#define EUI64_LEN 8
|
||||
#define SEC_TOTAL_TIMEOUT 30 * 60 * 10 // 30 minutes
|
||||
#define SEC_INIT_TIMEOUT 60 * 10 // 60 seconds
|
||||
#define SEC_FINISHED_TIMEOUT 5 * 10 // 5 seconds
|
||||
|
||||
|
||||
|
@ -295,4 +296,12 @@ bool sec_prot_result_timeout_check(sec_prot_common_t *data);
|
|||
*/
|
||||
bool sec_prot_result_ok_check(sec_prot_common_t *data);
|
||||
|
||||
/**
|
||||
* sec_prot_default_timeout_set sets default timeout for protocol
|
||||
*
|
||||
* \param data common data
|
||||
*
|
||||
*/
|
||||
void sec_prot_default_timeout_set(sec_prot_common_t *data);
|
||||
|
||||
#endif /* SEC_PROT_LIB_H_ */
|
||||
|
|
|
@ -104,6 +104,8 @@ static bool tls_sec_prot_queue_check(sec_prot_t *prot);
|
|||
static bool tls_sec_prot_queue_process(sec_prot_t *prot);
|
||||
static void tls_sec_prot_queue_remove(sec_prot_t *prot);
|
||||
|
||||
static uint16_t tls_sec_prot_send_buffer_size_get(sec_prot_t *prot);
|
||||
|
||||
#define tls_sec_prot_get(prot) (tls_sec_prot_int_t *) &prot->data
|
||||
|
||||
static NS_LIST_DEFINE(tls_sec_prot_queue, tls_sec_prot_queue_t, link);
|
||||
|
@ -292,15 +294,17 @@ static void client_tls_sec_prot_state_machine(sec_prot_t *prot)
|
|||
|
||||
switch (sec_prot_state_get(&data->common)) {
|
||||
case TLS_STATE_INIT:
|
||||
tr_debug("TLS: init");
|
||||
sec_prot_state_set(prot, &data->common, TLS_STATE_CREATE_REQ);
|
||||
prot->timer_start(prot);
|
||||
// Set default timeout for the total maximum length of the negotiation
|
||||
sec_prot_default_timeout_set(&data->common);
|
||||
break;
|
||||
|
||||
// Wait KMP-CREATE.request
|
||||
case TLS_STATE_CREATE_REQ:
|
||||
tr_debug("TLS: start");
|
||||
|
||||
prot->timer_start(prot);
|
||||
|
||||
prot->create_conf(prot, SEC_RESULT_OK);
|
||||
|
||||
sec_prot_state_set(prot, &data->common, TLS_STATE_CONFIGURE);
|
||||
|
@ -383,15 +387,17 @@ static void server_tls_sec_prot_state_machine(sec_prot_t *prot)
|
|||
|
||||
switch (sec_prot_state_get(&data->common)) {
|
||||
case TLS_STATE_INIT:
|
||||
tr_debug("TLS: init");
|
||||
sec_prot_state_set(prot, &data->common, TLS_STATE_CLIENT_HELLO);
|
||||
prot->timer_start(prot);
|
||||
// Set default timeout for the total maximum length of the negotiation
|
||||
sec_prot_default_timeout_set(&data->common);
|
||||
break;
|
||||
|
||||
// Wait EAP request, Identity (starts handshake on supplicant)
|
||||
case TLS_STATE_CLIENT_HELLO:
|
||||
|
||||
tr_debug("TLS: start, eui-64: %s", trace_array(sec_prot_remote_eui_64_addr_get(prot), 8));
|
||||
|
||||
prot->timer_start(prot);
|
||||
client_hello = true;
|
||||
|
||||
sec_prot_state_set(prot, &data->common, TLS_STATE_CREATE_RESP);
|
||||
|
@ -494,12 +500,23 @@ static int16_t tls_sec_prot_tls_send(void *handle, const void *buf, size_t len)
|
|||
tls_sec_prot_int_t *data = tls_sec_prot_get(prot);
|
||||
|
||||
if (!data->tls_send.data) {
|
||||
eap_tls_sec_prot_lib_message_allocate(&data->tls_send, prot->header_size, TLS_SEC_PROT_BUFFER_SIZE);
|
||||
uint16_t buffer_len = tls_sec_prot_send_buffer_size_get(prot);
|
||||
eap_tls_sec_prot_lib_message_allocate(&data->tls_send, prot->header_size, buffer_len);
|
||||
}
|
||||
if (!data->tls_send.data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If send buffer is too small for the TLS payload, re-allocates */
|
||||
uint16_t new_len = prot->header_size + data->tls_send.handled_len + len;
|
||||
if (new_len > data->tls_send.total_len) {
|
||||
tr_error("TLS send buffer size too small: %i < %i, allocating new: %i", data->tls_send.total_len, new_len, data->tls_send.total_len + TLS_SEC_PROT_SEND_BUFFER_SIZE_INCREMENT);
|
||||
if (eap_tls_sec_prot_lib_message_realloc(&data->tls_send, prot->header_size,
|
||||
data->tls_send.total_len + TLS_SEC_PROT_SEND_BUFFER_SIZE_INCREMENT) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(data->tls_send.data + prot->header_size + data->tls_send.handled_len, buf, len);
|
||||
data->tls_send.handled_len += len;
|
||||
|
||||
|
@ -685,4 +702,9 @@ static void tls_sec_prot_queue_remove(sec_prot_t *prot)
|
|||
}
|
||||
}
|
||||
|
||||
static uint16_t tls_sec_prot_send_buffer_size_get(sec_prot_t *prot)
|
||||
{
|
||||
return TLS_SEC_PROT_SEND_BUFFER_SIZE + sec_prot_certs_own_cert_chain_len_get(prot->sec_keys->certs);
|
||||
}
|
||||
|
||||
#endif /* HAVE_WS */
|
||||
|
|
|
@ -23,7 +23,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define TLS_SEC_PROT_BUFFER_SIZE 1200 // Send buffer size (maximum size for a TLS data for a flight)
|
||||
/* TLS send buffer size not including certificates. This should include e.g. on
|
||||
* server: server hello, server key exchange, certificate request and server
|
||||
* hello done. */
|
||||
#define TLS_SEC_PROT_SEND_BUFFER_SIZE 500
|
||||
|
||||
/* TLS send buffer size increment if it is detected that buffer is too small */
|
||||
#define TLS_SEC_PROT_SEND_BUFFER_SIZE_INCREMENT 1000
|
||||
|
||||
/**
|
||||
* client_tls_sec_prot_register register client TLS protocol to KMP service
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/ssl_ciphersuites.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/oid.h"
|
||||
|
||||
#include "mbedtls/ssl_internal.h"
|
||||
|
||||
|
@ -57,7 +58,9 @@
|
|||
#define TLS_HANDSHAKE_TIMEOUT_MIN 25000
|
||||
#define TLS_HANDSHAKE_TIMEOUT_MAX 201000
|
||||
|
||||
//#define TLS_SEC_PROT_LIB_TLS_DEBUG // Enable mbed TLS debug traces
|
||||
//#define TLS_SEC_PROT_LIB_TLS_DEBUG // Enable mbed TLS debug traces
|
||||
|
||||
typedef int tls_sec_prot_lib_crt_verify_cb(tls_security_t *sec, mbedtls_x509_crt *crt, uint32_t *flags);
|
||||
|
||||
struct tls_security_s {
|
||||
mbedtls_ssl_config conf; /**< mbed TLS SSL configuration */
|
||||
|
@ -71,6 +74,8 @@ struct tls_security_s {
|
|||
mbedtls_x509_crt owncert; /**< Own certificate(s) */
|
||||
mbedtls_pk_context pkey; /**< Private key for own certificate */
|
||||
void *handle; /**< Handle provided in callbacks (defined by library user) */
|
||||
bool ext_cert_valid : 1; /**< Extended certificate validation enabled */
|
||||
tls_sec_prot_lib_crt_verify_cb *crt_verify; /**< Verify function for client/server certificate */
|
||||
tls_sec_prot_lib_send *send; /**< Send callback */
|
||||
tls_sec_prot_lib_receive *receive; /**< Receive callback */
|
||||
tls_sec_prot_lib_export_keys *export_keys; /**< Export keys callback */
|
||||
|
@ -85,23 +90,42 @@ static int tls_sec_prot_lib_ssl_send(void *ctx, const unsigned char *buf, size_t
|
|||
static int tls_sec_prot_lib_ssl_recv(void *ctx, unsigned char *buf, size_t len);
|
||||
static int tls_sec_prot_lib_ssl_export_keys(void *p_expkey, const unsigned char *ms,
|
||||
const unsigned char *kb, size_t maclen, size_t keylen,
|
||||
size_t ivlen, unsigned char client_random[32],
|
||||
unsigned char server_random[32],
|
||||
size_t ivlen, const unsigned char client_random[32],
|
||||
const unsigned char server_random[32],
|
||||
mbedtls_tls_prf_types tls_prf_type);
|
||||
|
||||
static int tls_sec_prot_lib_x509_crt_verify(void *ctx, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags);
|
||||
static int8_t tls_sec_prot_lib_subject_alternative_name_validate(mbedtls_x509_crt *crt);
|
||||
static int8_t tls_sec_prot_lib_extended_key_usage_validate(mbedtls_x509_crt *crt);
|
||||
#ifdef HAVE_PAE_AUTH
|
||||
static int tls_sec_prot_lib_x509_crt_idevid_ldevid_verify(tls_security_t *sec, mbedtls_x509_crt *crt, uint32_t *flags);
|
||||
#endif
|
||||
#ifdef HAVE_PAE_SUPP
|
||||
static int tls_sec_prot_lib_x509_crt_server_verify(tls_security_t *sec, mbedtls_x509_crt *crt, uint32_t *flags);
|
||||
#endif
|
||||
#ifdef TLS_SEC_PROT_LIB_TLS_DEBUG
|
||||
static void tls_sec_prot_lib_debug(void *ctx, int level, const char *file, int line, const char *string);
|
||||
#endif
|
||||
|
||||
#ifdef MBEDTLS_PLATFORM_MEMORY
|
||||
// Disable for now
|
||||
//#define TLS_SEC_PROT_LIB_USE_MBEDTLS_PLATFORM_MEMORY
|
||||
#endif
|
||||
|
||||
#ifdef TLS_SEC_PROT_LIB_USE_MBEDTLS_PLATFORM_MEMORY
|
||||
static void *tls_sec_prot_lib_mem_calloc(size_t count, size_t size);
|
||||
static void tls_sec_prot_lib_mem_free(void *ptr);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PAE_AUTH) && defined(HAVE_PAE_SUPP)
|
||||
#define is_server_is_set (is_server == true)
|
||||
#define is_server_is_not_set (is_server == false)
|
||||
#elif defined(HAVE_PAE_AUTH)
|
||||
#define is_server_is_set true
|
||||
#define is_server_is_not_set false
|
||||
#elif defined(HAVE_PAE_SUPP)
|
||||
#define is_server_is_set false
|
||||
#define is_server_is_not_set true
|
||||
#endif
|
||||
|
||||
int8_t tls_sec_prot_lib_init(tls_security_t *sec)
|
||||
{
|
||||
const char *pers = "ws_tls";
|
||||
|
@ -110,7 +134,6 @@ int8_t tls_sec_prot_lib_init(tls_security_t *sec)
|
|||
mbedtls_platform_set_calloc_free(tls_sec_prot_lib_mem_calloc, tls_sec_prot_lib_mem_free);
|
||||
#endif
|
||||
|
||||
|
||||
mbedtls_ssl_init(&sec->ssl);
|
||||
mbedtls_ssl_config_init(&sec->conf);
|
||||
mbedtls_ctr_drbg_init(&sec->ctr_drbg);
|
||||
|
@ -269,21 +292,37 @@ static int tls_sec_prot_lib_configure_certificates(tls_security_t *sec, const se
|
|||
// Certificate verify required on both client and server
|
||||
mbedtls_ssl_conf_authmode(&sec->conf, MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
|
||||
// Get extended certificate validation setting
|
||||
sec->ext_cert_valid = sec_prot_certs_ext_certificate_validation_get(certs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t tls_sec_prot_lib_connect(tls_security_t *sec, bool is_server, const sec_prot_certs_t *certs)
|
||||
{
|
||||
#if !defined(HAVE_PAE_SUPP) || !defined(HAVE_PAE_AUTH)
|
||||
(void) is_server;
|
||||
#endif
|
||||
|
||||
if (!sec) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int endpoint = MBEDTLS_SSL_IS_CLIENT;
|
||||
if (is_server) {
|
||||
endpoint = MBEDTLS_SSL_IS_SERVER;
|
||||
#ifdef HAVE_PAE_SUPP
|
||||
if (is_server_is_not_set) {
|
||||
sec->crt_verify = tls_sec_prot_lib_x509_crt_server_verify;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_PAE_AUTH
|
||||
if (is_server_is_set) {
|
||||
sec->crt_verify = tls_sec_prot_lib_x509_crt_idevid_ldevid_verify;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((mbedtls_ssl_config_defaults(&sec->conf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, 0)) != 0) {
|
||||
|
||||
if ((mbedtls_ssl_config_defaults(&sec->conf,
|
||||
is_server_is_set ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT,
|
||||
MBEDTLS_SSL_TRANSPORT_STREAM, 0)) != 0) {
|
||||
tr_error("config defaults fail");
|
||||
return -1;
|
||||
}
|
||||
|
@ -331,8 +370,11 @@ int8_t tls_sec_prot_lib_connect(tls_security_t *sec, bool is_server, const sec_p
|
|||
mbedtls_ssl_conf_min_version(&sec->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3);
|
||||
mbedtls_ssl_conf_max_version(&sec->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3);
|
||||
|
||||
// Set certificate verify callback
|
||||
mbedtls_ssl_set_verify(&sec->ssl, tls_sec_prot_lib_x509_crt_verify, sec);
|
||||
|
||||
#ifdef MBEDTLS_ECP_RESTARTABLE
|
||||
if (endpoint == MBEDTLS_SSL_IS_SERVER) {
|
||||
if (is_server_is_set) {
|
||||
// Temporary to enable non blocking ECC */
|
||||
sec->ssl.handshake->ecrs_enabled = 1;
|
||||
}
|
||||
|
@ -405,8 +447,8 @@ static int tls_sec_prot_lib_ssl_recv(void *ctx, unsigned char *buf, size_t len)
|
|||
|
||||
static int tls_sec_prot_lib_ssl_export_keys(void *p_expkey, const unsigned char *ms,
|
||||
const unsigned char *kb, size_t maclen, size_t keylen,
|
||||
size_t ivlen, unsigned char client_random[32],
|
||||
unsigned char server_random[32],
|
||||
size_t ivlen, const unsigned char client_random[32],
|
||||
const unsigned char server_random[32],
|
||||
mbedtls_tls_prf_types tls_prf_type)
|
||||
{
|
||||
(void) kb;
|
||||
|
@ -433,6 +475,109 @@ static int tls_sec_prot_lib_ssl_export_keys(void *p_expkey, const unsigned char
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tls_sec_prot_lib_x509_crt_verify(void *ctx, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags)
|
||||
{
|
||||
tls_security_t *sec = (tls_security_t *) ctx;
|
||||
|
||||
/* MD/PK forced by configuration flags and dynamic settings but traced also here
|
||||
to prevent invalid configurations/certificates */
|
||||
if (crt->sig_md != MBEDTLS_MD_SHA256) {
|
||||
tr_error("Invalid signature md algorithm");
|
||||
}
|
||||
if (crt->sig_pk != MBEDTLS_PK_ECDSA) {
|
||||
tr_error("Invalid signature pk algorithm");
|
||||
}
|
||||
|
||||
// Verify client/server certificate of the chain
|
||||
if (certificate_depth == 0) {
|
||||
return sec->crt_verify(sec, crt, flags);
|
||||
}
|
||||
|
||||
// No further checks for intermediate and root certificates at the moment
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int8_t tls_sec_prot_lib_subject_alternative_name_validate(mbedtls_x509_crt *crt)
|
||||
{
|
||||
mbedtls_asn1_sequence *seq = &crt->subject_alt_names;
|
||||
int8_t result = -1;
|
||||
while (seq) {
|
||||
mbedtls_x509_subject_alternative_name san;
|
||||
int ret_value = mbedtls_x509_parse_subject_alt_name((mbedtls_x509_buf *)&seq->buf, &san);
|
||||
if (ret_value == 0 && san.type == MBEDTLS_X509_SAN_OTHER_NAME) {
|
||||
// id-on-hardwareModuleName must be present (1.3.6.1.5.5.7.8.4)
|
||||
if (MBEDTLS_OID_CMP(MBEDTLS_OID_ON_HW_MODULE_NAME, &san.san.other_name.value.hardware_module_name.oid)) {
|
||||
// Traces hardwareModuleName (1.3.6.1.4.1.<enteprise number>.<model,version,etc.>)
|
||||
char buffer[30];
|
||||
ret_value = mbedtls_oid_get_numeric_string(buffer, sizeof(buffer), &san.san.other_name.value.hardware_module_name.oid);
|
||||
if (ret_value != MBEDTLS_ERR_OID_BUF_TOO_SMALL) {
|
||||
tr_info("id-on-hardwareModuleName %s", buffer);
|
||||
}
|
||||
// Traces serial number as hex string
|
||||
mbedtls_x509_buf *val = &san.san.other_name.value.hardware_module_name.val;
|
||||
if (val->p) {
|
||||
tr_info("id-on-hardwareModuleName hwSerialNum %s", trace_array(val->p, val->len));
|
||||
}
|
||||
result = 0;
|
||||
}
|
||||
} else {
|
||||
tr_debug("Ignored subject alt name: %i", san.type);
|
||||
}
|
||||
seq = seq->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int8_t tls_sec_prot_lib_extended_key_usage_validate(mbedtls_x509_crt *crt)
|
||||
{
|
||||
#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE)
|
||||
// Extended key usage must be present
|
||||
if (mbedtls_x509_crt_check_extended_key_usage(crt, MBEDTLS_OID_WISUN_FAN, sizeof(MBEDTLS_OID_WISUN_FAN) - 1) != 0) {
|
||||
tr_error("invalid extended key usage");
|
||||
return -1; // FAIL
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PAE_AUTH
|
||||
static int tls_sec_prot_lib_x509_crt_idevid_ldevid_verify(tls_security_t *sec, mbedtls_x509_crt *crt, uint32_t *flags)
|
||||
{
|
||||
// For both IDevID and LDevId both subject alternative name or extended key usage must be valid
|
||||
if (tls_sec_prot_lib_subject_alternative_name_validate(crt) < 0 ||
|
||||
tls_sec_prot_lib_extended_key_usage_validate(crt) < 0) {
|
||||
tr_error("invalid cert");
|
||||
if (sec->ext_cert_valid) {
|
||||
*flags |= MBEDTLS_X509_BADCERT_OTHER;
|
||||
return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PAE_SUPP
|
||||
static int tls_sec_prot_lib_x509_crt_server_verify(tls_security_t *sec, mbedtls_x509_crt *crt, uint32_t *flags)
|
||||
{
|
||||
int8_t sane_res = tls_sec_prot_lib_subject_alternative_name_validate(crt);
|
||||
int8_t ext_key_res = tls_sec_prot_lib_extended_key_usage_validate(crt);
|
||||
|
||||
// If either subject alternative name or extended key usage is present
|
||||
if (sane_res >= 0 || ext_key_res >= 0) {
|
||||
// Then both subject alternative name and extended key usage must be valid
|
||||
if (sane_res < 0 || ext_key_res < 0) {
|
||||
tr_error("invalid cert");
|
||||
if (sec->ext_cert_valid) {
|
||||
*flags |= MBEDTLS_X509_BADCERT_OTHER;
|
||||
return MBEDTLS_ERR_X509_CERT_VERIFY_FAILED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int tls_sec_lib_entropy_poll(void *ctx, unsigned char *output, size_t len, size_t *olen)
|
||||
{
|
||||
(void)ctx;
|
||||
|
@ -518,4 +663,3 @@ uint16_t tls_sec_prot_lib_size(void)
|
|||
}
|
||||
#endif /* WS_MBEDTLS_SECURITY_ENABLED */
|
||||
#endif /* HAVE_WS */
|
||||
|
||||
|
|
|
@ -679,6 +679,7 @@ void dhcp_service_delete(uint16_t instance)
|
|||
|
||||
int dhcp_service_send_resp(uint32_t msg_tr_id, uint8_t options, uint8_t *msg_ptr, uint16_t msg_len)
|
||||
{
|
||||
tr_debug("Send DHCPv6 response");
|
||||
msg_tr_t *msg_tr_ptr;
|
||||
server_instance_t *srv_instance;
|
||||
msg_tr_ptr = dhcp_tr_find(msg_tr_id);
|
||||
|
@ -706,6 +707,7 @@ int dhcp_service_send_resp(uint32_t msg_tr_id, uint8_t options, uint8_t *msg_ptr
|
|||
}
|
||||
uint32_t dhcp_service_send_req(uint16_t instance_id, uint8_t options, void *ptr, const uint8_t addr[static 16], uint8_t *msg_ptr, uint16_t msg_len, dhcp_service_receive_resp_cb *receive_resp_cb)
|
||||
{
|
||||
tr_debug("Send DHCPv6 request");
|
||||
msg_tr_t *msg_tr_ptr;
|
||||
server_instance_t *srv_ptr;
|
||||
srv_ptr = dhcp_service_client_find(instance_id);
|
||||
|
@ -767,6 +769,17 @@ void dhcp_service_req_remove(uint32_t msg_tr_id)
|
|||
return;
|
||||
}
|
||||
|
||||
void dhcp_service_req_remove_all(void *msg_class_ptr)
|
||||
{
|
||||
if (dhcp_service) {
|
||||
ns_list_foreach_safe(msg_tr_t, cur_ptr, &dhcp_service->tr_list) {
|
||||
if (cur_ptr->client_obj_ptr == msg_class_ptr) {
|
||||
dhcp_tr_delete(cur_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dhcp_service_send_message(msg_tr_t *msg_tr_ptr)
|
||||
{
|
||||
int8_t retval;
|
||||
|
@ -930,4 +943,9 @@ bool dhcp_service_timer_tick(uint16_t ticks)
|
|||
return false;
|
||||
}
|
||||
|
||||
void dhcp_service_req_remove_all(void *msg_class_ptr)
|
||||
{
|
||||
(void)msg_class_ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -217,6 +217,17 @@ dhcpv6_client_server_data_t *libdhcpv6_nonTemporal_entry_get_by_prefix(int8_t in
|
|||
return NULL;
|
||||
}
|
||||
|
||||
dhcpv6_client_server_data_t *libdhcpv6_nonTemporal_validate_class_pointer(void *class_ptr)
|
||||
{
|
||||
ns_list_foreach(dhcpv6_client_server_data_t, cur, &dhcpv6_client_nonTemporal_list) {
|
||||
if (cur == class_ptr) {
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
uint16_t libdhcpv6_duid_option_size(uint16_t linkType)
|
||||
{
|
||||
uint16_t length = 8; // Type & Length header part *2
|
||||
|
|
|
@ -235,6 +235,7 @@ dhcpv6_client_server_data_t *libdhcpv6_nonTemporal_entry_get_by_iaid(uint32_t ia
|
|||
dhcpv6_client_server_data_t *libdhcpv6_nonTemporal_entry_get_by_transactionId(uint32_t txId);
|
||||
dhcpv6_client_server_data_t *libdhcpv6_nonTemporal_entry_get_by_prefix(int8_t interfaceId, uint8_t *prefix);
|
||||
dhcpv6_client_server_data_t *libdhcpv6_nonTemporal_entry_get_by_instance(uint8_t instanceId);
|
||||
dhcpv6_client_server_data_t *libdhcpv6_nonTemporal_validate_class_pointer(void *class_ptr);
|
||||
uint8_t libdhcpv6_nonTemporal_entry_get_unique_instance_id(void);
|
||||
|
||||
|
||||
|
|
|
@ -988,18 +988,30 @@ int8_t arm_network_trusted_certificate_remove(const arm_certificate_entry_s *cer
|
|||
|
||||
int8_t arm_network_trusted_certificates_remove(void)
|
||||
{
|
||||
#ifdef HAVE_WS
|
||||
return ws_pae_controller_trusted_certificates_remove();
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int8_t arm_network_own_certificate_add(const arm_certificate_entry_s *cert)
|
||||
{
|
||||
#ifdef HAVE_WS
|
||||
return ws_pae_controller_own_certificate_add(cert);
|
||||
#else
|
||||
(void) cert;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern int8_t arm_network_own_certificates_remove(void)
|
||||
{
|
||||
#ifdef HAVE_WS
|
||||
return ws_pae_controller_own_certificates_remove();
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
int8_t arm_network_certificate_revocation_list_add(const arm_cert_revocation_list_entry_s *crl)
|
||||
|
|
Loading…
Reference in New Issue