IP Security and Hardware Encryption

This chapter includes:

The io-pkt-v4-hc and io-pkt-v6-hc stack variants include full, built-in support for IPsec.

Note: You need to specify the ipsec parameter option to the stack in order to enable IPsec when the stack starts.

There's a good reference page in the NetBSD man pages covering IPsec in general. There are some aspects that don't apply (you obviously don't have to worry about rebuilding the kernel), but the general usage is the same.

Setting up an IPsec connection: examples

The following examples illustrate how to set up IPsec:

Between two boxes manually

Suppose we have two boxes, A and B, and we want to establish IPsec between them. Here's how:

  1. On each box, create a script file (let's say its name is my_script) having the following content:
    # args: This script takes two arguments:
    #    - The first one is the IP address of the box that is to
    #      run it on.  
    #    - The second one is the IP address of the box that this
    #      box is to establish IPsec connection to.
    # The following two lines are to clean the database.
    # They're here simply to demonstrate the "hello world" level
    # connection.
    setkey -FP
    setkey -F
    # Use setkey to input all of the SA content.
    setkey -c << EOF
    spdadd $Myself $Remote any -P out ipsec esp/transport/$Myself-$Remote/require;
    spdadd $Remote $Myself any -P in ipsec esp/transport/$Remote-$Myself/require;
    add  $Myself $Remote esp 1234 -m any -E 3des-cbc "KeyIsTwentyFourBytesLong";
    add  $Remote $Myself esp 1234 -m any -E 3des-cbc "KeyIsTwentyFourBytesLong";
  2. On BoxA, run ./my_script BoxA BoxB, or give the IP address of each box if the name can't be resolved.
  3. Similarly, on BoxB, run ./my_script BoxB BoxA.

Now you can check the connection by pinging each box from the other. You can get the IPsec status by using setkey -PD.

With authentication using the preshared-key method

Consider the simplest case where there are two boxes, BoxA and BoxB. User A is on BoxA, User B is on Box B, and the two users have a shared secret, which is a string of hello_world.

  1. On Box A, create a file, psk.txt, that has these related lines:
    usera@qnx.com   "Hello_world"
    userb@qnx.com   "Hello_world"

    The IPsec IKE daemon, racoon, will use this file to do the authentication and IPsec connection job.

  2. The root user must own psk.txt and the file's permissions must be read/write only by root. To ensure this is the case, run:
    chmod 0600 psk.txt
  3. The racoon daemon needs a configuration file (e.g. racoon.conf) that defines the way that racoon is to operate. In the remote session, specify that we're going to use the preshared key method as authentication and let racoon know where to find the secret. For example:
    # Let racoon know where your preshared keys are:
    path pre_shared_key "your_full_path_to_psk.txt" ;
    remote anonymous
        exchange_mode aggressive,main;
        doi ipsec_doi;
        situation identity_only;
        #my_identifier address;
        my_identifier user_fqdn "usera@qnx.com";
        peers_identifier user_fqdn "userb@qnx.com";
        nonce_size 16;
        lifetime time 1 hour;   # sec,min,hour
        initial_contact on;
        proposal_check obey;    # obey, strict or claim
        proposal {
            encryption_algorithm 3des;
            hash_algorithm sha1;
            authentication_method pre_shared_key ;
            dh_group 2 ;
  4. Set up the policy using setkey. You can use the following script (called my_script) to tell the stack that the IPsec between BoxA and BoxB requires key negotiation:
    # This is a simple configuration for testing racoon negotiation.
    setkey -FP
    setkey -F
    setkey -c << EOF
    spdadd $Remote $Myself any -P in  ipsec esp/transport/$Remote-$Myself/require;
    spdadd $Myself $Remote any -P out ipsec esp/transport/$Myself-$Remote/require;

    Run this on BoxA as ./my_script BoxA BoxB.

  5. Repeat the above steps on BoxB. Needless to say, on BoxB you need to run as ./my_script BoxB BoxA (and so on).
  6. On both boxes, run racoon -c full_path_to_racoon.conf. When you initiate traffic, say by trying to ping the peer box, racoon will do its job and establish the IPsec connection by creating Security Associations (SAs) for both directions, and then you can see the traffic passing back and forth, which indicates that the IPsec connection is established.

IPsec tools

The Neutrino Core Networking uses the IPsec tools from the NetBSD source base and incorporates it into its source base. The tools include:

PF_KEY library routines.
Security Policy Database and Security Association Database management tool.
IKE key-management daemon. This utility is available only in binary form on request. Under encryption export law, we must track to whom we send this technology and report the information to the US government.
A command-line tool that controls racoon.

OpenSSL support

We've ported the OpenSSL crypto and SSL libraries (from http://www.openssl.org) for your applications to use.

Hardware-accelerated crypto

The io-pkt-v4-hc and io-pkt-v6-hc managers have the (hardware-independent) infrastructure to load a (hardware-dependent) driver to take advantage of dedicated hardware that can perform cryptographic operations at high speed. This not only speeds up the crypto operations (such as those used by IPsec), but also reduces the CPU load.

This interface is carefully crafted so that the stack doesn't block on the crypto operation; rather, it continues, and later on, using a callback, the driver returns the processed data to the stack. This is ideal for DMA-driven crypto hardware.

Supported hardware crypto engines

The MPCSEC crypto hardware core (present on the E-series PowerQUICC III and PowerQUICC-II PRO series of processors from Freescale) is supported by the devnp-mpcsec.so driver. This driver loads just like a standard Ethernet driver from the command line:

# io-pkt-v6-hc -d mpcsec -d mpc85xx

where devnp-mpc85xx.so is the Ethernet driver for the Freescale TSEC (Triple Speed Ethernet Controller) hardware block.