1.2.1. Storing private keys in Hardware Secure Modules (HSM)

1.2.1.1. Background

ROS 2 Security is implemented by means of the DDS Security specification. Specifically, when using Vulcanexus, security is implemented through Fast DDS security plugins. The security files required by the aforementioned specification are encapsulated within the ROS 2 security enclaves. This approach allows to set different security policies for different nodes, processes, users, or devices by defining different enclaves with their corresponding permissions. However, ROS 2 currently requires that the private key used to encrypt and decrypt the enclave information is also stored within the enclave as plain text, which might pose a security vulnerability. Such vulnerability can be mitigated through the use of Hardware Security Modules (HSM). These modules provide a query API compliant with the PKCS #11 standard for which Vulcanexus Core (through Fast DDS) provides the required support so the private keys, instead of being stored in the filesystem, could be kept inside HSM devices.

This tutorial provides step-by-step instructions to secure the communications within the ROS 2 talker/listener demo by the means of a HSM and leveraging Vulcanexus Core enhanced security capabilities.

1.2.1.2. Prerequisites

This tutorial does not require a physical HSM device connected to the test environment. Instead, a software HSM emulator is going to be installed and used. Run the following commands to install the required packages (administrative privileges may be required):

apt update
apt install --yes --no-install-recommends \
  softhsm2 \
  gnutls-bin

Note that softhsm2 package creates a new group called softhsm. In order to grant access to the HSM module, non-root users must belong to this group (root users already have permission). To add a user to the group, run the following command (administrative privileges may be required):

usermod -a -G softhsm <user>

For this command to take effect, the user should log out and in again into its account.

Please, also remember to source the environment in every terminal in this tutorial.

source /opt/vulcanexus/humble/setup.bash

1.2.1.3. ROS 2 Security infrastructure

First of all, the required security enclaves to run this tutorial has to be generated using the ROS 2 CLI. Two security enclaves are going to be generated in this tutorial, one for the talker node and the other for the listener. ROS 2 enclaves are saved within a keystore generated running the following commands:

mkdir ~/vulcanexus_hsm_ws && cd ~/vulcanexus_hsm_ws
ros2 security create_keystore vulcanexus_demo_keystore
ros2 security create_enclave vulcanexus_demo_keystore /talker_listener/talker
ros2 security create_enclave vulcanexus_demo_keystore /talker_listener/listener

For more information about ROS 2 security infrastructure, please refer to this tutorial.

1.2.1.4. Generate HSM token

In this step, the private keys that have been generated by ROS 2 CLI in each enclave are going to be imported into virtual HSM tokens for later retrieval by Vulcanexus when necessary using PKCS #11. Therefore, the key.pem auto-generated files within each enclave are going to be replaced by a key.p11 file with the PKCS #11 URI in it. As already explained, this tutorial emulates the HSM using softHSM. Generate the HSM tokens running (administrative privileges may be required):

softhsm2-util --init-token --free --label vulcanexus_demo_talker --pin VulcanexusDemoTalker --so-pin VulcanexusDemoTalker
softhsm2-util --init-token --free --label vulcanexus_demo_listener --pin VulcanexusDemoListener --so-pin VulcanexusDemoListener

As the private keys have already been generated by ROS 2 CLI, this demo is going to directly import these keys into the HSM tokens (administrative privileges may be required).

softhsm2-util --import vulcanexus_demo_keystore/enclaves/talker_listener/talker/key.pem --token vulcanexus_demo_talker --label key --pin VulcanexusDemoTalker --id 123456789ABCDEF123456789ABCDEF
softhsm2-util --import vulcanexus_demo_keystore/enclaves/talker_listener/listener/key.pem --token vulcanexus_demo_listener --label key --pin VulcanexusDemoListener --id 123456789ABCDEF123456789ABCDEF

Once the tokens have been initialized, the auto-generated private keys can be safely removed from the filesystem.

rm -rf vulcanexus_demo_keystore/enclaves/talker_listener/talker/key.pem
rm -rf vulcanexus_demo_keystore/enclaves/talker_listener/listener/key.pem

The PKCS #11 URI with the HSM information has to be stored in the key.p11 file. When inquiring the HSM emulator for the stored tokens, the pin is going to be required. Either set the GNUTLS_PIN environment variable with the pin or enter it when asked by the tool. Run the following commands to extract the required URIs and save them automatically to the files (administrative privileges may be required):

GNUTLS_PIN=VulcanexusDemoTalker p11tool --provider /usr/lib/softhsm/libsofthsm2.so --list-tokens --login | grep "token=vulcanexus_demo_talker" | awk '{print $2}' > vulcanexus_demo_keystore/enclaves/talker_listener/talker/key.p11
GNUTLS_PIN=VulcanexusDemoListener p11tool --provider /usr/lib/softhsm/libsofthsm2.so --list-tokens --login | grep "token=vulcanexus_demo_listener" | awk '{print $2}' > vulcanexus_demo_keystore/enclaves/talker_listener/listener/key.p11

Even though the URIs have been saved, the corresponding pins have not been included into the URIs. Two options can be followed:

export FASTDDS_PKCS11_PIN=VulcanexusDemo<Talker|Listener>

1.2.1.5. Execute ROS 2 demo nodes with security

Security in ROS 2 is enabled by means of environment variables as explained in ROS 2 documentation. Remember to correctly setup your environment in each terminal.

source /opt/vulcanexus/humble/setup.bash
export ROS_SECURITY_KEYSTORE=~/vulcanexus_hsm_ws/vulcanexus_demo_keystore
export ROS_SECURITY_ENABLE=true
export ROS_SECURITY_STRATEGY=Enforce

The latest environment variable ensures that if the security files are not correct, ROS 2 will not be initialized.

If the pin is not included in the PKCS #11 URI within the key.p11 file, then remember to also export the following environment variable with the corresponding pin depending on the node being launched:

export FASTDDS_PKCS11_PIN=VulcanexusDemo<Talker|Listener>

Please, remember to also source Vulcanexus installation before launching the following commands.

In the first terminal launch the talker:

ros2 run demo_nodes_cpp talker --ros-args --enclave /talker_listener/talker

In the second terminal launch the listener:

ros2 run demo_nodes_cpp listener --ros-args --enclave /talker_listener/listener

Communication between both nodes is established.

1.2.1.6. Security breach tryout

If a second listener is launched in a third terminal without security (do not set the environment variables but remember to source Vulcanexus installation), this node will not be included into the communication.

source /opt/vulcanexus/humble/setup.bash
ros2 run demo_nodes_cpp listener