From e5718111e490e04d9231cdb69d4b9f7288d7893b Mon Sep 17 00:00:00 2001 From: jordan Date: Tue, 2 Jun 2026 17:10:52 -0500 Subject: [PATCH 1/4] esp: improve spi and ip checks. --- src/test/unit/unit_esp.c | 15 ++++++++++ src/wolfesp.c | 60 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/test/unit/unit_esp.c b/src/test/unit/unit_esp.c index 1dbe906d..fef38bd2 100644 --- a/src/test/unit/unit_esp.c +++ b/src/test/unit/unit_esp.c @@ -86,6 +86,7 @@ static uint8_t spi_a[4] = { 0x11, 0x22, 0x33, 0x44 }; static uint8_t spi_b[4] = { 0x55, 0x66, 0x77, 0x88 }; static uint8_t spi_c[4] = { 0x99, 0xAA, 0xBB, 0xCC }; static uint8_t spi_d[4] = { 0xFF, 0xEE, 0xDD, 0xCC }; /* overflows pool */ +static uint8_t spi_bad[4] = { 0x00, 0x00, 0x00, 0x00 }; /* Test IP addresses. */ #define T_SRC "192.168.1.1" @@ -206,6 +207,14 @@ START_TEST(test_sa_hmac_bad) int ret; esp_setup(); + /* everything good but spi */ + ret = wolfIP_esp_sa_new_hmac(1, (uint8_t *)spi_bad, + atoip4(T_SRC), atoip4(T_DST), + ESP_AUTH_SHA256_RFC4868, + (uint8_t *)k_auth16, sizeof(k_auth16), + ESP_ICVLEN_HMAC_128); + ck_assert_int_eq(ret, -1); + /* auth with wrong icv len */ ret = wolfIP_esp_sa_new_hmac(1, (uint8_t *)spi_a, atoip4(T_SRC), atoip4(T_DST), @@ -255,6 +264,12 @@ START_TEST(test_sa_cbc_hmac_bad) { int ret; esp_setup(); + ret = wolfIP_esp_sa_new_cbc_hmac(1, (uint8_t *)spi_bad, + atoip4(T_SRC), atoip4(T_DST), + (uint8_t *)k_aes128, sizeof(k_aes128), + ESP_AUTH_NONE, NULL, 0, 0); + ck_assert_int_eq(ret, -1); + ret = wolfIP_esp_sa_new_cbc_hmac(1, (uint8_t *)spi_a, atoip4(T_SRC), atoip4(T_DST), (uint8_t *)k_aes128, sizeof(k_aes128), diff --git a/src/wolfesp.c b/src/wolfesp.c index 00e5aa4e..b1288d03 100644 --- a/src/wolfesp.c +++ b/src/wolfesp.c @@ -71,15 +71,19 @@ void wolfIP_esp_sa_del_all(void) return; } +static const uint8_t zero_spi[ESP_SPI_LEN] = {0x00, 0x00, 0x00, 0x00}; + +/* Get an SA by spi. + * If spi is null, return the first empty slot (an SA with all zero SPI). + * */ static inline wolfIP_esp_sa * esp_sa_get(int in, const uint8_t * spi) { - uint8_t empty_sa[4] = {0x00, 0x00, 0x00, 0x00}; wolfIP_esp_sa * list = NULL; size_t i = 0; if (spi == NULL) { - spi = empty_sa; + spi = zero_spi; } in = (in == 0 ? 0 : 1); @@ -109,6 +113,27 @@ void wolfIP_esp_sa_del(int in, uint8_t * spi) return; } +/* return 0 if valid spi number. + * return -1 if invalid + * */ +static inline int +esp_spi_valid(const uint8_t * spi) +{ + /* RFC4303: + * The SPI value of zero (0) is reserved for local, + * implementation-specific use and MUST NOT be sent on the wire. + * */ + if (memcmp(spi, zero_spi, ESP_SPI_LEN) == 0) { + ESP_LOG("info: invalid zero (0) value spi\n"); + return -1; + } + + /* SPI values 1 through 255 are reserved by IANA, and technically we + * could check and reject them. Probably not worth being this fastidious. + * */ + return 0; +} + /* Configure a new Security Association based on either * enc = ESP_ENC_GCM_RFC4106 (gcm), or enc = ESP_AUTH_GCM_RFC4543 (gmac). * */ @@ -120,6 +145,10 @@ int wolfIP_esp_sa_new_gcm(int in, uint8_t * spi, ip4 src, ip4 dst, int err = 0; esp_auth_t auth = 0; + if (esp_spi_valid(spi) < 0) { + return -1; + } + new_sa = esp_sa_get(in, NULL); if (new_sa == NULL) { ESP_LOG("error: sa %s pool is full\n", in == 1 ? "in" : "out"); @@ -233,6 +262,10 @@ int wolfIP_esp_sa_new_hmac(int in, uint8_t * spi, ip4 src, ip4 dst, { wolfIP_esp_sa * new_sa = NULL; + if (esp_spi_valid(spi) < 0) { + return -1; + } + new_sa = esp_sa_get(in, NULL); if (new_sa == NULL) { ESP_LOG("error: sa %s pool is full\n", in == 1 ? "in" : "out"); @@ -275,6 +308,10 @@ int wolfIP_esp_sa_new_cbc_hmac(int in, uint8_t * spi, ip4 src, ip4 dst, { wolfIP_esp_sa * new_sa = NULL; + if (esp_spi_valid(spi) < 0) { + return -1; + } + new_sa = esp_sa_get(in, NULL); if (new_sa == NULL) { ESP_LOG("error: sa %s pool is full\n", in == 1 ? "in" : "out"); @@ -329,6 +366,10 @@ wolfIP_esp_sa_new_des3_hmac(int in, uint8_t * spi, ip4 src, ip4 dst, { wolfIP_esp_sa * new_sa = NULL; + if (esp_spi_valid(spi) < 0) { + return -1; + } + new_sa = esp_sa_get(in, NULL); if (new_sa == NULL) { ESP_LOG("error: sa %s pool is full\n", in == 1 ? "in" : "out"); @@ -1312,8 +1353,14 @@ esp_transport_unwrap(struct wolfIP_ip_packet *ip, uint32_t * frame_len) memcpy(&seq, ip->data + ESP_SPI_LEN, sizeof(seq)); seq = ee32(seq); + if (esp_spi_valid(spi) < 0) { + return -1; + } + for (size_t i = 0; i < in_sa_num; ++i) { - if (memcmp(spi, in_sa_list[i].spi, sizeof(spi)) == 0) { + if (memcmp(spi, in_sa_list[i].spi, sizeof(spi)) == 0 && + ip->dst == ee32(in_sa_list[i].dst) && + ip->src == ee32(in_sa_list[i].src)) { ESP_DEBUG("info: found sa: 0x%02x%02x%02x%02x\n", spi[0], spi[1], spi[2], spi[3]); esp_sa = &in_sa_list[i]; @@ -1326,7 +1373,7 @@ esp_transport_unwrap(struct wolfIP_ip_packet *ip, uint32_t * frame_len) * If no valid Security Association exists for this packet, the * receiver MUST discard the packet; this is an auditable event. * */ - ESP_LOG("error: unknown spi: 0x%02x%02x%02x%02x\n", + ESP_LOG("info: unknown spi: 0x%02x%02x%02x%02x\n", spi[0], spi[1], spi[2], spi[3]); return -1; } @@ -1521,9 +1568,10 @@ esp_transport_wrap(struct wolfIP_ip_packet *ip, uint16_t * ip_len) } /* todo: priority, proto / port filtering. currently this grabs - * the first dst match. */ + * the first dst and src match. */ for (size_t i = 0; i < out_sa_num; ++i) { - if (ip->dst == ee32(out_sa_list[i].dst)) { + if (ip->dst == ee32(out_sa_list[i].dst) && + ip->src == ee32(out_sa_list[i].src)) { esp_sa = &out_sa_list[i]; ESP_DEBUG("info: found out sa: 0x%02x%02x%02x%02x\n", esp_sa->spi[0], esp_sa->spi[1], esp_sa->spi[2], From cc8f9197459232edd223737e0809882144e5861e Mon Sep 17 00:00:00 2001 From: jordan Date: Wed, 3 Jun 2026 12:26:51 -0500 Subject: [PATCH 2/4] esp: improve SA lookups. --- src/test/unit/unit_esp.c | 4 +-- src/wolfesp.c | 70 +++++++++++++++++++++++++++++++--------- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/test/unit/unit_esp.c b/src/test/unit/unit_esp.c index fef38bd2..5debc56c 100644 --- a/src/test/unit/unit_esp.c +++ b/src/test/unit/unit_esp.c @@ -1263,8 +1263,8 @@ END_TEST /* * no matching outbound SA (esp_transport_wrap returns 1) - * */ -/* When no outbound SA matches ip->dst, wrap must return 1 (caller should + * + * When no outbound SA matches ip->dst, wrap must return 1 (caller should * send plaintext). */ START_TEST(test_wrap_no_matching_sa) { diff --git a/src/wolfesp.c b/src/wolfesp.c index b1288d03..3d7f12c1 100644 --- a/src/wolfesp.c +++ b/src/wolfesp.c @@ -119,6 +119,9 @@ void wolfIP_esp_sa_del(int in, uint8_t * spi) static inline int esp_spi_valid(const uint8_t * spi) { + if (spi == NULL) { + return -1; + } /* RFC4303: * The SPI value of zero (0) is reserved for local, * implementation-specific use and MUST NOT be sent on the wire. @@ -1357,15 +1360,38 @@ esp_transport_unwrap(struct wolfIP_ip_packet *ip, uint32_t * frame_len) return -1; } + /* ESP SA lookup: + * - If user configured {spi, src, dst}, then match on full triplet. + * - If either src or dst are 0, don't require a full match. + * - The spi must always match. + * */ for (size_t i = 0; i < in_sa_num; ++i) { - if (memcmp(spi, in_sa_list[i].spi, sizeof(spi)) == 0 && - ip->dst == ee32(in_sa_list[i].dst) && - ip->src == ee32(in_sa_list[i].src)) { - ESP_DEBUG("info: found sa: 0x%02x%02x%02x%02x\n", - spi[0], spi[1], spi[2], spi[3]); - esp_sa = &in_sa_list[i]; - break; + if (esp_spi_valid(out_sa_list[i].spi) < 0) { + /* skip empty slots */ + continue; + } + + if (memcmp(spi, in_sa_list[i].spi, sizeof(spi)) != 0) { + /* SPI doesn't match */ + continue; + } + + if (in_sa_list[i].dst != 0 && + ip->dst != ee32(in_sa_list[i].dst)) { + /* SA ip dst is configured, and doesn't match */ + continue; + } + + if (in_sa_list[i].src != 0 && + ip->src != ee32(in_sa_list[i].src)) { + /* SA ip src is configured, and doesn't match */ + continue; } + + ESP_DEBUG("info: found sa: 0x%02x%02x%02x%02x\n", + spi[0], spi[1], spi[2], spi[3]); + esp_sa = &in_sa_list[i]; + break; } if (esp_sa == NULL) { @@ -1373,7 +1399,7 @@ esp_transport_unwrap(struct wolfIP_ip_packet *ip, uint32_t * frame_len) * If no valid Security Association exists for this packet, the * receiver MUST discard the packet; this is an auditable event. * */ - ESP_LOG("info: unknown spi: 0x%02x%02x%02x%02x\n", + ESP_LOG("error: unknown spi: 0x%02x%02x%02x%02x\n", spi[0], spi[1], spi[2], spi[3]); return -1; } @@ -1570,14 +1596,28 @@ esp_transport_wrap(struct wolfIP_ip_packet *ip, uint16_t * ip_len) /* todo: priority, proto / port filtering. currently this grabs * the first dst and src match. */ for (size_t i = 0; i < out_sa_num; ++i) { - if (ip->dst == ee32(out_sa_list[i].dst) && - ip->src == ee32(out_sa_list[i].src)) { - esp_sa = &out_sa_list[i]; - ESP_DEBUG("info: found out sa: 0x%02x%02x%02x%02x\n", - esp_sa->spi[0], esp_sa->spi[1], esp_sa->spi[2], - esp_sa->spi[3]); - break; + if (esp_spi_valid(out_sa_list[i].spi) < 0) { + /* skip empty slots */ + continue; + } + + if (out_sa_list[i].dst != 0 && + ip->dst != ee32(out_sa_list[i].dst)) { + /* SA ip dst is configured, and doesn't match */ + continue; + } + + if (out_sa_list[i].src != 0 && + ip->src != ee32(out_sa_list[i].src)) { + /* SA ip src is configured, and doesn't match */ + continue; } + + esp_sa = &out_sa_list[i]; + ESP_DEBUG("info: found out sa: 0x%02x%02x%02x%02x\n", + esp_sa->spi[0], esp_sa->spi[1], esp_sa->spi[2], + esp_sa->spi[3]); + break; } if (esp_sa == NULL) { From 4407abb49478f801bf769b54aeac493099815785 Mon Sep 17 00:00:00 2001 From: jordan Date: Wed, 3 Jun 2026 16:27:35 -0500 Subject: [PATCH 3/4] esp: cleanup, and add unit_esp ip filtering tests. --- src/test/unit/unit_esp.c | 197 ++++++++++++++++++++++++++++++++++++++- src/wolfesp.c | 20 ++-- 2 files changed, 205 insertions(+), 12 deletions(-) diff --git a/src/test/unit/unit_esp.c b/src/test/unit/unit_esp.c index 5debc56c..4336c7e9 100644 --- a/src/test/unit/unit_esp.c +++ b/src/test/unit/unit_esp.c @@ -86,11 +86,12 @@ static uint8_t spi_a[4] = { 0x11, 0x22, 0x33, 0x44 }; static uint8_t spi_b[4] = { 0x55, 0x66, 0x77, 0x88 }; static uint8_t spi_c[4] = { 0x99, 0xAA, 0xBB, 0xCC }; static uint8_t spi_d[4] = { 0xFF, 0xEE, 0xDD, 0xCC }; /* overflows pool */ -static uint8_t spi_bad[4] = { 0x00, 0x00, 0x00, 0x00 }; +static uint8_t spi_zero[4] = { 0x00, 0x00, 0x00, 0x00 }; /* Test IP addresses. */ #define T_SRC "192.168.1.1" #define T_DST "192.168.1.2" +#define T_MISC "192.168.1.9" /* * builds a minimal IPv4 packet (with Ethernet frame header). @@ -208,7 +209,7 @@ START_TEST(test_sa_hmac_bad) esp_setup(); /* everything good but spi */ - ret = wolfIP_esp_sa_new_hmac(1, (uint8_t *)spi_bad, + ret = wolfIP_esp_sa_new_hmac(1, (uint8_t *)spi_zero, atoip4(T_SRC), atoip4(T_DST), ESP_AUTH_SHA256_RFC4868, (uint8_t *)k_auth16, sizeof(k_auth16), @@ -264,7 +265,7 @@ START_TEST(test_sa_cbc_hmac_bad) { int ret; esp_setup(); - ret = wolfIP_esp_sa_new_cbc_hmac(1, (uint8_t *)spi_bad, + ret = wolfIP_esp_sa_new_cbc_hmac(1, (uint8_t *)spi_zero, atoip4(T_SRC), atoip4(T_DST), (uint8_t *)k_aes128, sizeof(k_aes128), ESP_AUTH_NONE, NULL, 0, 0); @@ -901,6 +902,195 @@ START_TEST(test_unwrap_invalid_pad_pattern) } END_TEST +/* + * test esp ip src/dst filtering + * + * This tests 4 scenarios: + * 1. misc src, dst address that does not match the SA triplet. + * 2. wildcard dst ip in outbound SA only, with misc dst address. + * 3. wildcard dst ip in both in/out SAs, with misc dst address. + * 4. wildcard src ip in both in/out SAs, with misc src address. + * */ +START_TEST(test_unwrap_ip_filtering) +{ + static uint8_t buf[LINK_MTU + 256]; + uint8_t ref[64]; + uint32_t frame_len; + uint16_t ip_len; + struct wolfIP_ip_packet *ip = (struct wolfIP_ip_packet *)buf; + uint8_t restored_proto; + int ret; + uint32_t i; + + /* Fill reference payload with a known pattern. */ + for (i = 0U; i < sizeof(ref); i++) { + ref[i] = (uint8_t)(i & 0xFFU); + } + + esp_setup(); + + /* + * 0th Scenario: + * do quick sanity check that wrap/unwrap works. + * */ + ret = wolfIP_esp_sa_new_cbc_hmac(0, (uint8_t *)spi_rt, + atoip4(T_SRC), atoip4(T_DST), + k_aes128, sizeof(k_aes128), + ESP_AUTH_SHA256_RFC4868, + k_auth16, sizeof(k_auth16), + ESP_ICVLEN_HMAC_128); + ck_assert_int_eq(ret, 0); + ret = wolfIP_esp_sa_new_cbc_hmac(1, (uint8_t *)spi_rt, + atoip4(T_SRC), atoip4(T_DST), + k_aes128, sizeof(k_aes128), + ESP_AUTH_SHA256_RFC4868, + k_auth16, sizeof(k_auth16), + ESP_ICVLEN_HMAC_128); + ck_assert_int_eq(ret, 0); + frame_len = build_udp_ip_packet(buf, sizeof(buf), + atoip4(T_SRC), atoip4(T_DST), + 4321, 1234, ref, sizeof(ref)); + ip_len = (uint16_t)(frame_len - ETH_HEADER_LEN); + /* wrap */ + ret = esp_transport_wrap(ip, &ip_len); + ck_assert_int_eq(ret, 0); + frame_len = (uint32_t)ip_len + ETH_HEADER_LEN; + /* unwrap */ + ret = esp_transport_unwrap(ip, &frame_len); + ck_assert_int_eq(ret, 0); + restored_proto = ip->proto; + ck_assert_uint_eq(restored_proto, WI_IPPROTO_UDP); + /* The udp payload must match the original plaintext exactly. */ + ck_assert_mem_eq(ip->data + UDP_HEADER_LEN, ref, sizeof(ref)); + + /* + * 1st Scenario: + * misc src, dst address that do not match the SA triplet + * */ + frame_len = build_udp_ip_packet(buf, sizeof(buf), + atoip4(T_MISC), atoip4(T_DST), + 4321, 1234, ref, sizeof(ref)); + ip_len = (uint16_t)(frame_len - ETH_HEADER_LEN); + ret = esp_transport_wrap(ip, &ip_len); + /* wrap fails */ + ck_assert_int_eq(ret, 1); + + frame_len = build_udp_ip_packet(buf, sizeof(buf), + atoip4(T_SRC), atoip4(T_MISC), + 4321, 1234, ref, sizeof(ref)); + ip_len = (uint16_t)(frame_len - ETH_HEADER_LEN); + ret = esp_transport_wrap(ip, &ip_len); + /* wrap fails */ + ck_assert_int_eq(ret, 1); + + /* + * 2nd Scenario: + * wildcard dst ip in outbound SA only, with misc dst address. + * */ + wolfIP_esp_sa_del_all(); + ret = wolfIP_esp_sa_new_cbc_hmac(0, (uint8_t *)spi_rt, + atoip4(T_SRC), 0, + k_aes128, sizeof(k_aes128), + ESP_AUTH_SHA256_RFC4868, + k_auth16, sizeof(k_auth16), + ESP_ICVLEN_HMAC_128); + ck_assert_int_eq(ret, 0); + + ret = wolfIP_esp_sa_new_cbc_hmac(1, (uint8_t *)spi_rt, + atoip4(T_SRC), atoip4(T_DST), + k_aes128, sizeof(k_aes128), + ESP_AUTH_SHA256_RFC4868, + k_auth16, sizeof(k_auth16), + ESP_ICVLEN_HMAC_128); + ck_assert_int_eq(ret, 0); + /* Build a plaintext IPv4/UDP packet to MISC address. */ + frame_len = build_udp_ip_packet(buf, sizeof(buf), + atoip4(T_SRC), atoip4(T_MISC), + 4321, 1234, ref, sizeof(ref)); + + ip_len = (uint16_t)(frame_len - ETH_HEADER_LEN); + + /* wrap succeeds because it can wildcard. */ + ret = esp_transport_wrap(ip, &ip_len); + ck_assert_int_eq(ret, 0); + frame_len = (uint32_t)ip_len + ETH_HEADER_LEN; + /* but unwrap does not have wildcard and fails to match triplet */ + ret = esp_transport_unwrap(ip, &frame_len); + ck_assert_int_eq(ret, -1); + + /* + * 3rd Scenario: + * wildcard dst ip in both in/out SAs, with misc dst address. + * */ + wolfIP_esp_sa_del_all(); + ret = wolfIP_esp_sa_new_cbc_hmac(0, (uint8_t *)spi_rt, + atoip4(T_SRC), 0, + k_aes128, sizeof(k_aes128), + ESP_AUTH_SHA256_RFC4868, + k_auth16, sizeof(k_auth16), + ESP_ICVLEN_HMAC_128); + ck_assert_int_eq(ret, 0); + + ret = wolfIP_esp_sa_new_cbc_hmac(1, (uint8_t *)spi_rt, + atoip4(T_SRC), 0, + k_aes128, sizeof(k_aes128), + ESP_AUTH_SHA256_RFC4868, + k_auth16, sizeof(k_auth16), + ESP_ICVLEN_HMAC_128); + ck_assert_int_eq(ret, 0); + + /* Build a plaintext IPv4/UDP packet to MISC. */ + frame_len = build_udp_ip_packet(buf, sizeof(buf), + atoip4(T_SRC), atoip4(T_MISC), + 4321, 1234, ref, sizeof(ref)); + + ip_len = (uint16_t)(frame_len - ETH_HEADER_LEN); + + /* now wrap and unwrap succeeds because dst can wildcard match */ + ret = esp_transport_wrap(ip, &ip_len); + ck_assert_int_eq(ret, 0); + frame_len = (uint32_t)ip_len + ETH_HEADER_LEN; + + ret = esp_transport_unwrap(ip, &frame_len); + ck_assert_int_eq(ret, 0); + + /* + * 4th Scenario: + * wildcard src ip in both in/out SAs, with misc src address. + * */ + wolfIP_esp_sa_del_all(); + ret = wolfIP_esp_sa_new_cbc_hmac(0, (uint8_t *)spi_rt, + 0, atoip4(T_DST), + k_aes128, sizeof(k_aes128), + ESP_AUTH_SHA256_RFC4868, + k_auth16, sizeof(k_auth16), + ESP_ICVLEN_HMAC_128); + ck_assert_int_eq(ret, 0); + + ret = wolfIP_esp_sa_new_cbc_hmac(1, (uint8_t *)spi_rt, + 0, atoip4(T_DST), + k_aes128, sizeof(k_aes128), + ESP_AUTH_SHA256_RFC4868, + k_auth16, sizeof(k_auth16), + ESP_ICVLEN_HMAC_128); + ck_assert_int_eq(ret, 0); + + /* Build a plaintext IPv4/UDP packet from MISC. */ + frame_len = build_udp_ip_packet(buf, sizeof(buf), + atoip4(T_MISC),atoip4(T_DST), + 4321, 1234, ref, sizeof(ref)); + + ip_len = (uint16_t)(frame_len - ETH_HEADER_LEN); + + /* now wrap and unwrap succeeds because src can wildcard match */ + ret = esp_transport_wrap(ip, &ip_len); + ck_assert_int_eq(ret, 0); + frame_len = (uint32_t)ip_len + ETH_HEADER_LEN; + + ret = esp_transport_unwrap(ip, &frame_len); + ck_assert_int_eq(ret, 0); +} + /* * full enc/dec round-trips * */ @@ -1740,6 +1930,7 @@ static Suite *esp_suite(void) tcase_add_test(tc, test_unwrap_below_min_len); tcase_add_test(tc, test_unwrap_pad_too_big); tcase_add_test(tc, test_unwrap_invalid_pad_pattern); + tcase_add_test(tc, test_unwrap_ip_filtering); suite_add_tcase(s, tc); /* Crypto round-trips */ diff --git a/src/wolfesp.c b/src/wolfesp.c index 3d7f12c1..e5e221e0 100644 --- a/src/wolfesp.c +++ b/src/wolfesp.c @@ -117,7 +117,7 @@ void wolfIP_esp_sa_del(int in, uint8_t * spi) * return -1 if invalid * */ static inline int -esp_spi_valid(const uint8_t * spi) +esp_spi_valid(const uint8_t * spi, int log_it) { if (spi == NULL) { return -1; @@ -127,7 +127,9 @@ esp_spi_valid(const uint8_t * spi) * implementation-specific use and MUST NOT be sent on the wire. * */ if (memcmp(spi, zero_spi, ESP_SPI_LEN) == 0) { - ESP_LOG("info: invalid zero (0) value spi\n"); + if (log_it) { + ESP_LOG("info: invalid zero (0) value spi\n"); + } return -1; } @@ -148,7 +150,7 @@ int wolfIP_esp_sa_new_gcm(int in, uint8_t * spi, ip4 src, ip4 dst, int err = 0; esp_auth_t auth = 0; - if (esp_spi_valid(spi) < 0) { + if (esp_spi_valid(spi, 1) < 0) { return -1; } @@ -265,7 +267,7 @@ int wolfIP_esp_sa_new_hmac(int in, uint8_t * spi, ip4 src, ip4 dst, { wolfIP_esp_sa * new_sa = NULL; - if (esp_spi_valid(spi) < 0) { + if (esp_spi_valid(spi, 1) < 0) { return -1; } @@ -311,7 +313,7 @@ int wolfIP_esp_sa_new_cbc_hmac(int in, uint8_t * spi, ip4 src, ip4 dst, { wolfIP_esp_sa * new_sa = NULL; - if (esp_spi_valid(spi) < 0) { + if (esp_spi_valid(spi, 1) < 0) { return -1; } @@ -369,7 +371,7 @@ wolfIP_esp_sa_new_des3_hmac(int in, uint8_t * spi, ip4 src, ip4 dst, { wolfIP_esp_sa * new_sa = NULL; - if (esp_spi_valid(spi) < 0) { + if (esp_spi_valid(spi, 1) < 0) { return -1; } @@ -1356,7 +1358,7 @@ esp_transport_unwrap(struct wolfIP_ip_packet *ip, uint32_t * frame_len) memcpy(&seq, ip->data + ESP_SPI_LEN, sizeof(seq)); seq = ee32(seq); - if (esp_spi_valid(spi) < 0) { + if (esp_spi_valid(spi, 1) < 0) { return -1; } @@ -1366,7 +1368,7 @@ esp_transport_unwrap(struct wolfIP_ip_packet *ip, uint32_t * frame_len) * - The spi must always match. * */ for (size_t i = 0; i < in_sa_num; ++i) { - if (esp_spi_valid(out_sa_list[i].spi) < 0) { + if (esp_spi_valid(in_sa_list[i].spi, 0) < 0) { /* skip empty slots */ continue; } @@ -1596,7 +1598,7 @@ esp_transport_wrap(struct wolfIP_ip_packet *ip, uint16_t * ip_len) /* todo: priority, proto / port filtering. currently this grabs * the first dst and src match. */ for (size_t i = 0; i < out_sa_num; ++i) { - if (esp_spi_valid(out_sa_list[i].spi) < 0) { + if (esp_spi_valid(out_sa_list[i].spi, 0) < 0) { /* skip empty slots */ continue; } From 552b3e6b41e1ec8ff54d5222b85c6b4ee44c904f Mon Sep 17 00:00:00 2001 From: jordan Date: Wed, 3 Jun 2026 16:51:50 -0500 Subject: [PATCH 4/4] esp: add missing END_TEST to unit_est. --- src/test/unit/unit_esp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/unit/unit_esp.c b/src/test/unit/unit_esp.c index 4336c7e9..755495fd 100644 --- a/src/test/unit/unit_esp.c +++ b/src/test/unit/unit_esp.c @@ -1090,6 +1090,7 @@ START_TEST(test_unwrap_ip_filtering) ret = esp_transport_unwrap(ip, &frame_len); ck_assert_int_eq(ret, 0); } +END_TEST /* * full enc/dec round-trips