@@ -86,7 +86,7 @@ static int8_t supp_fwh_sec_prot_init(sec_prot_t *prot);
86
86
static void supp_fwh_sec_prot_create_response (sec_prot_t * prot , sec_prot_result_e result );
87
87
static void supp_fwh_sec_prot_delete (sec_prot_t * prot );
88
88
static int8_t supp_fwh_sec_prot_receive (sec_prot_t * prot , void * pdu , uint16_t size );
89
- static fwh_sec_prot_msg_e supp_fwh_sec_prot_message_get (eapol_pdu_t * eapol_pdu , sec_prot_keys_t * sec_keys );
89
+ static fwh_sec_prot_msg_e supp_fwh_sec_prot_message_get (sec_prot_t * prot , eapol_pdu_t * eapol_pdu );
90
90
static void supp_fwh_sec_prot_state_machine (sec_prot_t * prot );
91
91
92
92
static int8_t supp_fwh_sec_prot_message_send (sec_prot_t * prot , fwh_sec_prot_msg_e msg );
@@ -96,6 +96,7 @@ static int8_t supp_fwh_sec_prot_ptk_generate(sec_prot_t *prot, sec_prot_keys_t *
96
96
static int8_t supp_fwh_sec_prot_mic_validate (sec_prot_t * prot );
97
97
98
98
static void supp_fwh_sec_prot_recv_replay_counter_store (sec_prot_t * prot );
99
+ static uint64_t supp_fwh_sec_prot_recv_replay_counter_get (sec_prot_t * prot );
99
100
static void supp_fwh_sec_prot_anonce_store (sec_prot_t * prot );
100
101
static int8_t supp_fwh_sec_prot_anonce_validate (sec_prot_t * prot );
101
102
static void supp_fwh_sec_prot_security_replay_counter_update (sec_prot_t * prot );
@@ -137,6 +138,7 @@ static int8_t supp_fwh_sec_prot_init(sec_prot_t *prot)
137
138
138
139
data -> common .ticks = 30 * 10 ; // 30 seconds
139
140
data -> msg3_retry_wait = false;
141
+ data -> recv_replay_cnt = 0 ;
140
142
141
143
uint8_t eui64 [8 ] = {0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 };
142
144
sec_prot_lib_nonce_init (data -> snonce , eui64 , 1000 );
@@ -167,7 +169,7 @@ static int8_t supp_fwh_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16_t si
167
169
// Decoding is successful
168
170
if (eapol_parse_pdu_header (pdu , size , & data -> recv_eapol_pdu )) {
169
171
// Get message
170
- data -> recv_msg = supp_fwh_sec_prot_message_get (& data -> recv_eapol_pdu , prot -> sec_keys );
172
+ data -> recv_msg = supp_fwh_sec_prot_message_get (prot , & data -> recv_eapol_pdu );
171
173
if (data -> recv_msg != FWH_MESSAGE_UNKNOWN ) {
172
174
tr_info ("4WH: recv %s" , data -> recv_msg == FWH_MESSAGE_1 ? "Message 1" : "Message 3" );
173
175
@@ -191,7 +193,7 @@ static int8_t supp_fwh_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16_t si
191
193
return ret_val ;
192
194
}
193
195
194
- static fwh_sec_prot_msg_e supp_fwh_sec_prot_message_get (eapol_pdu_t * eapol_pdu , sec_prot_keys_t * sec_keys )
196
+ static fwh_sec_prot_msg_e supp_fwh_sec_prot_message_get (sec_prot_t * prot , eapol_pdu_t * eapol_pdu )
195
197
{
196
198
fwh_sec_prot_msg_e msg = FWH_MESSAGE_UNKNOWN ;
197
199
@@ -203,17 +205,23 @@ static fwh_sec_prot_msg_e supp_fwh_sec_prot_message_get(eapol_pdu_t *eapol_pdu,
203
205
uint8_t key_mask = sec_prot_lib_key_mask_get (eapol_pdu );
204
206
205
207
switch (key_mask ) {
208
+ // Message 1
206
209
case KEY_INFO_KEY_ACK :
207
- // Must have valid replay counter
208
- if (eapol_pdu -> msg .key .replay_counter > sec_prot_keys_pmk_replay_cnt_get (sec_keys )) {
210
+ /* Must have valid replay counter, both larger for PMK and larger that is used on
211
+ * the four way handshake session (note: PMK replay counter is not updated for Message 1
212
+ * but session specific counter is)
213
+ */
214
+ if (eapol_pdu -> msg .key .replay_counter > sec_prot_keys_pmk_replay_cnt_get (prot -> sec_keys ) &&
215
+ eapol_pdu -> msg .key .replay_counter > supp_fwh_sec_prot_recv_replay_counter_get (prot )) {
209
216
msg = FWH_MESSAGE_1 ;
210
217
} else {
211
218
tr_error ("4WH: invalid replay counter %" PRId64 , eapol_pdu -> msg .key .replay_counter );
212
219
}
213
220
break ;
221
+ // Message 3
214
222
case KEY_INFO_INSTALL | KEY_INFO_KEY_ACK | KEY_INFO_KEY_MIC | KEY_INFO_SECURED_KEY_FRAME :
215
223
// Must have valid replay counter
216
- if (eapol_pdu -> msg .key .replay_counter > sec_prot_keys_pmk_replay_cnt_get (sec_keys )) {
224
+ if (eapol_pdu -> msg .key .replay_counter > sec_prot_keys_pmk_replay_cnt_get (prot -> sec_keys )) {
217
225
if (eapol_pdu -> msg .key .key_information .encrypted_key_data ) {
218
226
// This should include the GTK KDE, Lifetime KDE and GTKL KDE.
219
227
// At least some of them should be present
@@ -468,6 +476,12 @@ static void supp_fwh_sec_prot_recv_replay_counter_store(sec_prot_t *prot)
468
476
data -> recv_replay_cnt = data -> recv_eapol_pdu .msg .key .replay_counter ;
469
477
}
470
478
479
+ static uint64_t supp_fwh_sec_prot_recv_replay_counter_get (sec_prot_t * prot )
480
+ {
481
+ fwh_sec_prot_int_t * data = fwh_sec_prot_get (prot );
482
+ return data -> recv_replay_cnt ;
483
+ }
484
+
471
485
static void supp_fwh_sec_prot_anonce_store (sec_prot_t * prot )
472
486
{
473
487
fwh_sec_prot_int_t * data = fwh_sec_prot_get (prot );
0 commit comments