Checksum (ESP ICV) with Extended Sequence Number (ESN) incorrectly computed
Summary
The Integrity Check Value (ICV) for ESP Packets are incorrectly computed if the IPSec connection is negotiated with Extended Sequence Numbers (ESN) See https://datatracker.ietf.org/doc/html/rfc4303
Sample capture file
esp-sa-with-esn.zip The file contains two .pcap files, the Strongswan configuration needed to reproduce the issue, and two bitmaps with the ESP SAs settings
Steps to reproduce
Testbed configuration: two Ubuntu 22.04.3 LTS virtual machines
Strongswan 5.9.13 (latest version available)
tcpdump version 4.99.1
libpcap version 1.10.1 (with TPACKET_V3)
OpenSSL 3.0.2 15 Mar 2022
Server ip: 192.168.1.221
Client ip: 192.168.1.116
An extra ip 10.1.0.99 is added on the server to the ens3 interface, to have an IP to ping over the IPSec tunnel
Strongswan is configured like in this example https://docs.strongswan.org/docs/5.9/config/quickstart.html#_roadwarrior_case
I attached the two files server-swanctl.conf and client-swanctl.conf
On the client, initiate the ipsec connection to the server:
swanctl --initiate --ike home
root@konnektor-ms:~# swanctl --list-sa home:
#1 (closed), ESTABLISHED, IKEv2, 0676616dabeafbbb_i* f06d3de246bfbc6c_r
local 'carol.strongswan.org' @ 192.168.1.116[4500]
remote 'moon.strongswan.org' @ 192.168.1.221[4500] AES_CBC-256/HMAC_SHA2_256_128/PRF_HMAC_SHA2_256/MODP_2048 established 3s ago, rekeying in 13312s
home:
#1 (closed), reqid 1, INSTALLED, TUNNEL, ESP:AES_CBC-256/HMAC_SHA2_256_128/ESN installed 3s ago, rekeying in 3390s, expires in 3957s in c92b17f3, 0 bytes, 0 packets out c2f28ade, 0 bytes, 0 packets local 192.168.1.116/32 remote 10.1.0.0/16
root@konnektor-ms:~# ip xfrm state
src 192.168.1.116 dst 192.168.1.221
proto esp spi 0xc2f28ade reqid 1 mode tunnel
replay-window 0 flag af-unspec esn
auth-trunc hmac(sha256) 0x86a53c58d31eca244ced9220108c4b33026ad949449e99ee16c5d3800af9e5f5 128
enc cbc(aes) 0x48ab767bb96c1d2668081dad678467b75976c53ecada5690e7c21ec1f93854d6
anti-replay esn context: seq-hi 0x0, seq 0x0, oseq-hi 0x0, oseq 0x0 replay_window 1, bitmap-length 1 00000000
src 192.168.1.221 dst 192.168.1.116
proto esp spi 0xc92b17f3 reqid 1 mode tunnel
replay-window 0 flag af-unspec esn
auth-trunc hmac(sha256) 0xdafca95a395adb060c7d87e336f17e3cdead400d4db9e8568e9bcc76cee17322 128
enc cbc(aes) 0x29f17ae1fc357bd13954099577784268cd088799e5123797bb929ae19f55ec13
anti-replay esn context: seq-hi 0x0, seq 0x0, oseq-hi 0x0, oseq 0x0 replay_window 32, bitmap-length 1 00000000
on the server, capture the ESP packets
tcpdump -i ens3 ip proto 50 -w esp-with-esn.pcap
on the client, ping the extra IP on the server
root@konnektor-ms:~# ping -c 3 10.1.0.99 -s 37
PING 10.1.0.99 (10.1.0.99) 37(65) bytes of data.
45 bytes from 10.1.0.99: icmp_seq=1 ttl=64 time=1.53 ms
45 bytes from 10.1.0.99: icmp_seq=2 ttl=64 time=1.32 ms
45 bytes from 10.1.0.99: icmp_seq=3 ttl=64 time=1.27 ms
--- 10.1.0.99 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms
The ESP communication is working (ICMP requests are sent and the replies received). This means both instances of Strongswan, client and server, compute the checksums correctly.
Open the attached esp-with-esn.pcap in Wireshark In Preferences/Protocols/ESP check all 4 options, in particular “Attempt to check ESP Authentication”
In ESP SAs, enter the information from "ip xfrm above", to decrypt the ESP packets. See attached bitmap esp-sa-with-esn.jpg
The 6 ESP packets are now decrypted and displayed as ICMP
What is the current bug behavior?
For all 6 ICMP packets, in Encapsulated Security Payload, the ESP ICV is marked as “Incorrect”
[Good: False] [Bad: True]
I think the ICV are computed correctly in Strongswan (otherwise the ICMP packets would be discarded), but in Wireshark only the lower 32 bits of the Sequence Number are used to compute the ICV
What is the expected correct behavior?
To verify that the packets can be decrypted and the ICV computed, without ESN (extended Sequence numbers):
On the same two Strongswan servers, modify the configuration so Extended Sequence Numbers are not used:
esp_proposals = aes256-sha256-modp2048-esn
instead of
esp_proposals = aes256-sha256-modp2048
Restart strongswan, capture the ESP packets on the server
tcpdump -i ens3 host 192.168.1.116 -w esp-no.esn.pcap
on the client, ping the extra server IP
root@konnektor-ms:~# ping -c 3 10.1.0.99 -s 37
PING 10.1.0.99 (10.1.0.99) 37(65) bytes of data.
45 bytes from 10.1.0.99: icmp_seq=1 ttl=64 time=1.45 ms
45 bytes from 10.1.0.99: icmp_seq=2 ttl=64 time=1.05 ms
45 bytes from 10.1.0.99: icmp_seq=3 ttl=64 time=1.14 ms
--- 10.1.0.99 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms
Enter the information from "ip xfrm state" in ESP SAs to decrypt the ESP packages. The ESP ICV is marked "correct" for all 6 ICMP packets
root@konnektor-ms:~# ip xfrm state
src 192.168.1.116 dst 192.168.1.221
proto esp spi 0xc643a54c reqid 1 mode tunnel
replay-window 0 flag af-unspec
auth-trunc hmac(sha256) 0x1f85409fcbb88485281b5d65f419a7cf6a25c814c73208869f6348dd9353ca5a 128
enc cbc(aes) 0xfeb791166fb7e05d31859198f00dc1c6153d1a061f48d2843b0de7eb651cc0aa
anti-replay context: seq 0x0, oseq 0x3, bitmap 0x00000000
src 192.168.1.221 dst 192.168.1.116
proto esp spi 0xcb17e7b2 reqid 1 mode tunnel
replay-window 32 flag af-unspec
auth-trunc hmac(sha256) 0xf7c167bd74fbc7254d4708e7f831754a23d895800d2828861eb4ce011456dfcf 128
enc cbc(aes) 0x1db4e517bc366a20c00657765d5e185036bda30fdcbc2b82deff7a8fdcb3a34f
anti-replay context: seq 0x3, oseq 0x0, bitmap 0x00000007
Build information
Version 4.2.3 (v4.2.3-0-ga15d7331476c).
Compiled (64-bit) using Microsoft Visual Studio 2022 (VC++ 14.37, build 32822),
with GLib 2.78.0, with Qt 6.5.3, with libpcap, with zlib 1.3.0, with PCRE2, with
Lua 5.2.4 (with UfW patches), with GnuTLS 3.8.3 and PKCS #11 support, with
Gcrypt 1.10.2-unknown, with Kerberos (MIT), with MaxMind, with nghttp2 1.57.0,
with nghttp3 1.0.0, with brotli, with LZ4, with Zstandard, with Snappy, with
libxml2 2.11.5, with libsmi 0.5.0, with QtMultimedia, with automatic updates
using WinSparkle 0.8.0, with AirPcap, with Minizip, with binary plugins.
Running on 64-bit Windows 11 (22H2), build 22621, with Intel(R) Core(TM)
i5-8365U CPU @ 1.60GHz (with SSE4.2), with 15710 MB of physical memory, with
GLib 2.78.0, with Qt 6.5.3, without Npcap or WinPcap, with PCRE2 10.42
2022-12-11, with c-ares 1.19.0, with GnuTLS 3.8.3, with Gcrypt 1.10.2-unknown,
with nghttp2 1.57.0, with nghttp3 1.0.0, with brotli 1.0.9, with LZ4 1.9.3, with
Zstandard 1.5.2, without AirPcap, with light display mode, with HiDPI, with QPA
plugin "windows", with LC_TYPE=German_Germany.utf8, binary plugins supported.