@@ -79,6 +79,7 @@ typedef struct {
79
79
uint64_t recv_replay_cnt ; /**< received replay counter */
80
80
bool msg3_received : 1 ; /**< Valid Message 3 has been received */
81
81
bool msg3_retry_wait : 1 ; /**< Waiting for Message 3 retry */
82
+ bool recv_replay_cnt_set : 1 ; /**< received replay counter set */
82
83
} fwh_sec_prot_int_t ;
83
84
84
85
static uint16_t supp_fwh_sec_prot_size (void );
@@ -97,7 +98,7 @@ static int8_t supp_fwh_sec_prot_ptk_generate(sec_prot_t *prot, sec_prot_keys_t *
97
98
static int8_t supp_fwh_sec_prot_mic_validate (sec_prot_t * prot );
98
99
99
100
static void supp_fwh_sec_prot_recv_replay_counter_store (sec_prot_t * prot );
100
- static uint64_t supp_fwh_sec_prot_recv_replay_counter_get ( sec_prot_t * prot );
101
+ static bool supp_fwh_sec_prot_recv_replay_cnt_compare ( uint64_t received_counter , sec_prot_t * prot );
101
102
static void supp_fwh_sec_prot_anonce_store (sec_prot_t * prot );
102
103
static int8_t supp_fwh_sec_prot_anonce_validate (sec_prot_t * prot );
103
104
static void supp_fwh_sec_prot_security_replay_counter_update (sec_prot_t * prot );
@@ -141,6 +142,7 @@ static int8_t supp_fwh_sec_prot_init(sec_prot_t *prot)
141
142
data -> msg3_received = false;
142
143
data -> msg3_retry_wait = false;
143
144
data -> recv_replay_cnt = 0 ;
145
+ data -> recv_replay_cnt_set = false;
144
146
145
147
uint8_t eui64 [8 ] = {0x01 , 0x02 , 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 };
146
148
sec_prot_lib_nonce_init (data -> snonce , eui64 , 1000 );
@@ -213,8 +215,8 @@ static fwh_sec_prot_msg_e supp_fwh_sec_prot_message_get(sec_prot_t *prot, eapol_
213
215
* the four way handshake session (note: PMK replay counter is not updated for Message 1
214
216
* but session specific counter is)
215
217
*/
216
- if (eapol_pdu -> msg .key .replay_counter > sec_prot_keys_pmk_replay_cnt_get ( prot -> sec_keys ) &&
217
- eapol_pdu -> msg .key .replay_counter > supp_fwh_sec_prot_recv_replay_counter_get ( prot )) {
218
+ if (sec_prot_keys_pmk_replay_cnt_compare ( eapol_pdu -> msg .key .replay_counter , prot -> sec_keys ) &&
219
+ supp_fwh_sec_prot_recv_replay_cnt_compare ( eapol_pdu -> msg .key .replay_counter , prot )) {
218
220
msg = FWH_MESSAGE_1 ;
219
221
} else {
220
222
tr_error ("4WH: invalid replay counter %" PRId64 , eapol_pdu -> msg .key .replay_counter );
@@ -223,7 +225,7 @@ static fwh_sec_prot_msg_e supp_fwh_sec_prot_message_get(sec_prot_t *prot, eapol_
223
225
// Message 3
224
226
case KEY_INFO_INSTALL | KEY_INFO_KEY_ACK | KEY_INFO_KEY_MIC | KEY_INFO_SECURED_KEY_FRAME :
225
227
// Must have valid replay counter
226
- if (eapol_pdu -> msg .key .replay_counter > sec_prot_keys_pmk_replay_cnt_get ( prot -> sec_keys )) {
228
+ if (sec_prot_keys_pmk_replay_cnt_compare ( eapol_pdu -> msg .key .replay_counter , prot -> sec_keys )) {
227
229
if (eapol_pdu -> msg .key .key_information .encrypted_key_data ) {
228
230
// This should include the GTK KDE, Lifetime KDE and GTKL KDE.
229
231
// At least some of them should be present
@@ -489,12 +491,21 @@ static void supp_fwh_sec_prot_recv_replay_counter_store(sec_prot_t *prot)
489
491
{
490
492
fwh_sec_prot_int_t * data = fwh_sec_prot_get (prot );
491
493
data -> recv_replay_cnt = data -> recv_eapol_pdu .msg .key .replay_counter ;
494
+ data -> recv_replay_cnt_set = true;
492
495
}
493
496
494
- static uint64_t supp_fwh_sec_prot_recv_replay_counter_get ( sec_prot_t * prot )
497
+ static bool supp_fwh_sec_prot_recv_replay_cnt_compare ( uint64_t received_counter , sec_prot_t * prot )
495
498
{
496
499
fwh_sec_prot_int_t * data = fwh_sec_prot_get (prot );
497
- return data -> recv_replay_cnt ;
500
+ // If previous value is set must be greater
501
+ if (data -> recv_replay_cnt_set && received_counter > data -> recv_replay_cnt ) {
502
+ return true;
503
+ } else if (!data -> recv_replay_cnt_set && received_counter >= data -> recv_replay_cnt ) {
504
+ // Otherwise allows also same value e.g. zero
505
+ return true;
506
+ }
507
+
508
+ return false;
498
509
}
499
510
500
511
static void supp_fwh_sec_prot_anonce_store (sec_prot_t * prot )
0 commit comments