As the quantum era approaches, the need for cryptographic systems that can withstand the power of quantum computing becomes increasingly urgent. Current key exchange mechanisms like Elliptic Curve Diffie-Hellman (ECDH) are vulnerable to attacks from quantum computers, which can easily break these algorithms. To address this looming threat, it is critical to incorporate post-quantum key exchanges alongside traditional methods like (EC)DH to ensure that the resulting shared keys are secure against quantum-based attacks. RFC 9370 provides a framework for enhancing the Internet Key Exchange (IKEv2) protocol by enabling multiple successive key exchanges, including Post-Quantum Cryptography (PQC) techniques. This allows for the seamless integration of quantum-resistant algorithms with existing cryptographic protocols, ensuring compatibility while significantly strengthening security. The derived IKEv2 keys, fortified with these advanced techniques, are thus designed to be robust against the unprecedented capabilities of quantum computers.
Qrypt integrated the BLAST protocol and post-quantum algorithms in IKEv2 as additional key exchange methods, providing security against Harvest Now Decrypt Later (HNDL) attacks and future quantum attacks. This solution, is built as an IPsec plug-in that seamlessly combines existing classical and quantum-secure key exchanges with Qrypt’s BLAST protocol. The solution leverages the NVIDIA Bluefield-3 DPU’s hardware capability for secure network communication and optimized performance. Support for the Qrypt plug-in can be easily enabled by configuring the StrongSwan service running on the DPUs.
RFC 9370 extends the Internet Key Exchange Version 2 (IKEv2) protocol to facilitate multiple key exchanges during the establishment of a Security Association (SA). This enhancement allows the computation of a final shared secret derived from multiple component key exchange secrets. Key points include:
There are two primary methods to negotiate additional key exchange algorithms and establish quantum-secure IKE SAs: utilizing IKE_INTERMEDIATE exchanges during the initial Security Association (SA) setup or employing the IKE_FOLLOWUP_KE exchange for subsequent key exchanges. Below is a step-by-step breakdown of each method:
The shared keying material is completed as follows:
SKEYSEED(n) = prf(SK_d(n-1), SK(n) | Ni | Nr)
Where:
Key materials (SK_d, SK_ai, SK_ar, SK_ei, SK_er, SK_pi, SK_pr) are derived from SKEYSEED(n) using the following formula:
{SK_d(n) | SK_ai(n) | SK_ar(n) | SK_ei(n) | SK_er(n) | SK_pi(n) | SK_pr(n)}
= prf+ (SKEYSEED(n), Ni | Nr | SPIi | SPIr)
Both the initiator and responder use these updated keys in the next IKE_INTERMEDIATE or IKE_AUTH exchange.
[Initiator] [Responder]
| |
| ------ IKE_SA_INIT ------> |
| |
|<------ IKE_SA_INIT ------> |
| |
|----- IKE_INTERMEDIATE ---->|
| |
|<----- IKE_INTERMEDIATE --->|
| |
|------- IKE_AUTH ---------> |
| |
|<------- IKE_AUTH --------->|
After the exchanges, both peers compute updated keying materials as follows:
For IKE SA rekey:
SKEYSEED = prf(SK_d, SK(0) | Ni | Nr | SK(1) | ... | SK(n))
For Child SA creation or rekey:
KEYMAT = prf+ (SK_d, SK(0) | Ni | Nr | SK(1) | ... | SK(n))
In both cases, SK_d comes from the existing IKE SA, and the keying material is derived from SK(0), Ni, Nr, and additional shared keys.
[Initiator] [Responder]
| |
| ------ IKE_SA_INIT ------> |
| |
|<------ IKE_SA_INIT ------> |
| |
|------ IKE_AUTH ----------> |
| |
|<------ IKE_AUTH ---------->|
| |
|---- CREATE_CHILD_SA -----> |
| |
|<---- CREATE_CHILD_SA ----->|
| |
|--- IKE_FOLLOWUP_KE ------> |
| |
|<--- IKE_FOLLOWUP_KE ------>|
The choice between using IKE_INTERMEDIATE or IKE_FOLLOWUP_KE exchanges depends on the peers’ security policies. If the initial Child SA must be quantum secure, negotiating additional key exchanges through IKE_INTERMEDIATE exchanges may be preferable.
Qrypt solution leverages RFC9370 specification that describes a method to perform multiple successive key exchanges in IKEv2. Qrypt keys are generated independently on each endpoint, however, to establish the same set of keys, parties must exchange the associated key metadata. Additional IKEv2 key exchanges are used to exchange the metadata.
BLAST is the protocol used to eliminate key transmission and safeguard data against the Harvest Now Decrypt Later (HNDL) attack.
For more information see BLAST
The process starts with IKEv2 negotiating Security Associations (SAs) between the initiator and responder, defining cryptographic parameters like algorithms and key lengths. An SA is uniquely identified by a triplet, which consists of the security parameter index (SPI), destination IP address, and security protocol identifier. An SPI is a 32-bit number. It is transmitted in the AH/ESP header. In IPsec, ESP uses these SAs to secure IP packets by referencing the Security Parameter Index (SPI) to identify the correct SA for each packet.
SA Establishment: During the IKEv2 negotiation, strongSwan establishes SAs between peers, assigning a unique SPI to each SA. This SPI serves as an identifier for the SA’s cryptographic parameters.
Packet Processing: As ESP processes incoming packets, it examines the SPI in each packet’s header. Using this SPI, ESP retrieves the corresponding SA from the Security Association Database (SAD) to apply the correct cryptographic operations.
Receiving a Packet: When an IP packet arrives, ESP examines the SPI value in the packet’s header.
SA Lookup: Using the SPI, ESP searches its Security Association Database (SAD) to find the corresponding SA that matches the SPI. The SAD contains entries for each active SA, indexed by their SPIs.
Applying Security Parameters: Once the matching SA is identified, ESP retrieves the cryptographic parameters (such as encryption and authentication algorithms) associated with that SA. It then processes the packet accordingly to ensure data confidentiality and integrity.
OVS is used to facilitate the transfer of plaintext messages between the host and the DPU. In this context, OVS acts as a software-based network switch that manages network traffic, routing messages between the host’s CPU and the DPU without encryption.
Setting up east-west overlay encryption can be done in two steps:
Configure the OVS (Open vSwitch):
Run the script: Execute the following command, which runs the ovs-monitor-ipsec script and automates the configuration process:
systemctl start openvswitch-ipsec.service
Start Open vSwitch. If your operating system is Ubuntu, run the following on both Arm_1 and Arm_2:
service openvswitch-switch start
If your operating system is CentOS, run the following on both Arm_1 and Arm_2:
service openvswitch restart
Start OVS IPsec service. Run the following on both Arm_1 and Arm_2:
systemctl start openvswitch-ipsec.service
Set up OVS bridges in both DPUs. Run the following on both Arm_1 and Arm_2:
ovs-vsctl add-br vxlan-br
ovs-vsctl add-port ovs-br $PF_REP
ovs-vsctl set Open_vSwitch . other_config:hw-offload=true
Set up IPsec tunnel on the OVS bridge. Three authentication methods are possible. Select your preferred method and follow the steps relevant to it. Note that some authentication methods require you to create certificates (self-signed or certificate authority certificates).
There are three authentication methods:
Using pre-shared key
On Arm_1, run:
ovs-vsctl add-port vxlan-br tun -- \
set interface tun type=vxlan \
options:local_ip=$ip1 \
options:remote_ip=$ip2 \
options:key=100 \
options:dst_port=4789 \
options:psk= your pre-shared secret value
On Arm_2, run:
ovs-vsctl add-port vxlan-br tun -- \
set interface tun type=vxlan \
options:local_ip=$ip2 \
options:remote_ip=$ip1 \
options:key=100 \
options:dst_port=4789\
options:psk=your pre-shared secret value
Pre-shared key (PSK) based authentication is easy to set up but less secure compared with other authentication methods. You should use it cautiously in production systems.
Using self-signed certificates
Generate self-signed certificate in both Arm_1and Arm_2. Then copy the certificate of Arm_1 to Arm_2 and the certificate of Arm_2 to Arm_1.
On Arm_1, run:
Generate self-signed certificates
ovs-pki req -u host_1.
ovs-pki self-sign host_1
ovs-vsctl set Open_vSwitch . other_config:certificate=/etc/swanctl/x509/host_1-cert.pem \
other_config:private_key=/etc/swanctl/private/host_1-privkey.pem
On Arm_2, run:
Generate self-signed certificates
ovs-pki req -u host_2.
ovs-pki self-sign host_2
ovs-vsctl set Open_vSwitch . other_config:certificate=/etc/swanctl/x509/host_2-cert.pem \
other_config:private_key=/etc/swanctl/private/host_2-privkey.pem
Using CA-signed certificate:
First you need to establish a public key infrastructure (PKI), generate certificate requests, and copy the certificate request of Arm_1 to Arm_2 and Arm_2 to Arm_1 . Sign the certificate requests with the CA key.
On Arm_1, run:
ovs-pki init --force
cp /var/lib/openvswitch/pki/controllerca/cacert.pem <path_to>/certsworkspace
cd <path_to>/certsworkspace
ovs-pki req -u host_1
ovs-pki sign host1 switch
After running this code, you should have host_1-cert.pem, host_1-privkey.pem, and cacert.pm in the certsworkspace folder.
On Arm_2, run:
ovs-pki init --force
cp /var/lib/openvswitch/pki/controllerca/cacert.pem <path_to>/certsworkspace
cd <path_to>/certsworkspace
ovs-pki req -u host_2
ovs-pki sign host_2 switch
After running this code, you should have host_2-cert.pem, host_2-privkey.pem, and cacert.pm in the certsworkspace folder.
Configure IPsec tunnel to use CA-signed certificate:
On Arm_1, run:
ovs-vsctl set Open_vSwitch . \
other_config:certificate=/etc/strongswan/swanctl/x509/host_1.pem \
other_config:private_key=/etc/strongswan/swanctl/private/host_1-privkey.pem \
other_config:ca_cert=/etc/strongswan/swanctl/x509ca/cacert.pem
On Arm_2, run:
ovs-vsctl set Open_vSwitch . \
other_config:certificate=/etc/strongswan/swanctl/x509/host_2.pem \
other_config:private_key=/etc/strongswan/swanctl/private/host_2-privkey.pem \
other_config:ca_cert=/etc/strongswan/swanctl/x509ca/cacert.pem
After OVS is configured, run the following command:
systemctl start openvswitch-ipsec.service
This command automatically runs the ovs-monitor-ipsec script and generates the swanctl.conf file. This command also runs the strongSwan IPsec service.
Note that critical information such as key exchange and authentication algorithms to be used for IKE SA and ESP SA are passed in the ovs-monitor-ipsec script to later generate a swanctl.conf file. Ensure that the script contains all the key exchange algorithms to be used for IKE SA establishment. For instance, parameters ke1_kyber3-ke2_blast passed in the ovs-monitor-ipsec script
sudo sed -i 's/aes256gcm16-modp2048-esn/aes256gcm16-modp2048-ke1_kyber3-ke2_blast-esn/g' /usr/share/openvswitch/scripts/ovs-monitor-ipsec
will result in swanctl.conf parameters:
esp_proposals = aes128gcm128-x25519-ke1_kyber3-ke2_blast
Here’s a basic structure for the swanctl.conf file that includes necessary parameters for both ends of the connection (referred to as Left (BFL) and Right (BFR)):
connections {
BFL-BFR {
local_addrs = 192.168.50.1 // Replace with your local IP
remote_addrs = 192.168.50.2 // Replace with your remote IP
local {
auth = psk // Use pre-shared key authentication
id = host1 // Identifier for local machine
}
remote {
auth = psk // Use pre-shared key authentication
id = host2 // Identifier for remote machine
}
children {
bf {
local_ts = 192.168.50.1/24 [udp/4789] // Local traffic selectors
remote_ts = 192.168.50.2/24 [udp/4789] // Remote traffic selectors
esp_proposals = aes128gcm128-x25519 // Encryption proposals should include additional key exchanges
mode = transport // Use transport mode
policies_fwd_out = yes // Forward output policies
hw_offload = full // Enable hardware offload
}
}
version = 2 // Specify version
mobike = no / Mobile IP not used
reauth_time = 0 // Re-authentication time
proposals = aes128-sha256-x25519 // IKE proposals
}
}
If using pre-shared key (PSK) for authentication, add a section to the swanctl.conf file:
secrets {
ike-BF {
id-host1 = host1 // Identifier for Left Arm
id-host2 = host2 // Identifier for Right Arm
secret = 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jL // Replace with your actual secret
}
}
Ensure that all the data needed to generate the swanctl.conf file is correctly passed in the ovs-monitor-ipsec script.
For more information see NVIDIA DOCA East-West Overlay Encryption Application
mkdir qrypt
cd qrypt
sudo apt -y install astyle cmake gcc ninja-build libssl-dev python3-pytest python3-pytest-xdist unzip xsltproc doxygen graphviz python3-yaml valgrind
git clone -b main <https://github.com/open-quantum-safe/liboqs.git>
cd liboqs
mkdir build
cd build
cmake -GNinja -DOQS_USE_OPENSSL=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=/usr \\
-DCMAKE_BUILD_TYPE=Release -DOQS_BUILD_ONLY_LIB=ON ..
ninja
sudo ninja install
cd ../../
git clone <https://github.com/QryptInc/strongswan.git>
cd strongswan
git checkout BF-6.0.0beta4-qrypt-plugins
Create a free account at https://docs.qrypt.com/getting_started/ This will enable you to generate JSON web tokens (JWT) that you’ll need to add to the conf files.
strongswan/src/libstrongswan/plugins/quantum_entropy/quantum-entropy.conf:
quantum_entropy {
// Entropy API FQDN
fqdn = api-eus.qrypt.com
// Entropy API JWT
jwt = <PASTE-TOKEN-HERE>
// File to read local random bytes for xor with downloaded entropy
random = /dev/random
// Whether to load the plugin. Can also be an integer to increase the
// priority of this plugin.
load = yes
}
strongswan/src/libstrongswan/plugins/blast/blast.conf:
blast {
jwt = <PASTE-TOKEN-HERE>
load = yes
}
Building a strongSwan 6.X tag will include support for RFC 9370 which will allow for hybrid key exchanges including PQC and BLAST.
sudo apt-get -y install pkg-config shtool autoconf gperf bison build-essential pkg-config m4 libtool libgmp3-dev automake autoconf gettext perl flex libsystemd-dev libjansson-dev curl libcurl4-openssl-dev
./autogen.sh
./configure --enable-openssl --disable-random --prefix=/usr/local --sysconfdir=/etc --enable-systemd --enable-oqs --enable-curl
make
sudo make install
cd ..
Retrieve Qrypt’s SDK library from the Qrypt Portal from “Products->Qrypt SDK”. Copy the libQryptSecurity.so and libQryptSecurityC.so libraries to src/libstrongswan/plugins/blast/. Then, proceed with the following instructions.
cd src/libstrongswan/plugins/blast/
sudo make install-deps
sudo ldconfig
make SWANDIR=../../../..
sudo make install PLUGINCONF=/etc/strongswan.d/charon/
cd ../../../..
sudo systemctl daemon-reload
sudo systemctl stop strongswan.service
sudo systemctl start strongswan.service
sudo systemctl status strongswan.service