Tag Archives: P-CSCF

Kamailio Proxy-CSCF Pull

I had a few headaches getting the example P-CSCF example configs from the Kamailio team to run, recent improvements with the IPsec support and code evolution meant that the example config just didn’t run.

So, after finally working out the changes I needed to make to get Kamailio to function as a P-CSCF, I took the plunge and made my first pull request on the Kamailio project.

And here it is!


It’s now in the master branch, so if you want to setup a P-CSCF using Kamailio, give it a shot, as the example config finally works!

VoLTE / IMS – P-CSCF Assignment

The Proxy-Call Session Control Function is the first network element a UE sends it’s SIP REGISTER message to, but how does it get there?

To begin with our UE connects as it would normally, getting a default bearer, an IP address and connectivity.


If the USIM has an ISIM application on it (or IMS is enabled on the UE using USIM for auth) and an IMS APN exists on the UE for IMS, the UE will set up another bearer in addition to the default bearer.

This bearer will carry our IMS traffic and allow QoS to be managed through the QCI values set on the bearer.

While setting up the bearer the UE requests certain parameters from the network in the Protocol Configuration Options element, including the P-CSCF address.

When setting up the bearer the network responds with this information, which if supported includes the P-CSCF IPv4 &/or IPv6 addresses.

The Message Exchange

We’ll start assuming the default bearer is in place & our UE is configured with the APN for IMS and supports IMS functionality.

The first step is to begin the establishment of an additional bearer for the IMS traffic.

This is kicked off through the Uplink NAS Transport, PDN Connectivity Request from the UE to the network. This includes the IMS APN information, and the UE’s NAS Payload includes the Protocol Configuration Options element (PCO), with a series of fields the UE requires responses from the network. including DNS Server, MTU, etc.

In the PCO the UE also includes the P-CSCF address request, so the network can tell the UE the IP of the P-CSCF to use.

If this is missing it’s because either your APN settings for IMS are not valid, or your device doesn’t have IMS support or isn’t enabling it.(that could be for a few reasons).

Protocol Configuration Options (Unpopulated) used to request information from the Network by the UE

The MME gets this information from the P-GW, and the network responds in the E-RAB Setup Request, Activate default EPS bearer Context Request and includes the Protocol Configuration Options again, this time the fields are populated with their respective values, including the P-CSCF Address;

Once the UE has this setup, the eNB confirms it’s setup the radio resources through the E-RAB Setup Response.

One the eNB has put the radio side of things in place, the UE confirms the bearer assignment has completed successfully through the Uplink NAS Transport, Activate default EPS Bearer Accept, denoting the bearer is now in place.

Now the UE has the IP address(s) of the P-CSCF and a bearer to send it over, the UE establishes a TCP socket with the address specified in the P-CSCF IPv4 or IPv6 address, to start communicating with the P-CSCF.

The SIP REGISTER request can now be sent and the REGISTRATION procedure can begin.

I’ve attached a PCAP of the full exchange here.

I’ve written a bit about the Gm REGISTER procedure and how IPsec is implemented between the UE and the P-CSCF in this post.

If you’re leaning about VoLTE & IMS networks, or building your own, I’d suggest checking out my other posts on the topic.

IMS / VoLTE IPsec on the Gm Interface

For most Voice / Telco engineers IPsec is a VPN technology, maybe something used when backhauling over an untrusted link, etc, but voice over IP traffic is typically secured with TLS and SRTP.

IMS / Voice over LTE handles things a bit differently, it encapsulates the SIP & RTP traffic between the UE and the P-CSCF in IPsec Encapsulating Security Payload (ESP) payloads.

In this post we’ll take a look at how it works and what it looks like.

It’s worth noting that Kamailio recently added support for IPsec encapsulation on a P-CSCF, in the IMS IPSec-Register module. I’ll cover usage of this at a later date.

The Message Exchange

The exchange starts off looking like any other SIP Registration session, in this case using TCP for transport. The UE sends a REGISTER to the Proxy-CSCF which eventually forwards the request through to a Serving-CSCF.

This is where we diverge from the standard SIP REGISTER message exchange. The Serving-CSCF generates a 401 Unauthorized response, containing an authentication challenge in the WWW-Authenticate header, and also a Ciphering Key & Integrity Key (ck= and ik=) also in the WWW-Authenticate header.

The Serving-CSCF sends the Proxy-CSCF the 401 response it created. The Proxy-CSCF assigns a SPI for the IPsec ESP to use, a server port and client port and indicates the used encryption algorithm (ealg) and algorithm to use (In this case HMAC-SHA-1-96.) and adds a new header to the 401 Unauthorized called SecurityServer header to share this information with the UE.

The Proxy-CSCF also strips the Ciphering Key (ck=) and Integrity Key (ik=) headers from the SIP authentication challenge (WWW-Auth) and uses them as the ciphering and integrity keys for the IPsec connection.

Finally after setting up the IPsec server side of things, it forwards the 401 Unauthorized response onto the UE.

Upon receipt of the 401 response, the UE looks at the authentication challenge.

Keep in mind that the 3GPP specs dictate that IMS / VoLTE authentication requires mutual network authentication meaning the UE authenticates the network as well as the network authenticating the UE. I’ve written a bit about mutual network authentication in this post for anyone not familiar with it.

If the network is considered authenticated by the UE it generates a response to the Authentication Challenge, but it doesn’t deliver it over TCP. Using the information generated in the authentication challenge the UE encapsulates everything from the network layer (IPv4) up and sends it to the P-CSCF in an IPsec ESP.

Communication between the UE and the P-CSCF is now encapsulated in IPsec.

Wireshark trace of IPsec IMS Traffic between UE and P-CSCF

If you’re leaning about VoLTE & IMS networks, or building your own, I’d suggest checking out my other posts on the topic.

Using Wireshark to peer inside IPsec ESP VoLTE data from the P-CSCF

IPsec ESP can be used in 3 different ways on the Gm interface between the Ue and the P-CSCF:

  • Integrity Protection – To prevent tampering
  • Ciphering – To prevent inception / eavesdropping
  • Integrity Protection & Ciphering

On Wireshark, you’ll see the ESP, but you won’t see the payload contents, just the fact it’s an Encapsulated Security Payload, it’s SPI and Sequence number.

By default, Kamailio’s P-CSCF only acts in Integrity Protection mode, meaning the ESP payloads aren’t actually encrypted, with a few clicks we can get Wireshark to decode this data;

Just open up Wireshark Preferences, expand Protocols and jump to ESP

Now we can set the decoding preferences for our ESP payloads,

In our case we’ll tick the “Attempt to detect/decode NULL encrypted ESP payloads” box and close the box by clicking OK button.

Now Wireshark will scan through all the frames again, anything that’s an ESP payload it will attempt to parse.

Now if we go back to the ESP payload with SQN 1 I showed a screenshot of earlier, we can see the contents are a TCP SYN.

Now we can see what’s going on inside this ESP data between the P-CSCF and the UE!

As a matter of interest if you can see the IK and CK values in the 401 response before they’re stripped you can decode encrypted ESP payloads from Wireshark, from the same Protocol -> ESP section you can load the Ciphering and Integrity keys used in that session to decrypt them.

If you’re leaning about VoLTE & IMS networks, or building your own, I’d suggest checking out my other posts on the topic.