TL;DR: You can implement FIPS 140-2 VoIP with RFC 3711 media and RFC 4568 signaling using baresip.

This article describes implementing & verifying secure VoIP using the Baresip library. Verification steps avoid intercepting or decrypting transport media, and instead rely on the protocol negotiation parameters of TLS and SIP to ensure compliance.

The intention is to configure a Baresip User Agent to comply with the following standards for secure signaling transport & media:


Our Signaling Cipher Suite is: ECDHE-ECDSA-AES256-GCM-SHA384


Our Media "Crypto-Suite" is: AES_CM_128_HMAC_SHA1_80

Many of these standards are also applicable to the National Information Assurance Program (NIAP) Protection Profile (PP) for Voice over IP (VoIP).


Voice over IP (VoIP) is a broad term that can refer to any method of transmitting voice communications over an IP network. When implemented out-of-the-box, the most common VoIP protocol, SIP, lacks any security provisions for this these voice communications. Fortunately the flexibility of SIP allows for enhancements that provide a level of security, and when configured correctly, allows the protocol to meet certain standards of security as selected by the US Government, et al.

We'll work through the following steps to build an environment that applies these enhancements to a Baresip UA, and ensure the environment meets certain security standards:

  1. Generate a compliant client & server security certificate.
  2. Compile & Run the baresip UA with the security parameters set.
  3. Simulate a remote SIP endpoint using OpenSSL's s_client & s_server.
  4. Verify the exchange between OpenSSL & Baresip.



SIP, by default, passes traffic unencrypted over UDP on port 5060. When used RTP transport, the media is also passed in unencrypted UDP (typically on a random port). We're going to encrypt our media using SDES-SRTP, and wrap our SIP signaling in TLS over TCP on port 5061. This ensures that bout our voice traffic, as well as the keys used to encrypt that voice traffic, is secure.

To enable SIP over TLS with Baresip, we'll need to configure the Baresip UA with a Cert. Once configured, Baresip will be capable of sending and receiving calls over SIP TLS on port 5061.

All of these steps can take place on a single TW running both Baresip & the Simulated SIP Send & Receive Endpoints

These steps are broken down as follows:

Certificate Generation

An end-user would be expected to generate (or provide) their own Cert for use by their UA, but for this example we'll generate our own self-signed Cert.

We're also going to generate our own ECPK using P-384.

Generate an ECPK using P-384

This section describes the process of generating an ECPK using P-384 on the TW. Additional prerequisite steps are provided to ensure the TW is capable of generating ECPKs using P-384.

All of the commands in this section must be executed on the same TW.


The following steps verify the OpenSSL library on the TW is (1) installed and (2) capable of generating an ECPK using P-384:

  1. Ensure OpenSSL's command-line tool 'openssl' is installed:
    The command:
    $ openssl version && echo ''openssl' installed!'
    Should return:
    openssl installed!
  2. Ensure OpenSSL includes support for the P-384:
    The command:
    $ openssl ecparam -list_curves|grep secp384r1
    Should return:
    secp384r1 : NIST/SECG curve over a 384 bit prime field


  1. Generate an ECPK using P-384.
    The command:
    $ openssl ecparam -genkey -name secp384r1 -param_enc explicit -out example.key -param_enc named_curve
    Should create the file ‘example.key’, as verified with the command:
    $ ls example.key
    Should return:


  1. Display the curve used to create the ECPK.
    The command:
    $ openssl ecparam -in example.key -text -noout
    Should return:
    ASN1 OID: secp384r1
    NIST CURVE: P-384

Create a Self-Signed Cert using an ECPK with P-384


  1. Create the Cert using the OpenSSL command-line tool 'openssl':
    The command:
    $ openssl req -x509 -new -sha384 -days 30 -nodes -key example.key -out example.cert -subj "/C=US/ST=California/L=San Francisco/O=Example Co./OU=IT/"
    Should create the file ‘example.cert', as verified with the command:
    $ ls example.cert
    Should return:

Create a combined PEM file

Baresip requires the Cert be provided in PEM format, with the Cert & ECPK concatenated together into a single file:
The command:
$ cat example.key example.cert > example.pem
Should create the file ‘example.pem’, as verified with the command:
$ ls example.pem
Should return:

Build & Run Baresip UA

Baresip requires the libre and librem libraries as well as a complete build environment. For simplicity, we're going to use a Docker container to build and run the UA.

  1. Create a Dockerfile with the following content:

    FROM python:3-buster
    WORKDIR /baresip-docker
    RUN git clone && \
      cd re && \
      make RELEASE=yes install
    RUN git clone && \
      cd rem && \
      make install
    RUN git clone && \
      cd baresip && \
      make USE_TLS=yes USE_SRTP=yes install
    RUN ldconfig
    EXPOSE 5061
    CMD ["baresip", "-f", "/dev_volume"]
  2. Create an accounts file with the following content:;regint=0;transport=tls;mediaenc=srtp-mand;answermode=early
  3. Create a config file with the following content:

    module_path /usr/local/lib/baresip/modules
    sip_certificate /dev_volume/example.pem
  4. Build the container: $ docker build -t baresip-docker .

  5. Run the container: $ docker run -itv $(pwd):/dev_volume baresip-docker:latest baresip -f /dev_volume
  6. With the Baresip UA running, you should see the following output:
    baresip v1.0.0 Copyright (C) 2010 - 2020 Alfred E. Heggestad et al.
    Local network address:  IPv4=eth0|
    SIP Certificate: /dev_volume/example.pem
    Populated 0 contacts
    aucodec: PCMU/8000/1
    aucodec: PCMA/8000/1
    mediaenc: srtp
    mediaenc: srtp-mand
    mediaenc: srtp-mandf Using media encryption 'srtp-mand'
    Populated 1 account
    Populated 2 audio codecs
    Populated 0 audio filters
    Populated 0 video codecs
    Populated 0 video filters
    baresip is ready.

Notice that the UA has enabled SRTP for our account: Using media encryption 'srtp-mand'

Test & Verify Configuration

Sending (originating) a Call from the Baresip UA

We're going to use the same Cert & ECPK we created for the Baresip UA with the Simulated Receiver. The Simulated Receiver will allow the Baresip UA to create a TLS connection and send an initial SDP with SDES, with those connection parameters output in a manner viewable by the tester.

The command:
$ openssl s_server -accept 5071 -cert example.cert -key example.key -cipher ECDHE-ECDSA-AES256-GCM-SHA384 -named_curve secp384r1 -no_dhe

Should return:

    Using default temp ECDH parameters


These steps assume the Baresip UA is running on host, and the Simulated Receiver is running on host

  1. On the Baresip UA, dial our Simulated Receiver: /dial sip:b@;transport=tls;mediaenc=srtp-mand
  2. On the Simulated Receiver you should see the following output:
    Secure Renegotiation IS supported
    INVITE sip:xb192.168.1.2:5071;transport=tls;mediaenc=srtp-mand SIP/2.0
    Via: SIP/2.0/TLS;branch=z9hG4bKc141b65f66cd0e02;rport
    Contact: <sip:user-0x55dc09027150@;transport=tls>
    Max-Forwards: 70
    To: <sip:b@;transport=tls;mediaenc=srtp-mand>
    From: <>;tag=0a94555cd2c228dd
    Call-ID: f9595791e9191927
    CSeq: 59280 INVITE
    User-Agent: baresip v1.0.0 (x86_64/linux)
    Content-Type: application/sdp
    Content-Length: 429
    o=- 1975181172 1106161735 IN IP4
    c=IN IP4
    t=0 0
    a=tool:baresip 1.0.0
    m=audio 16796 RTP/SAVP 0 8 101
    a=rtpmap:0 PCMU/8000
    a=rtpmap:8 PCMA/8000
    a=rtpmap:101 telephone-event/8000
    a=fmtp:101 0-15
    a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:vXMep/SIW4iMD21StWgrmy024dJZfOAM7qFFJfsJ

This output ensures the system meets the following standards:



Receiving a Call in Baresip UA

We're going to use the same Cert & ECPK we created for the Baresip UA with the Simulated Sender. This will allow the Baresip UA to receive a TLS connection, and output the connection parameters in a manner viewable by the tester.


  1. On the host acting as the Simulated Sender, run the following command:
    $ openssl s_client -connect localhost:5061 -cert example.cert -key example.key -cipher ECDHE-ECDSA-AES256-GCM-SHA384 -groups P-384
  2. This will provide the following output:
    depth=0 C = US, ST = California, L = San Francisco, O = Example Co., OU = IT, CN =
    verify error:num=18:self signed certificate
    verify return:1
    depth=0 C = US, ST = California, L = San Francisco, O = Example Co., OU = IT, CN =
    verify return:1
    Certificate chain
     0 s:/C=US/ST=California/L=San Francisco/O=Example Co./OU=IT/
       i:/C=US/ST=California/L=San Francisco/O=Example Co./OU=IT/
    Server certificate
    -----END CERTIFICATE-----
    subject=/C=US/ST=California/L=San Francisco/O=Example Co./OU=IT/
    issuer=/C=US/ST=California/L=San Francisco/O=Example Co./OU=IT/
    No client certificate CA names sent
    Server Temp Key: ECDH, P-384, 384 bits
    SSL handshake has read 1068 bytes and written 262 bytes
    New, TLSv1/SSLv3, Cipher is ECDHE-ECDSA-AES256-GCM-SHA384
    Server public key is 384 bit
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    No ALPN negotiated
        Protocol  : TLSv1.2
        Cipher    : ECDHE-ECDSA-AES256-GCM-SHA384
        Session-ID: 0966C0600004F9A7DF9F67EF90FAAF412191E5239F38929CE80F495FEDD78352
        Master-Key: AF01D67E554CF8B8BED9732CE8DEFD02C97FFBA9F7B1DF36E7E37163F3E1633250BD9E96FEBB35217BF3FC0ACB1668F8
        TLS session ticket lifetime hint: 7200 (seconds)
        TLS session ticket:
        0000 - 39 65 eb dd 81 b8 07 1f-2b 0e a3 52 c1 c2 3e f1   9e......+..R..>.
        0010 - ba 41 2a 58 6e b0 16 28-56 e5 a4 81 c3 7c a3 ee   .A*Xn..(V....|..
        0020 - 8d ba 7f 4e ff 65 53 ef-be 80 c8 98 ca 12 0a 8c   ...N.eS.........
        0030 - c9 e1 f8 c7 cc d7 f5 6c-8d bc f1 3e 53 09 43 2f   .......l...>S.C/
        0040 - b9 7c 3f 0a 9e 39 30 cf-f2 eb 72 fd f3 51 08 25   .|?..90...r..Q.%
        0050 - f1 4a 58 49 f0 11 c1 75-03 ef 79 93 9f 20 85 ba   .JXI...u..y.. ..
        0060 - d2 80 73 2d 9e 6a 03 7e-a6 38 2c 75 f4 d1 c5 67   ..s-.j.~.8,u...g
        0070 - 44 09 ae f0 7d ad 0e b5-6c b2 3c b0 ca 28 4d 1c   D...}...l.<..(M.
        0080 - e0 04 c9 5e 6b dd 8d e1-a6 81 19 03 c4 b9 77 4b   ...^k.........wK
        0090 - 2f 61 5f 72 2d d7 f9 c0-65 18 30 72 85 10 99 55   /a_r-...e.0r...U
        Start Time: 1594689170
        Timeout   : 7200 (sec)
        Verify return code: 18 (self signed certificate)

This output ensures the system meets the following standards:




blog comments powered by Disqus