Creating VoWifi client - IPSec/SAs

First off, sorry if this is the wrong forum or category. Not entirely sure where to ask this.

I have been playing around trying to get a VoWifi client up and running using most of this guide:

I have done most of the guide, except setting up Asterisk. I am not interested in that - I want to create “my own” (web) client, that is doing all the SIP/IMS handling.

  1. StrongSwan is up and running and connected to my carriers ePDG.
  2. I run the first SIP REGISTER call towards the provided P-CSCF IP, and get a 401 response back
  3. Then I run the Authentication parameters up against the USIM and get the (correct) values back
  4. When I then send the next SIP REGISTER call, to the new port provided from the P-CSCF (port-s) with the calcualated values from the SIM card, I get a timeout.

My initial findings was that I needed to set up new Security Associations for the IPSec tunnel. Both for incoming and outgoing connections. And that the P-CSCF drops all packets that are not protected using ESP and the provided SPIs from the initial 401 response (which is why I am getting timeout trying to connect).

Here is what I am trying at this point, which does not work:

  • Connect StrongSwan IPSec tunnel - this is now running in namespace “ims”, as per the guide.
  • Enter the namespace (ip netns exec ims bash)
  • Send the first SIP REGISTER:
REGISTER sip:msg.pc.t-mobile.com SIP/2.0
...
Via: SIP/2.0/TCP [2607:fc20:155:b2e1:ac39:883a:7e67:6830]:5060;branch=z9hG4bK-fc2775db8732f5974970814929dba9be;rport
Contact: <sip:[2607:fc20:155:b2e1:ac39:883a:7e67:6830]:5060>;+g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel";+g.3gpp.smsip;+g.3gpp.srvcc-alerting;+sip.instance="<urn:gsma:imei:35282611-218717-0>";text
Security-Client: ipsec-3gpp;alg=hmac-md5-96;ealg=aes-cbc;mod=trans;port-c=62182;port-s=54350;prot=esp;spi-c=3404407405;spi-s=1890521255,ipsec-3gpp;alg=hmac-md5-96;ealg=null;mod=trans;port-c=62182;port-s=54350;prot=esp;spi-c=3404407405;spi-s=1890521255,ipsec-3gpp;alg=hmac-sha-1-96;ealg=aes-cbc;mod=trans;port-c=62182;port-s=54350;prot=esp;spi-c=3404407405;spi-s=1890521255,ipsec-3gpp;alg=hmac-sha-1-96;ealg=null;mod=trans;port-c=62182;port-s=54350;prot=esp;spi-c=3404407405;spi-s=1890521255
...

I send that to: fd00:976a:14fe:31::5 on port 5060 (P-CSCF IP)

  • Then I get a 401 response back, with the following Security-Server header:
    Security-Server: ipsec-3gpp;q=0.5;alg=hmac-sha-1-96;prot=esp;mod=trans;ealg=aes-cbc;spi-c=968410622;spi-s=968410623;port-c=65528;port-s=65529

If I understand it correctly, I have to use the SPI values to create a pair of IPSec Security Associations. Incoming on my provided port-c (62182) with my provided spi-c (3404407405 / 0xcaeb226d), and outgoing on their port-s (65529) with their provided spi-s (968410623 / 0x39b8c5ff).
This is what I can gather is the way to do that:

# Outgoing 
ip -6 xfrm state add src 2607:fc20:155:b2e1:ac39:883a:7e67:6830 dst fd00:976a:14fe:31::5 proto esp spi 0x39b8c5ff \
     mode transport \
     enc "cbc(aes)" (enc key from "outgoing" in 'ip xfrm state' of main IPSec tunnel) \
     auth "hmac(sha1)" (auth key from "outgoing" in 'ip xfrm state' of main IPSec tunnel) \
     reqid 2
# Incoming
ip -6 xfrm state add src fd00:976a:14fe:31::5 dst 2607:fc20:155:b2e1:ac39:883a:7e67:6830 proto esp spi 0xcaeb226d \
     mode transport \
     enc "cbc(aes)" (enc key from "incoming" in 'ip xfrm state' of main IPSec tunnel) \
     auth "hmac(sha1)" (auth key from "incoming" in 'ip xfrm state' of main IPSec tunnel) \
     reqid 2
# Outgoing
ip -6 xfrm policy add src 2607:fc20:155:b2e1:ac39:883a:7e67:6830/128 dst fd00:976a:14fe:31::5/128 proto tcp sport 62182 dport 65529 dir out \
     tmpl src 2607:fc20:155:b2e1:ac39:883a:7e67:6830 dst fd00:976a:14fe:31::5 proto esp spi 0x39b8c5ff mode transport reqid 2
# Incoming
ip -6 xfrm policy add src fd00:976a:14fe:31::5/128 dst 2607:fc20:155:b2e1:ac39:883a:7e67:6830/128 proto tcp sport 65529 dport 62182 dir in \
     tmpl src fd00:976a:14fe:31::5 dst 2607:fc20:155:b2e1:ac39:883a:7e67:6830 proto esp spi 0xcaeb226d mode transport reqid 2

After having run those commands, I run the USIM RAND/AUTN Auth and calculate the “res”. With the final request assembled, I try to create a TCP connection to fd00:976a:14fe:31::5 on port 65529, binding locally on port 62182, but I get a timeout.

“ip xfrm monitor” shows:

Async event  (0x20)  timer expired
	src 2607:fc20:155:b2e1:ac39:883a:7e67:6830 dst fd00:976a:14fe:31::5  reqid 0x2 protocol esp  SPI 0x39b8c5ff

I am a little unsure where I am going wrong. From a tcpdump on my iphone, using the same SIM, I can see that the SPI used for UE → P-CSCF is the “spi-s” value from the headers. Doing a tcpdump on the linux box, on “tun23” in “ims” namespace, it’s doing the same - using the spi-s for the ESP packet. But it feels like it’s getting dropped somewhere. My knowledge with IPSec is limited, but I am very interested in the inner workings of it - but find the documentation a bit lacking when it comes to IPSec and IMS/SIP.

tl;dr:
I try to establish Security Associations doing a IMS registration. Not sure if I am adding the states and policies in the correct places as I am getting a timeout when trying to connect to the P-CSCF on the provided port-s.

Hope someone can nudge me in the right direction! Thanks in advance

1 Like

Hi Thomas,

we didn’t appear to have a matching category in the forum yet, so I now created one and moved your post to it.

1 Like

So for anyone curious - I was able to establish the correct SAs and finally able to connect.

I was using the encryption and authentication keys from the IPSec tunnel for the SAs - that is incorrect. When performing RAND and AUTN auth on the usim, the provided ck and ik must be used as enc and auth keys for the SAs.

The "auth key is the IK value, and the "enc key is the CK value.

After setting correct keys, I was able to connect on the “port_s” on the P-CSCF.

2 Likes

reference implementation, see GitHub - amitv87/IMSClient: IMS client with SWu (VoWiFi) protocol. Fully PHP implementation.

but, currently is unavailable