diff --git a/src/test/unit/unit_esp.c b/src/test/unit/unit_esp.c index 5d3433c..e988898 100644 --- a/src/test/unit/unit_esp.c +++ b/src/test/unit/unit_esp.c @@ -383,6 +383,17 @@ START_TEST(test_replay_advance_hi_seq) } END_TEST +/* A corrupted low hi_seq should not underflow the window floor. */ +START_TEST(test_replay_low_hi_seq_accepts_seq_one) +{ + replay_t r; + esp_replay_init(r); + r.hi_seq = 1U; + r.bitmap = 0U; + ck_assert_int_eq(esp_check_replay(&r, 1U), 0); +} +END_TEST + /* A jump larger than the window width resets the bitmap. */ START_TEST(test_replay_jump_resets_bitmap) { @@ -944,6 +955,7 @@ static Suite *esp_suite(void) tcase_add_test(tc, test_replay_multiple_in_window); tcase_add_test(tc, test_replay_below_window_rejected); tcase_add_test(tc, test_replay_advance_hi_seq); + tcase_add_test(tc, test_replay_low_hi_seq_accepts_seq_one); tcase_add_test(tc, test_replay_jump_resets_bitmap); tcase_add_test(tc, test_replay_old_seqs_after_jump); suite_add_tcase(s, tc); diff --git a/src/wolfesp.c b/src/wolfesp.c index 1987e6c..61e4e2a 100644 --- a/src/wolfesp.c +++ b/src/wolfesp.c @@ -1060,12 +1060,17 @@ esp_check_replay(struct replay_t * replay, uint32_t seq) #else uint32_t diff = 0; uint32_t bitn = 0; - uint32_t seq_low = replay->hi_seq - (ESP_REPLAY_WIN - 1); + uint32_t seq_low = 1U; if (seq == 0) { return -1; } + /* Clamp window floor to 1 when hi_seq is corrupted below window width. */ + if (replay->hi_seq >= (ESP_REPLAY_WIN - 1U)) { + seq_low = replay->hi_seq - (ESP_REPLAY_WIN - 1U); + } + if (seq < seq_low) { ESP_LOG("error: seq (%d) below window (%d)\n", seq, seq_low); return -1;