@@ -86,7 +86,7 @@ static int8_t supp_fwh_sec_prot_init(sec_prot_t *prot);
8686static void supp_fwh_sec_prot_create_response (sec_prot_t * prot , sec_prot_result_e result );
8787static void supp_fwh_sec_prot_delete (sec_prot_t * prot );
8888static 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 );
9090static void supp_fwh_sec_prot_state_machine (sec_prot_t * prot );
9191
9292static 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 *
9696static int8_t supp_fwh_sec_prot_mic_validate (sec_prot_t * prot );
9797
9898static 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 );
99100static void supp_fwh_sec_prot_anonce_store (sec_prot_t * prot );
100101static int8_t supp_fwh_sec_prot_anonce_validate (sec_prot_t * prot );
101102static 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)
137138
138139 data -> common .ticks = 30 * 10 ; // 30 seconds
139140 data -> msg3_retry_wait = false;
141+ data -> recv_replay_cnt = 0 ;
140142
141143 uint8_t eui64 [8 ] = {0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 };
142144 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
167169 // Decoding is successful
168170 if (eapol_parse_pdu_header (pdu , size , & data -> recv_eapol_pdu )) {
169171 // 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 );
171173 if (data -> recv_msg != FWH_MESSAGE_UNKNOWN ) {
172174 tr_info ("4WH: recv %s" , data -> recv_msg == FWH_MESSAGE_1 ? "Message 1" : "Message 3" );
173175
@@ -191,7 +193,7 @@ static int8_t supp_fwh_sec_prot_receive(sec_prot_t *prot, void *pdu, uint16_t si
191193 return ret_val ;
192194}
193195
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 )
195197{
196198 fwh_sec_prot_msg_e msg = FWH_MESSAGE_UNKNOWN ;
197199
@@ -203,17 +205,23 @@ static fwh_sec_prot_msg_e supp_fwh_sec_prot_message_get(eapol_pdu_t *eapol_pdu,
203205 uint8_t key_mask = sec_prot_lib_key_mask_get (eapol_pdu );
204206
205207 switch (key_mask ) {
208+ // Message 1
206209 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 )) {
209216 msg = FWH_MESSAGE_1 ;
210217 } else {
211218 tr_error ("4WH: invalid replay counter %" PRId64 , eapol_pdu -> msg .key .replay_counter );
212219 }
213220 break ;
221+ // Message 3
214222 case KEY_INFO_INSTALL | KEY_INFO_KEY_ACK | KEY_INFO_KEY_MIC | KEY_INFO_SECURED_KEY_FRAME :
215223 // 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 )) {
217225 if (eapol_pdu -> msg .key .key_information .encrypted_key_data ) {
218226 // This should include the GTK KDE, Lifetime KDE and GTKL KDE.
219227 // 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)
468476 data -> recv_replay_cnt = data -> recv_eapol_pdu .msg .key .replay_counter ;
469477}
470478
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+
471485static void supp_fwh_sec_prot_anonce_store (sec_prot_t * prot )
472486{
473487 fwh_sec_prot_int_t * data = fwh_sec_prot_get (prot );
0 commit comments