Skip to content

Commit c110c19

Browse files
author
Mika Leppänen
committed
Added tx failure cause to initial EAPOL-key security protocol
TX failure cause "no acknowledge" is now sent from the mpx interface, via the eapol pdu, kpm and security protocols to pae supplicant, which sends the failure reason to bootstrap. Re-structured eapol-key protocol to be similar to other security protocols. Added own state machines to authenticator and supplicant. Supplicant now runs timer to wait for mpx tx response.
1 parent 678e0fd commit c110c19

17 files changed

+475
-103
lines changed

source/6LoWPAN/ws/ws_bootstrap.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static void ws_bootstrap_nw_key_clear(protocol_interface_info_entry_t *cur, uint
9292
static void ws_bootstrap_nw_key_index_set(protocol_interface_info_entry_t *cur, uint8_t index);
9393
static void ws_bootstrap_nw_frame_counter_set(protocol_interface_info_entry_t *cur, uint32_t counter);
9494
static void ws_bootstrap_nw_frame_counter_read(protocol_interface_info_entry_t *cur, uint32_t *counter);
95-
static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_t *cur, bool success);
95+
static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_t *cur, auth_result_e result);
9696
static void ws_bootstrap_pan_version_increment(protocol_interface_info_entry_t *cur);
9797
static ws_nud_table_entry_t *ws_nud_entry_discover(protocol_interface_info_entry_t *cur, void *neighbor);
9898
static void ws_nud_entry_remove(protocol_interface_info_entry_t *cur, mac_neighbor_table_entry_t *entry_ptr);
@@ -2196,9 +2196,9 @@ static void ws_bootstrap_nw_frame_counter_read(protocol_interface_info_entry_t *
21962196
mac_helper_link_frame_counter_read(cur->id, counter);
21972197
}
21982198

2199-
static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_t *cur, bool success)
2199+
static void ws_bootstrap_authentication_completed(protocol_interface_info_entry_t *cur, auth_result_e result)
22002200
{
2201-
if (success) {
2201+
if (result == AUTH_RESULT_OK) {
22022202
tr_debug("authentication success");
22032203
ws_bootstrap_event_configuration_start(cur);
22042204
} else {

source/6LoWPAN/ws/ws_eapol_pdu.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@
3737
#define TRACE_GROUP "wsep"
3838

3939
typedef struct {
40-
uint8_t handle;
4140
void *data_ptr;
4241
void *buffer;
42+
ws_eapol_pdu_tx_status *tx_status;
43+
uint8_t tx_identifier;
44+
uint8_t handle;
4345
ns_list_link_t link;
4446
} eapol_pdu_msdu_t;
4547

@@ -180,7 +182,7 @@ int8_t ws_eapol_pdu_cb_unregister(protocol_interface_info_entry_t *interface_ptr
180182
return -1;
181183
}
182184

183-
int8_t ws_eapol_pdu_send_to_mpx(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64, void *data, uint16_t size, void *buffer)
185+
int8_t ws_eapol_pdu_send_to_mpx(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64, void *data, uint16_t size, void *buffer, ws_eapol_pdu_tx_status *tx_status, uint8_t tx_identifier)
184186
{
185187
eapol_pdu_data_t *eapol_pdu_data = ws_eapol_pdu_data_get(interface_ptr);
186188

@@ -198,6 +200,8 @@ int8_t ws_eapol_pdu_send_to_mpx(protocol_interface_info_entry_t *interface_ptr,
198200
msdu_entry->data_ptr = data;
199201
msdu_entry->buffer = buffer;
200202
msdu_entry->handle = eapol_pdu_data->msdu_handle;
203+
msdu_entry->tx_status = tx_status;
204+
msdu_entry->tx_identifier = tx_identifier;
201205
ns_list_add_to_start(&eapol_pdu_data->msdu_list, msdu_entry);
202206

203207
memcpy(data_request.DstAddr, eui_64, 8);
@@ -265,6 +269,15 @@ static void ws_eapol_pdu_mpx_data_confirm(const mpx_api_t *api, const struct mcp
265269

266270
ns_list_foreach(eapol_pdu_msdu_t, msdu, &eapol_pdu_data->msdu_list) {
267271
if (msdu->handle == data->msduHandle) {
272+
if (msdu->tx_status) {
273+
eapol_pdu_tx_status_e status = EAPOL_PDU_TX_ERR_UNSPEC;
274+
if (data->status == MLME_SUCCESS) {
275+
status = EAPOL_PDU_TX_OK;
276+
} else if (data->status == MLME_TX_NO_ACK) {
277+
status = EAPOL_PDU_TX_ERR_TX_NO_ACK;
278+
}
279+
msdu->tx_status(eapol_pdu_data->interface_ptr, status, msdu->tx_identifier);
280+
}
268281
ns_dyn_mem_free(msdu->buffer);
269282
ns_list_remove(&eapol_pdu_data->msdu_list, msdu);
270283
ns_dyn_mem_free(msdu);

source/6LoWPAN/ws/ws_eapol_pdu.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,22 @@ int8_t ws_eapol_pdu_cb_register(protocol_interface_info_entry_t *interface_ptr,
127127
*/
128128
int8_t ws_eapol_pdu_cb_unregister(protocol_interface_info_entry_t *interface_ptr, const eapol_pdu_recv_cb_data_t *cb_data);
129129

130+
typedef enum {
131+
EAPOL_PDU_TX_OK = 0, // Successful
132+
EAPOL_PDU_TX_ERR_TX_NO_ACK = -1, // No acknowledge was received
133+
EAPOL_PDU_TX_ERR_UNSPEC = -2, // Other reason
134+
} eapol_pdu_tx_status_e;
135+
136+
/**
137+
* ws_eapol_pdu_tx_status will be called when TX status is known
138+
*
139+
* \param interface_ptr interface
140+
* \param tx_status tx status
141+
* \param tx_identifier tx identifier
142+
*
143+
*/
144+
typedef int8_t ws_eapol_pdu_tx_status(protocol_interface_info_entry_t *interface_ptr, eapol_pdu_tx_status_e tx_status, uint8_t tx_identifier);
145+
130146
/**
131147
* ws_eapol_pdu_send_to_mpx send EAPOL PDU to MPX
132148
*
@@ -135,11 +151,13 @@ int8_t ws_eapol_pdu_cb_unregister(protocol_interface_info_entry_t *interface_ptr
135151
* \param data EAPOL PDU
136152
* \param size PDU size
137153
* \param buffer pointer to allocated buffer
154+
* \param tx_status tx status callback
155+
* \param tx_identifier tx identifier
138156
*
139157
* \return < 0 failure
140158
* \return >= 0 success
141159
*
142160
*/
143-
int8_t ws_eapol_pdu_send_to_mpx(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64, void *data, uint16_t size, void *buffer);
161+
int8_t ws_eapol_pdu_send_to_mpx(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64, void *data, uint16_t size, void *buffer, ws_eapol_pdu_tx_status tx_status, uint8_t tx_identifier);
144162

145163
#endif /* WS_EAPOL_PDU_H_ */

source/6LoWPAN/ws/ws_eapol_relay.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ static void ws_eapol_relay_socket_cb(void *cb)
183183
}
184184

185185
//First 8 byte is EUID64 and rsr payload
186-
if (ws_eapol_pdu_send_to_mpx(eapol_relay->interface_ptr, socket_pdu, socket_pdu + 8, cb_data->d_len - 8, socket_pdu) < 0) {
186+
if (ws_eapol_pdu_send_to_mpx(eapol_relay->interface_ptr, socket_pdu, socket_pdu + 8, cb_data->d_len - 8, socket_pdu, NULL, 0) < 0) {
187187
ns_dyn_mem_free(socket_pdu);
188188
}
189189
}

source/6LoWPAN/ws/ws_pae_auth.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot
159159
goto error;
160160
}
161161

162-
if (kmp_service_cb_register(pae_auth->kmp_service, ws_pae_auth_kmp_incoming_ind, ws_pae_auth_kmp_service_addr_get, ws_pae_auth_kmp_service_api_get)) {
162+
if (kmp_service_cb_register(pae_auth->kmp_service, ws_pae_auth_kmp_incoming_ind, NULL, ws_pae_auth_kmp_service_addr_get, ws_pae_auth_kmp_service_api_get)) {
163163
goto error;
164164
}
165165

@@ -171,7 +171,7 @@ int8_t ws_pae_auth_init(protocol_interface_info_entry_t *interface_ptr, sec_prot
171171
goto error;
172172
}
173173

174-
if (key_sec_prot_register(pae_auth->kmp_service) < 0) {
174+
if (auth_key_sec_prot_register(pae_auth->kmp_service) < 0) {
175175
goto error;
176176
}
177177

source/6LoWPAN/ws/ws_pae_controller.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,15 @@
2020

2121
#ifdef HAVE_WS
2222

23+
typedef enum {
24+
AUTH_RESULT_OK = 0, // Successful
25+
AUTH_RESULT_ERR_NO_MEM = -1, // No memory
26+
AUTH_RESULT_ERR_TX_NO_ACK = -2, // No acknowledge was received
27+
AUTH_RESULT_ERR_UNSPEC = -3 // Other reason
28+
} auth_result_e;
29+
2330
struct nvm_tlv_entry;
31+
2432
/**
2533
* ws_pae_controller_set_target sets EAPOL target for PAE supplicant
2634
*
@@ -484,10 +492,10 @@ typedef void ws_pae_controller_nw_frame_counter_read(protocol_interface_info_ent
484492
* ws_pae_controller_auth_completed authentication completed callback
485493
*
486494
* \param interface_ptr interface
487-
* \param success true if authentication was successful
495+
* \param result result, either ok or failure reason
488496
*
489497
*/
490-
typedef void ws_pae_controller_auth_completed(protocol_interface_info_entry_t *interface_ptr, bool success);
498+
typedef void ws_pae_controller_auth_completed(protocol_interface_info_entry_t *interface_ptr, auth_result_e result);
491499

492500
/**
493501
* ws_pae_controller_pan_ver_increment PAN version increment callback

source/6LoWPAN/ws/ws_pae_lib.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ kmp_api_t *ws_pae_lib_kmp_list_type_get(kmp_list_t *kmp_list, kmp_type_e type)
9393
return kmp;
9494
}
9595

96+
kmp_api_t *ws_pae_lib_kmp_list_instance_id_get(kmp_list_t *kmp_list, uint8_t instance_id)
97+
{
98+
ns_list_foreach(kmp_entry_t, cur, kmp_list) {
99+
if (kmp_api_instance_id_get(cur->kmp) == instance_id) {
100+
return cur->kmp;
101+
}
102+
}
103+
104+
return NULL;
105+
}
106+
96107
void ws_pae_lib_kmp_list_free(kmp_list_t *kmp_list)
97108
{
98109
ns_list_foreach_safe(kmp_entry_t, cur, kmp_list) {

source/6LoWPAN/ws/ws_pae_lib.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ int8_t ws_pae_lib_kmp_list_delete(kmp_list_t *kmp_list, kmp_api_t *kmp);
8888
void ws_pae_lib_kmp_list_free(kmp_list_t *kmp_list);
8989

9090
/**
91-
* ws_pae_lib_kmp_list_type_get gets KMP entry from KMP list based on KMP type
91+
* ws_pae_lib_kmp_list_type_get gets KMP from KMP list based on KMP type
9292
*
9393
* \param kmp_list KMP list
9494
* \param type type
@@ -99,6 +99,18 @@ void ws_pae_lib_kmp_list_free(kmp_list_t *kmp_list);
9999
*/
100100
kmp_api_t *ws_pae_lib_kmp_list_type_get(kmp_list_t *kmp_list, kmp_type_e type);
101101

102+
/**
103+
* ws_pae_lib_kmp_list_instance_id_get gets KMP from KMP list based on instance identifier
104+
*
105+
* \param kmp_list KMP list
106+
* \param instance_id instance identifier
107+
*
108+
* \return KMP on success
109+
* \return NULL on failure
110+
*
111+
*/
112+
kmp_api_t *ws_pae_lib_kmp_list_instance_id_get(kmp_list_t *kmp_list, uint8_t instance_id);
113+
102114
/**
103115
* ws_pae_lib_kmp_list_entry_get gets KMP entry from KMP list based on KMP
104116
*

source/6LoWPAN/ws/ws_pae_supp.c

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ typedef struct {
9999
timer_settings_t *timer_settings; /**< Timer settings */
100100
uint8_t nw_keys_used_cnt; /**< How many times bootstrap has been tried with current keys */
101101
bool auth_trickle_running : 1; /**< Initial EAPOL-Key Trickle timer running */
102-
bool auth_requested : 1; /**< Authentication has been requested */
102+
bool auth_requested : 1; /**< Authentication has been requested by the bootstrap */
103103
bool timer_running : 1; /**< Timer is running */
104104
bool new_br_eui_64_set : 1; /**< Border router address has been set */
105105
bool new_br_eui_64_fresh : 1; /**< Border router address is fresh (set during this authentication attempt) */
@@ -117,7 +117,7 @@ static trickle_params_t initial_eapol_key_trickle_params = {
117117
};
118118

119119
static void ws_pae_supp_free(pae_supp_t *pae_supp);
120-
static void ws_pae_supp_authenticate_response(pae_supp_t *pae_supp, bool success);
120+
static void ws_pae_supp_authenticate_response(pae_supp_t *pae_supp, auth_result_e result);
121121
static int8_t ws_pae_supp_initial_key_send(pae_supp_t *pae_supp);
122122
static void ws_pae_supp_nvm_update(pae_supp_t *pae_supp);
123123
static int8_t ws_pae_supp_nw_keys_valid_check(pae_supp_t *pae_supp, uint16_t pan_id);
@@ -134,6 +134,7 @@ static bool ws_pae_supp_timer_running(pae_supp_t *pae_supp);
134134
static void ws_pae_supp_kmp_service_addr_get(kmp_service_t *service, kmp_api_t *kmp, kmp_addr_t *local_addr, kmp_addr_t *remote_addr);
135135
static kmp_api_t *ws_pae_supp_kmp_service_api_get(kmp_service_t *service, kmp_api_t *kmp, kmp_type_e type);
136136
static kmp_api_t *ws_pae_supp_kmp_incoming_ind(kmp_service_t *service, kmp_type_e type, const kmp_addr_t *addr);
137+
static kmp_api_t *ws_pae_supp_kmp_tx_status_ind(kmp_service_t *service, uint8_t instance_id);
137138
static kmp_api_t *ws_pae_supp_kmp_create_and_start(kmp_service_t *service, kmp_type_e type, pae_supp_t *pae_supp);
138139
static int8_t ws_pae_supp_eapol_pdu_address_check(protocol_interface_info_entry_t *interface_ptr, const uint8_t *eui_64);
139140
static int8_t ws_pae_supp_parent_eui_64_get(protocol_interface_info_entry_t *interface_ptr, uint8_t *eui_64);
@@ -143,6 +144,7 @@ static void ws_pae_supp_kmp_api_create_indication(kmp_api_t *kmp, kmp_type_e typ
143144
static void ws_pae_supp_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e result, kmp_sec_keys_t *sec_keys);
144145
static void ws_pae_supp_kmp_api_finished(kmp_api_t *kmp);
145146

147+
146148
static const eapol_pdu_recv_cb_data_t eapol_pdu_recv_cb_data = {
147149
.priority = EAPOL_PDU_RECV_HIGH_PRIORITY,
148150
.addr_check = ws_pae_supp_eapol_pdu_address_check,
@@ -381,8 +383,6 @@ static void ws_pae_supp_nvm_update(pae_supp_t *pae_supp)
381383
ws_pae_supp_nvm_keys_write(pae_supp);
382384
sec_prot_keys_updated_reset(&pae_supp->entry.sec_keys);
383385
}
384-
385-
386386
}
387387

388388
static int8_t ws_pae_supp_nvm_nw_info_write(pae_supp_t *pae_supp)
@@ -457,12 +457,12 @@ static int8_t ws_pae_supp_nvm_keys_read(pae_supp_t *pae_supp)
457457
return 0;
458458
}
459459

460-
static void ws_pae_supp_authenticate_response(pae_supp_t *pae_supp, bool success)
460+
static void ws_pae_supp_authenticate_response(pae_supp_t *pae_supp, auth_result_e result)
461461
{
462462
pae_supp->auth_trickle_running = false;
463463
if (pae_supp->auth_requested && pae_supp->auth_completed) {
464464
pae_supp->auth_requested = false;
465-
pae_supp->auth_completed(pae_supp->interface_ptr, success);
465+
pae_supp->auth_completed(pae_supp->interface_ptr, result);
466466
}
467467
}
468468

@@ -605,7 +605,7 @@ int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const se
605605
goto error;
606606
}
607607

608-
if (kmp_service_cb_register(pae_supp->kmp_service, ws_pae_supp_kmp_incoming_ind, ws_pae_supp_kmp_service_addr_get, ws_pae_supp_kmp_service_api_get) < 0) {
608+
if (kmp_service_cb_register(pae_supp->kmp_service, ws_pae_supp_kmp_incoming_ind, ws_pae_supp_kmp_tx_status_ind, ws_pae_supp_kmp_service_addr_get, ws_pae_supp_kmp_service_api_get) < 0) {
609609
goto error;
610610
}
611611

@@ -625,7 +625,7 @@ int8_t ws_pae_supp_init(protocol_interface_info_entry_t *interface_ptr, const se
625625
goto error;
626626
}
627627

628-
if (key_sec_prot_register(pae_supp->kmp_service) < 0) {
628+
if (supp_key_sec_prot_register(pae_supp->kmp_service) < 0) {
629629
goto error;
630630
}
631631

@@ -1115,14 +1115,24 @@ static void ws_pae_supp_kmp_api_finished_indication(kmp_api_t *kmp, kmp_result_e
11151115
ws_pae_lib_supp_timer_ticks_set(&pae_supp->entry, WAIT_FOR_AUTHENTICATION_TICKS);
11161116
}
11171117

1118+
/* When 4WH or GKH completes inserts keys and indicates authentication completed
1119+
(if not alredy indicated) */
11181120
if ((type == IEEE_802_11_4WH || type == IEEE_802_11_GKH) && result == KMP_RESULT_OK) {
11191121
if (sec_keys) {
11201122
sec_prot_keys_t *keys = sec_keys;
11211123
pae_supp->nw_key_insert(pae_supp->interface_ptr, keys->gtks);
11221124
}
11231125

1124-
ws_pae_supp_authenticate_response(pae_supp, true);
1126+
ws_pae_supp_authenticate_response(pae_supp, result);
1127+
}
1128+
1129+
/* If initial EAPOL-key message sending fails to tx no acknowledge, indicates failure so
1130+
that bootstrap can decide if EAPOL target should be changed */
1131+
else if (type > IEEE_802_1X_INITIAL_KEY && result == KMP_RESULT_ERR_TX_NO_ACK) {
1132+
tr_info("Initial EAPOL-Key TX failure, target: %s", trace_array(kmp_address_eui_64_get(&pae_supp->entry.addr), 8));
1133+
ws_pae_supp_authenticate_response(pae_supp, result);
11251134
}
1135+
11261136
}
11271137

11281138
static void ws_pae_supp_kmp_api_finished(kmp_api_t *kmp)
@@ -1137,6 +1147,21 @@ static void ws_pae_supp_kmp_api_finished(kmp_api_t *kmp)
11371147
ws_pae_lib_kmp_list_delete(&pae_supp->entry.kmp_list, kmp);
11381148
}
11391149

1150+
static kmp_api_t *ws_pae_supp_kmp_tx_status_ind(kmp_service_t *service, uint8_t instance_id)
1151+
{
1152+
pae_supp_t *pae_supp = ws_pae_supp_by_kmp_service_get(service);
1153+
if (!pae_supp) {
1154+
return NULL;
1155+
}
1156+
1157+
kmp_api_t *kmp = ws_pae_lib_kmp_list_instance_id_get(&pae_supp->entry.kmp_list, instance_id);
1158+
if (!kmp) {
1159+
return NULL;
1160+
}
1161+
1162+
return kmp;
1163+
}
1164+
11401165
#endif /* HAVE_PAE_SUPP */
11411166
#endif /* HAVE_WS */
11421167

source/6LoWPAN/ws/ws_pae_supp.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,10 @@ typedef void ws_pae_supp_nw_key_index_set(protocol_interface_info_entry_t *inter
206206
* ws_pae_supp_auth_completed authentication completed callback
207207
*
208208
* \param interface_ptr interface
209-
* \param success true if authentication was successful
209+
* \param result result, either ok or failure reason
210210
*
211211
*/
212-
typedef void ws_pae_supp_auth_completed(protocol_interface_info_entry_t *interface_ptr, bool success);
212+
typedef void ws_pae_supp_auth_completed(protocol_interface_info_entry_t *interface_ptr, auth_result_e result);
213213

214214
/**
215215
* ws_pae_supp_nw_key_insert network key insert callback

0 commit comments

Comments
 (0)