mirror of https://github.com/ARMmbed/mbed-os.git
Merge commit '3e6cb31659a56d343c7b8fe37645f195eb87ffcf'
* commit '3e6cb31659a56d343c7b8fe37645f195eb87ffcf': Squashed 'features/nanostack/sal-stack-nanostack/' changes from c473148..0824752pull/11639/head
commit
c15478021b
|
@ -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 */
|
||||
|
@ -88,20 +93,39 @@ static int tls_sec_prot_lib_ssl_export_keys(void *p_expkey, const unsigned char
|
|||
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;
|
||||
}
|
||||
|
@ -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