@@ -129,12 +129,62 @@ static uint32_t build_ip_packet(uint8_t *buf, size_t buf_size,
129129 return frame_len ;
130130}
131131
132+ static uint32_t build_udp_ip_packet (uint8_t * buf , size_t buf_size ,
133+ uint32_t src_ip , uint32_t dst_ip ,
134+ uint16_t src_port , uint16_t dst_port ,
135+ const uint8_t * payload , uint16_t payload_len )
136+ {
137+ struct wolfIP_ip_packet * ip ;
138+ struct wolfIP_udp_datagram * udp ;
139+ uint32_t frame_len ;
140+ uint16_t udp_len = (uint16_t )(UDP_HEADER_LEN + payload_len );
141+
142+ frame_len = build_ip_packet (buf , buf_size , WI_IPPROTO_UDP , NULL , udp_len );
143+ ip = (struct wolfIP_ip_packet * )buf ;
144+ udp = (struct wolfIP_udp_datagram * )ip ;
145+
146+ ip -> src = ee32 (src_ip );
147+ ip -> dst = ee32 (dst_ip );
148+ udp -> src_port = ee16 (src_port );
149+ udp -> dst_port = ee16 (dst_port );
150+ udp -> len = ee16 (udp_len );
151+ udp -> csum = 0 ;
152+ if (payload_len > 0U ) {
153+ memcpy (udp -> data , payload , payload_len );
154+ }
155+ ip -> csum = 0 ;
156+ iphdr_set_checksum (ip );
157+
158+ return frame_len ;
159+ }
160+
132161static void esp_setup (void )
133162{
134163 int ret = wolfIP_esp_init ();
135164 ck_assert_int_eq (ret , 0 );
136165}
137166
167+ static void esp_add_cbc_test_sas (void )
168+ {
169+ int ret ;
170+
171+ ret = wolfIP_esp_sa_new_cbc_hmac (0 , (uint8_t * )spi_rt ,
172+ atoip4 (T_SRC ), atoip4 (T_DST ),
173+ (uint8_t * )k_aes128 , sizeof (k_aes128 ),
174+ ESP_AUTH_SHA256_RFC4868 ,
175+ (uint8_t * )k_auth16 , sizeof (k_auth16 ),
176+ ESP_ICVLEN_HMAC_128 );
177+ ck_assert_int_eq (ret , 0 );
178+
179+ ret = wolfIP_esp_sa_new_cbc_hmac (1 , (uint8_t * )spi_rt ,
180+ atoip4 (T_SRC ), atoip4 (T_DST ),
181+ (uint8_t * )k_aes128 , sizeof (k_aes128 ),
182+ ESP_AUTH_SHA256_RFC4868 ,
183+ (uint8_t * )k_auth16 , sizeof (k_auth16 ),
184+ ESP_ICVLEN_HMAC_128 );
185+ ck_assert_int_eq (ret , 0 );
186+ }
187+
138188/* Creating an HMAC-only SA with valid params must succeed. */
139189START_TEST (test_sa_hmac_good )
140190{
@@ -1278,6 +1328,105 @@ START_TEST(test_wrap_rejects_ip_len_below_header)
12781328}
12791329END_TEST
12801330
1331+ START_TEST (test_ip_recv_esp_transport_delivers_udp_payload )
1332+ {
1333+ static uint8_t buf [LINK_MTU + 256 ];
1334+ struct wolfIP s ;
1335+ struct wolfIP_ip_packet * ip = (struct wolfIP_ip_packet * )buf ;
1336+ struct wolfIP_sockaddr_in sin ;
1337+ uint8_t payload [] = { 'e' , 's' , 'p' , '!' };
1338+ uint8_t rxbuf [sizeof (payload )] = {0 };
1339+ uint32_t frame_len ;
1340+ uint16_t ip_len ;
1341+ int udp_sd ;
1342+ int ret ;
1343+
1344+ wolfIP_init (& s );
1345+ esp_setup ();
1346+ esp_add_cbc_test_sas ();
1347+ wolfIP_ipconfig_set (& s , atoip4 (T_DST ), 0xFFFFFF00U , 0 );
1348+
1349+ udp_sd = wolfIP_sock_socket (& s , AF_INET , IPSTACK_SOCK_DGRAM , WI_IPPROTO_UDP );
1350+ ck_assert_int_gt (udp_sd , 0 );
1351+
1352+ memset (& sin , 0 , sizeof (sin ));
1353+ sin .sin_family = AF_INET ;
1354+ sin .sin_port = ee16 (1234 );
1355+ sin .sin_addr .s_addr = ee32 (atoip4 (T_DST ));
1356+ ck_assert_int_eq (wolfIP_sock_bind (& s , udp_sd , (struct wolfIP_sockaddr * )& sin , sizeof (sin )), 0 );
1357+
1358+ frame_len = build_udp_ip_packet (buf , sizeof (buf ), atoip4 (T_SRC ), atoip4 (T_DST ),
1359+ 4321 , 1234 , payload , sizeof (payload ));
1360+ ip_len = (uint16_t )(frame_len - ETH_HEADER_LEN );
1361+
1362+ ret = esp_transport_wrap (ip , & ip_len );
1363+ ck_assert_int_eq (ret , 0 );
1364+
1365+ frame_len = (uint32_t )ip_len + ETH_HEADER_LEN ;
1366+ ip -> proto = 0x32U ;
1367+ ip -> len = ee16 (ip_len );
1368+ ip -> csum = 0U ;
1369+ iphdr_set_checksum (ip );
1370+
1371+ ip_recv (& s , 0 , ip , frame_len );
1372+
1373+ ret = wolfIP_sock_recvfrom (& s , udp_sd , rxbuf , sizeof (rxbuf ), 0 , NULL , NULL );
1374+ ck_assert_int_eq (ret , (int )sizeof (payload ));
1375+ ck_assert_mem_eq (rxbuf , payload , sizeof (payload ));
1376+ }
1377+ END_TEST
1378+
1379+ START_TEST (test_ip_recv_esp_transport_unwrap_failure_drops_packet )
1380+ {
1381+ static uint8_t buf [LINK_MTU + 256 ];
1382+ struct wolfIP s ;
1383+ struct wolfIP_ip_packet * ip = (struct wolfIP_ip_packet * )buf ;
1384+ struct wolfIP_sockaddr_in sin ;
1385+ uint8_t payload [] = { 'b' , 'a' , 'd' , '!' };
1386+ uint8_t rxbuf [sizeof (payload )] = {0 };
1387+ uint32_t frame_len ;
1388+ uint16_t ip_len ;
1389+ uint32_t esp_len ;
1390+ int udp_sd ;
1391+ int ret ;
1392+
1393+ wolfIP_init (& s );
1394+ esp_setup ();
1395+ esp_add_cbc_test_sas ();
1396+ wolfIP_ipconfig_set (& s , atoip4 (T_DST ), 0xFFFFFF00U , 0 );
1397+
1398+ udp_sd = wolfIP_sock_socket (& s , AF_INET , IPSTACK_SOCK_DGRAM , WI_IPPROTO_UDP );
1399+ ck_assert_int_gt (udp_sd , 0 );
1400+
1401+ memset (& sin , 0 , sizeof (sin ));
1402+ sin .sin_family = AF_INET ;
1403+ sin .sin_port = ee16 (1234 );
1404+ sin .sin_addr .s_addr = ee32 (atoip4 (T_DST ));
1405+ ck_assert_int_eq (wolfIP_sock_bind (& s , udp_sd , (struct wolfIP_sockaddr * )& sin , sizeof (sin )), 0 );
1406+
1407+ frame_len = build_udp_ip_packet (buf , sizeof (buf ), atoip4 (T_SRC ), atoip4 (T_DST ),
1408+ 4321 , 1234 , payload , sizeof (payload ));
1409+ ip_len = (uint16_t )(frame_len - ETH_HEADER_LEN );
1410+
1411+ ret = esp_transport_wrap (ip , & ip_len );
1412+ ck_assert_int_eq (ret , 0 );
1413+
1414+ frame_len = (uint32_t )ip_len + ETH_HEADER_LEN ;
1415+ ip -> proto = 0x32U ;
1416+ ip -> len = ee16 (ip_len );
1417+ ip -> csum = 0U ;
1418+ iphdr_set_checksum (ip );
1419+
1420+ esp_len = frame_len - ETH_HEADER_LEN - IP_HEADER_LEN ;
1421+ ip -> data [esp_len - 1U ] ^= 0xFFU ;
1422+
1423+ ip_recv (& s , 0 , ip , frame_len );
1424+
1425+ ret = wolfIP_sock_recvfrom (& s , udp_sd , rxbuf , sizeof (rxbuf ), 0 , NULL , NULL );
1426+ ck_assert_int_eq (ret , - WOLFIP_EAGAIN );
1427+ }
1428+ END_TEST
1429+
12811430static Suite * esp_suite (void )
12821431{
12831432 Suite * s ;
@@ -1352,6 +1501,11 @@ static Suite *esp_suite(void)
13521501 tcase_add_test (tc , test_ciphertext_tamper_cbc_sha256 );
13531502 suite_add_tcase (s , tc );
13541503
1504+ tc = tcase_create ("ip_recv" );
1505+ tcase_add_test (tc , test_ip_recv_esp_transport_delivers_udp_payload );
1506+ tcase_add_test (tc , test_ip_recv_esp_transport_unwrap_failure_drops_packet );
1507+ suite_add_tcase (s , tc );
1508+
13551509 /* No-SA outbound path */
13561510 tc = tcase_create ("no_sa" );
13571511 tcase_add_test (tc , test_wrap_no_matching_sa );
0 commit comments