The first Post-Quantum Cryptography algorithms have been selected by NIST. Let's see if we can run an Apache httpd server on FreeBSD 14.2 using OpenSSL, liboqs, and oqs-provider.
There's been recent developments in Post-Quantum Cryptography that caught my attention.
- 2024-08-13 NIST published 3 PQC algorythm standards.
- 2024-11-12: NIST published an initial public draft "Transition to Post-Quantum Cryptography Standards".
- 2024-12-03: AIVD publishes "Het PQC-migratie handboek" (Dutch).
So I thought it's time to see if we can run a webserver that uses PQC algorithms.
With any luck (if your browser is up-to-date), this page was served using hybrid Post-Quantum Cryptography algorithm X25519MLKEM768!
What do we need?
Shopping list
- The Open Quantum Security liboqs library with the Kyber ML-KEM algorithms.
- The OpenSSL oqs-provider engine.
- An Apache httpd server using OpenSSL (that's "normal" for most installs).
- Configuration for Apache httpd to enable the OpenSSL provider and ML-KEM algorithms.
Luckily, the liboqs
library has already been ported to FreeBSD
but the oqs-provider does not exist yet.
Porting the OpenSSL OQS Provider
You can skip this chapter if all you want is Apache with ML-KEM!
You need a recent OpenSSL version, the one in FreeBSD base should work but has known issues. Best to use the latest release, at time of writing that was OpenSSL 3.4.0 (non-LTS). Since I use my own LibreBSD environment, I have to switch the default OpenSSL library anyway as LibreSSL does not support MK-KEM (yet?).
# /etc/make.conf
DEFAULT_VERSIONS+= ssl=openssl34
Then we build and install liboqs
. As you can see it uses the OpenSSL library
from ports and ignores OpenSSL 3.0 or 1.1.1 from base.
cd /usr/ports/security/libqs
make configure
...
-- Found OpenSSL: /usr/local/lib/libcrypto.so (found suitable version "3.4.0", minimum required is "1.1.1")
...
make reinstall
Now we're ready to port OpenSSL OQS-provider. This is a pretty basic Makefile for a port, and even the tests are OK.
```sh
Test project /wrkdir/usr/ports/security/openssl_oqs-provider/work/.build
Start 1: oqs_signatures
Start 2: oqs_kems
Start 3: oqs_groups
Start 4: oqs_tlssig
Start 5: oqs_endecode
Start 6: oqs_evp_pkey_params
1/6 Test #2: oqs_kems ......................... Passed 0.35 sec
2/6 Test #3: oqs_groups ....................... Passed 0.49 sec
3/6 Test #6: oqs_evp_pkey_params .............. Passed 1.68 sec
4/6 Test #4: oqs_tlssig ....................... Passed 6.65 sec
5/6 Test #1: oqs_signatures ................... Passed 8.37 sec
6/6 Test #5: oqs_endecode ..................... Passed 11.40 sec
100% tests passed, 0 tests failed out of 6
Total Test time (real) = 11.41 sec
This was all in my porting jail. I've created packages so we can install and use this in my Apache httpd jail.
Enabling ML-KEM support in Apache httpd
This should work on FreeBSD 14.x which has OpenSSL 3.0 in base, but there are
known problems, so best build an environment with OpenSSL from ports. Modify
your make.conf
file to set the OpenSSL version. I've tried OpenSSL 3.3 and
3.4.
# /etc/make.conf
DEFAULT_VERSIONS+= ssl=openssl34
Continue with (re-)building security/openssl
, security/liboqs
,
security/openssl_oqs-provider
, devel/apr1
and www/httpd
. Create packages
for deployment.
Tip: Use a poudriere "set" that uses OpenSSL 3.4 from ports.
cd /usr/ports/security/openssl34
make clean package reinstall && \
cd /usr/ports/security/liboqs && \
make clean package reinstall && \
cd /usr/ports/security/openssl_oqs-provider && \
make clean package reinstall && \
cd /usr/ports/devel/apr1 && \
make clean package reinstall && \
cd /usr/ports/www/apache24 && \
make clean package
Make sure you have all fresh packages in /usr/ports/packages/All
.
To be able to verify that we have a working OpenSSL library with OQS-provider,
you could use curl
.
Configure OpenSSL
To enable OQS-provider, we need to modify the openssl.cnf
file. On FreeBSD
this is /usr/local/openssl/openssl.cnf
. In a stock OpenSSL configuration we
need to modify the provider_sect
section. You should find it by following
the references starting with openssl_conf
.
# Use this in order to automatically load providers.
openssl_conf = openssl_init
[openssl_init]
providers = provider_sect
[provider_sect]
default = default_sect
oqsprovider = oqsprovider_sect
[default_sect]
activate = 1
[oqsprovider_sect]
activate = 1
Verify that your provider loads by default.
$ /usr/local/bin/openssl list -providers -verbose`
Providers:
default
name: OpenSSL Default Provider
version: 3.3.2
status: active
oqsprovider
name: OpenSSL OQS Provider
version: 0.7.0
status: active
If you only see the default
provider, check your config for typos etc.
Then we can verify that we have a PQC capable setup using curl
:
$ curl https://pq.cloudflareresearch.com/cdn-cgi/trace --curves X25519MLKEM768
fl=522f159
h=pq.cloudflareresearch.com
ip=192.0.1.7
ts=1733670505.942
visit_scheme=https
uag=curl/8.11.0
colo=AMS
sliver=none
http=http/2
loc=NL
tls=TLSv1.3
sni=plaintext
warp=off
gateway=off
rbi=off
kex=X25519MLKEM768
This validates two things:
- That your OpenSSL config has been picked up by curl, or it will errror out on the curve name.
- The response tells you that you've used a PQC key-exchange (
kex
).
Configure Apache httpd
Now that we know that we have OpenSSL all set up, we can move on to configuring Apache httpd.
This is a tiny task. We're starting with a config generated by Mozilla's SSL-configurator (only the relevant lines here for brevity).
# modern configuration
SSLProtocol TLSv1.3
SSLOpenSSLConfCmd Curves X25519:prime256v1:secp384r1
Simply extend the Curves
configuration with the ML-KEM curve
# modern configuration
SSLProtocol TLSv1.3
SSLOpenSSLConfCmd Curves X25519MLKEM768:X25519:prime256v1:secp384r1
Restart your Apache service. When all's well, you now have a PQC functional webserver!
Validate that your server is using MLKEM768 with curl
(output shortened)
$ curl -vo /dev/null --curves X25519MLKEM768 https://your.example.org/
...
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519MLKEM768 / id-ecPublicKey
...
Check the output to see that the SSL connection uses MLKEM768 hybrid mode.
Qualys SSL Labs is still oblivious to the concept of PQC it seems. Hope that that changes soon!
What's next?
Update 2024-12-09: The oqsprovider port is now available on FreeBSD.