RSS Amplifier

Signs of Triviality · May 3, 2025

Post-Quantum Cryptography on NetBSD

0
Sign in to vote or save

netmeister.org

May 2nd, 2025

So you want to try out post-quantum cryptography (PQC) like all the cool kids - what are your options? You could use Open Quantum Safe's various providers; you could use plain vanilla OpenSSL, so long as you use the most recent OpenSSL 3.5.0 release; or you could use Google's BoringSSL, as much as Google recommends against it.

If you're using Linux (and specifically Linux on Linode), you can follow, e.g., these instructions I provided previously, but as usual, I also like to get everything working on NetBSD, so let's give that a go:

PQC Using Open Quantum Safe

A few months ago, I imported the Open Quantum Safe OpenSSL provider into pkgsrc, and using that is straight forward:

# PKG_PATH="https://cdn.NetBSD.org/pub/pkgsrc/packages/NetBSD/$(uname -p)/$(uname -r|cut -f '1 2' -d.)/All/"
# export PKG_PATH
# pkg_add pkgin
# pkgin -y install oqs-provider
[...]
# cat >>/etc/openssl/openssl.cnf <<EOF
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
module = /usr/pkg/lib/ossl-modules/oqsprovider.so
EOF
# 

And that's really all. To verify that it's working, ensure that the list of providers includes the "OpenSSL OQS Provider" and your kem-algorithms include the NIST FIPS-203 ML-KEM options:

$ openssl list -providers
Providers:
  default
    name: OpenSSL Default Provider
    version: 3.0.12
    status: active
  oqsprovider
    name: OpenSSL OQS Provider
    version: 0.8.0
    status: active
$ openssl list -kem-algorithms | grep -i mlkem768
  mlkem768 @ oqsprovider
  p384_mlkem768 @ oqsprovider
  x448_mlkem768 @ oqsprovider
  X25519MLKEM768 @ oqsprovider
  SecP256r1MLKEM768 @ oqsprovider
$ 

You can now verify that you can speak PQC using the TLS 1.3 hybrid key exchange X25519MLKEM768 by connecting to, e.g., this website (or any of the other sites using PQC):

$ openssl s_client -curves X25519MLKEM768 -connect www.netmeister.org:443
CONNECTED(00000005)
[...]

To configure, e.g., apache, you'd then add the following SSLOpenSSLConfCmd directive to your httpd-ssl.conf file:

# PQC, requires oqs-provider (and OpenSSL >= 3.x)
SSLProtocol +TLSv1.3
SSLOpenSSLConfCmd Curves X25519:X25519MLKEM768:SecP256r1MLKEM768:secp384r1:prime256v1

If your browser speaks PQC (check about:config -> security.tls.enable_kyber in Firefox, chrome://flags/#enable-tls13-kyber and chrome://flags/#use-ml-kem for Chromium browsers) , you should then see your connection use X25519MLKEM768:

Browser network security details showing the
connection used X25519MLKEM768

Nice.

PQC Using BoringSSL

Google's BoringSSL, created back in 2014 after the Heartbleed vulnerability (ah, good times, good times), has had support for post-quantum cryptography for a while, being one of the early adopters of Kyber, ML-KEM's predecessor. However, BoringSSL is not (yet) available in pkgsrc, so we'll have to build it ourselves.

The process isn't particularly difficult. We'll need git-base, cmake, and ninja-build as build requirements and then install BoringSSL into /opt/boringssl:

$ sudo pkgin -y install git-base cmake ninja-build
[...]
$ git clone https://boringssl.googlesource.com/boringssl
[...]
$ cd boringssl
$ export PREFIX=/opt/boringssl
$ export LDFLAGS="-Wl,-rpath,${PREFIX}/lib"
$ cmake -GNinja -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=1 -DCMAKE_INSTALL_PREFIX=${PREFIX}
[...]
-- Configuring done (1.2s)
-- Generating done (0.4s)
-- Build files have been written to: /root/boringssl/build
$ ninja -C build
ninja: Entering directory `build'
[560/638] Building CXX object CMakeFiles/ssl_test.dir/ssl/ssl_test.cc.o
[638/638] Linking CXX executable ssl_test
$ 

Well, that was easy - let's install it and see if it works:

$ sudo ninja -C build install
[...]
$ /opt/boringssl/bin/bssl s_client -connect www.netmeister.org -curves X25519MLKEM768
Connecting to [2602:f977:800:0:e276:63ff:fe72:3900]:443
Connected.
  Version: TLSv1.3
  Cipher: TLS_AES_256_GCM_SHA384
  ECDHE group: X25519MLKEM768
  Signature algorithm: ecdsa_secp256r1_sha256
  Cert subject: CN = netmeister.org
  Cert issuer: C = US, O = Let's Encrypt, CN = E6

Neat. Now let's actually use it with... say, nginx. We can't use pkgsrc to install nginx, since we need to link it with our new BoringSSL library, so we need to build it by hand as well, using the configuration options taken over from pkgsrc's Makefile (modulo a different PREFIX) applying the minimally required patch:

$ ftp https://nginx.org/download/nginx-1.28.0.tar.gz
[...]
$ ftp https://github.com/freenginx/nginx/commit/1ac658f44afc9240f13e9d6c1c9d5a7816299e8e.patch
[...]
$ tar zxf nginx-1.28.0.tar.gz
$ cd nginx-1.28.0
$ patch -p1 < ../1ac658f44afc9240f13e9d6c1c9d5a7816299e8e.patch
[...]
$ export PREFIX="/opt/nginx"
$ ./configure --user=nginx                                                  \
              --group=nginx                                                 \
              --prefix=${PREFIX}                                            \
              --pid-path=/var/run/nginx.pid                                 \
              --lock-path=/var/db/nginx/nginx.lock                          \
              --error-log-path=/var/log/nginx/error.log                     \
              --http-log-path=/var/log/nginx/access.log                     \
              --http-client-body-temp-path=/var/db/nginx/client_body_temp   \
              --http-proxy-temp-path=/var/db/nginx/proxy_temp               \
              --http-fastcgi-temp-path=/var/db/nginx/fstcgi_temp            \
              --http-scgi-temp-path=/var/db/nginx/scgi_temp                 \
              --with-pcre                                                   \
              --with-mail_ssl_module                                        \
              --with-http_ssl_module                                        \
              --with-http_v2_module                                         \
              --with-http_v3_module                                         \
              --with-http_realip_module                                     \
              --http-uwsgi-temp-path=/var/db/nginx/uwsgi_temp               \
              --with-http_slice_module                                      \
              --with-http_stub_status_module                                \
              --with-http_gzip_static_module                                \
              --with-http_auth_request_module                               \
              --with-openssl-opt=enable-tls1_3                              \
              --with-cc-opt='-I/usr/pkg/include -I/opt/boringssl/include'   \
              --with-ld-opt='-L/usr/pkg/lib -Wl,-rpath,/usr/pkg/lib'        \
              --with-ld-opt="-L${PREFIX}/lib -Wl,-rpath,${PREFIX}/lib"      \
              --with-ld-opt='-L/opt/boringssl/lib -Wl,-rpath,/opt/boringssl/lib'
[...]
$ make
[...]
$ sudo make install
[...]

You can then update /opt/nginx/conf/nginx.conf to add a minimal TLS configuration:

server {
    listen 443 ssl;
    listen [::]:443 default_server ssl;
    server_name example.com www.example.com;
    root /var/www/pqc;
    index index.html;
    ssl_certificate /opt/certs/pqc.crt;
    ssl_certificate_key /opt/certs/pqc.key;
    ssl_protocols TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ecdh_curve X25519MLKEM768:X25519;
    location / {
        try_files $uri $uri/ =404;
    }
} 

...and just like before, you should see your connection use X25519MLKEM768:

$ /opt/boringssl/bin/bssl s_client -connect localhost -curves X25519MLKEM768
Connecting to [::1]:443
Connected.
  Version: TLSv1.3
  Resumed session: no
  Cipher: TLS_AES_128_GCM_SHA256
  ECDHE group: X25519MLKEM768
[...]

PQC - of course it runs NetBSD!

May 2nd, 2025


Links:

Read the original on netmeister.org

Comments

Nothing yet. Say the first thing.

    Sign in to join the conversation.