From 556da5e3b0cfa5470a9234f9dc357b18c137101a Mon Sep 17 00:00:00 2001 From: jordan Date: Sat, 14 Mar 2026 11:05:50 -0500 Subject: [PATCH 1/2] esp: improve oseq overflow handling. --- src/test/unit/unit_esp.c | 48 ++++++++++++++++++++++++++++++++++++++++ src/wolfesp.c | 6 ++++- wolfesp.h | 2 +- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/test/unit/unit_esp.c b/src/test/unit/unit_esp.c index 05f21db..aa393ff 100644 --- a/src/test/unit/unit_esp.c +++ b/src/test/unit/unit_esp.c @@ -503,6 +503,53 @@ START_TEST(test_replay_old_seqs_after_jump) } END_TEST +/* The transmitted sequence number must never be allowed to overflow. */ +START_TEST(test_replay_overflow) +{ + static uint8_t buf[LINK_MTU + 256]; + uint8_t ref[64]; + uint32_t frame_len, i; + uint16_t ip_len; + int ret; + wolfIP_esp_sa * esp_sa = NULL; + struct wolfIP_ip_packet *ip = (struct wolfIP_ip_packet *)buf; + + for (i = 0U; i < sizeof(ref); i++) ref[i] = (uint8_t)(i & 0xFFU); + + esp_setup(); + + ret = wolfIP_esp_sa_new_gcm(0, (uint8_t *)spi_rt, + atoip4(T_SRC), atoip4(T_DST), + ESP_ENC_GCM_RFC4543, + (uint8_t *)k_aes256_gcm, + sizeof(k_aes256_gcm)); + ck_assert_int_eq(ret, 0); + esp_sa = esp_sa_get(0, (uint8_t *)spi_rt); + ck_assert_ptr_nonnull(esp_sa); + + /* Set oseq to 10 before overflow. */ + esp_sa->replay.oseq = (ESP_MAX_32_SEQ - 10); + + /* all of these should be ok. */ + for (i = 0; i < 10; ++i) { + frame_len = build_ip_packet(buf, sizeof(buf), WI_IPPROTO_UDP, + ref, sizeof(ref)); + ip_len = (uint16_t)(frame_len - ETH_HEADER_LEN); + + ret = esp_transport_wrap(ip, &ip_len); + ck_assert_int_eq(ret, 0); + } + + /* oseq overflow is detected, and is rejected. */ + frame_len = build_ip_packet(buf, sizeof(buf), WI_IPPROTO_UDP, + ref, sizeof(ref)); + ip_len = (uint16_t)(frame_len - ETH_HEADER_LEN); + + ret = esp_transport_wrap(ip, &ip_len); + ck_assert_int_eq(ret, -1); +} +END_TEST + /* * esp_transport_unwrap error paths */ @@ -1123,6 +1170,7 @@ static Suite *esp_suite(void) 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); + tcase_add_test(tc, test_replay_overflow); suite_add_tcase(s, tc); /* Unwrap error paths */ diff --git a/src/wolfesp.c b/src/wolfesp.c index 003884f..82320fb 100644 --- a/src/wolfesp.c +++ b/src/wolfesp.c @@ -1489,10 +1489,14 @@ esp_transport_wrap(struct wolfIP_ip_packet *ip, uint16_t * ip_len) memcpy(payload, esp_sa->spi, sizeof(esp_sa->spi)); payload += ESP_SPI_LEN; + esp_sa->replay.oseq++; + if (esp_sa->replay.oseq == 0) { + ESP_LOG("error: oseq overflow\n"); + return -1; + } seq_n = ee32(esp_sa->replay.oseq); memcpy(payload, &seq_n, sizeof(seq_n)); payload += ESP_SEQ_LEN; - esp_sa->replay.oseq++; if (iv_len) { /* skip iv field, will generate later. */ diff --git a/wolfesp.h b/wolfesp.h index e0c7823..a2101cf 100644 --- a/wolfesp.h +++ b/wolfesp.h @@ -69,7 +69,7 @@ typedef struct replay_t replay_t; do { \ (r).bitmap = 0U; \ (r).hi_seq = ESP_REPLAY_WIN; \ - (r).oseq = 1U; \ + (r).oseq = 0U; \ } while (0) /* Minimal ESP Security Association structure. From 539cb6290aa108d86bbc42275bfbc0fee1f60782 Mon Sep 17 00:00:00 2001 From: jordan Date: Sat, 14 Mar 2026 11:25:46 -0500 Subject: [PATCH 2/2] esp: detect multiple subsequent seq overflows. --- src/test/unit/unit_esp.c | 14 ++++++++------ src/wolfesp.c | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/test/unit/unit_esp.c b/src/test/unit/unit_esp.c index aa393ff..f648c30 100644 --- a/src/test/unit/unit_esp.c +++ b/src/test/unit/unit_esp.c @@ -540,13 +540,15 @@ START_TEST(test_replay_overflow) ck_assert_int_eq(ret, 0); } - /* oseq overflow is detected, and is rejected. */ - frame_len = build_ip_packet(buf, sizeof(buf), WI_IPPROTO_UDP, - ref, sizeof(ref)); - ip_len = (uint16_t)(frame_len - ETH_HEADER_LEN); + /* all of these should be rejected, oseq overflow is detected. */ + for (i = 0; i < 10; ++i) { + frame_len = build_ip_packet(buf, sizeof(buf), WI_IPPROTO_UDP, + ref, sizeof(ref)); + ip_len = (uint16_t)(frame_len - ETH_HEADER_LEN); - ret = esp_transport_wrap(ip, &ip_len); - ck_assert_int_eq(ret, -1); + ret = esp_transport_wrap(ip, &ip_len); + ck_assert_int_eq(ret, -1); + } } END_TEST diff --git a/src/wolfesp.c b/src/wolfesp.c index 82320fb..4ada1d7 100644 --- a/src/wolfesp.c +++ b/src/wolfesp.c @@ -1491,6 +1491,7 @@ esp_transport_wrap(struct wolfIP_ip_packet *ip, uint16_t * ip_len) esp_sa->replay.oseq++; if (esp_sa->replay.oseq == 0) { + esp_sa->replay.oseq--; ESP_LOG("error: oseq overflow\n"); return -1; }