Skip to content
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d8c513f
Encrypt PKCS#8 keys when a cipher is configured
aidangarske Jul 30, 2026
327bae6
Add SLH-DSA provider operations
aidangarske Jul 30, 2026
5f21cae
Add SLH-DSA unit coverage
aidangarske Jul 30, 2026
dfc26e1
Run the OpenSSL SLH-DSA KAT vectors
aidangarske Jul 30, 2026
2442961
Add SLH-DSA interoperability coverage
aidangarske Jul 30, 2026
c20363e
Integrate SLH-DSA into builds and CI
aidangarske Jul 30, 2026
bc7a9de
Run nginx PQC tests in the shared CI container
aidangarske Jul 30, 2026
8d48f10
Add libacvp PQC integration coverage
aidangarske Jul 30, 2026
c78c2b2
Add maintained OpenSSL provider examples
aidangarske Jul 31, 2026
ea5bdec
Merge remote-tracking branch 'origin/master' into add-slhdsa
aidangarske Jul 31, 2026
ee6d7fe
Synchronize DH private key encoding
aidangarske Jul 31, 2026
75cffb9
Address SLH-DSA review findings
aidangarske Jul 31, 2026
1bb69c2
Tighten SLH-DSA decode and signature validation
aidangarske Aug 1, 2026
de5ab7b
Address SLH-DSA Skoll findings
aidangarske Aug 1, 2026
bf66a73
Fix provider example libtool path resolution
aidangarske Aug 1, 2026
1bd7734
Resolve provider path from example directory
aidangarske Aug 1, 2026
8dffa2a
Keep DH PKCS8 helper with its declaration
aidangarske Aug 3, 2026
2f6e94a
Keep DH PKCS8 helper with its declaration
aidangarske Aug 3, 2026
c8812c1
Pin libacvp OSP patch revision
aidangarske Aug 3, 2026
0d739e7
Track OSP test branch until upstream merge
aidangarske Aug 3, 2026
ae23402
Tighten PKCS8 feature guards and test strings
aidangarske Aug 3, 2026
571e5fa
Test unsupported PKCS8 cipher rejection
aidangarske Aug 3, 2026
12583a3
Test ECC type-specific cipher rejection
aidangarske Aug 3, 2026
91b9966
Make ECC cipher rejection test OpenSSL 3.0 compatible
aidangarske Aug 3, 2026
57e88dd
Match OpenSSL ML-KEM NULL output handling
aidangarske Aug 3, 2026
ba4b462
Add PKCS8 CLI encryption coverage
aidangarske Aug 3, 2026
93ee317
Wait for OpenSSL test server readiness
aidangarske Aug 4, 2026
88f9f29
Address SLH-DSA security review findings
aidangarske Aug 4, 2026
7ace477
Address PKCS8 security review findings
aidangarske Aug 4, 2026
6935a05
Merge PKCS8 prerequisite fixes
aidangarske Aug 4, 2026
984728d
Harden PKCS8 RNG cleanup and diagnostics
aidangarske Aug 4, 2026
d92b147
Merge final PKCS8 review fixes
aidangarske Aug 4, 2026
c95914f
Complete SLH-DSA review coverage
aidangarske Aug 4, 2026
21fdc66
Complete SLH-DSA review hardening
aidangarske Aug 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 0 additions & 93 deletions .github/nginx/Dockerfile

This file was deleted.

5 changes: 3 additions & 2 deletions .github/nginx/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
# chain, and that the page is served. Exits non-zero if any group fails; the CI
# step inverts that under WOLFPROV_FORCE_FAIL=1.

O=/opt/wolfProvider/openssl-install
WOLFPROV_ROOT=${WOLFPROV_ROOT:-/opt/wolfProvider}
O=${WOLFPROV_ROOT}/openssl-install
CA=/opt/nginx/cacert/CA.crt
PORT=4433
# NB: not "GROUPS" -- that is a bash special array (the user's group IDs).
KEX_GROUPS="X25519MLKEM768 SecP256r1MLKEM768 SecP384r1MLKEM1024 MLKEM512 MLKEM768 MLKEM1024"

export LD_LIBRARY_PATH="/opt/wolfProvider/wolfprov-install/lib:/opt/wolfProvider/wolfssl-install/lib:${O}/lib:${O}/lib64${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
export LD_LIBRARY_PATH="${WOLFPROV_ROOT}/wolfprov-install/lib:${WOLFPROV_ROOT}/wolfssl-install/lib:${O}/lib:${O}/lib64${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"

echo "Quantum-safe groups under test: ${KEX_GROUPS}"
/opt/nginx/sbin/nginx -c /opt/nginx/conf/nginx.conf
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/iperf.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,11 @@ jobs:
mkdir -p $KEY_DIR
cd $KEY_DIR
# Generate RSA keys for iperf tests
# PBKDF2 keys HMAC with the passphrase, and FIPS modules before
# v6.0.0 reject HMAC keys under 14 bytes, so keep this >= 14.
openssl genrsa -out rsa_private_unprotected.pem 2048
openssl rsa -in rsa_private_unprotected.pem -out rsa_private.pem -aes256 -passout 'pass:password'
openssl rsa -in rsa_private.pem -pubout -out rsa_public.pem -passin 'pass:password'
openssl rsa -in rsa_private_unprotected.pem -out rsa_private.pem -aes256 -passout 'pass:wolfprov-iperf-pass'
openssl rsa -in rsa_private.pem -pubout -out rsa_public.pem -passin 'pass:wolfprov-iperf-pass'
# Create a credentials file for iperf
# Username: mario, Password: rossi
echo "mario,bf7a49a846d44b454a5d11e7acfaf13d138bbe0b7483aa3e050879700572709b" > credentials.csv
Expand Down
197 changes: 197 additions & 0 deletions .github/workflows/libacvp-pqc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
name: libacvp PQC Tests

on:
workflow_call:
inputs:
wolfssl_refs_json:
description: "JSON array of wolfssl refs to test; empty = master + latest -stable (pre-PQC-floor refs are dropped)"
required: false
type: string
default: ""
workflow_dispatch: {}

permissions:
contents: read
packages: write

jobs:
discover-versions:
name: Resolve wolfSSL/OpenSSL versions
runs-on: ubuntu-22.04
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
openssl-tag: ${{ steps.set-matrix.outputs.openssl-tag }}
steps:
- name: Resolve wolfSSL refs and latest OpenSSL release
id: set-matrix
env:
INPUT_REFS: ${{ inputs.wolfssl_refs_json }}
run: |
set -euo pipefail
LATEST=$(git ls-remote --tags --refs \
https://github.com/wolfSSL/wolfssl.git 'v*-stable' \
| awk -F/ '{print $NF}' | sort -V | tail -n 1)
if [ -z "${LATEST:-}" ]; then
echo "::error::Could not resolve latest wolfSSL -stable tag"
exit 1
fi
# PQC needs OpenSSL 3.6+, so always build against the latest release.
OSSL=$(git ls-remote --tags --refs \
https://github.com/openssl/openssl.git 'openssl-3.*' \
| awk -F/ '{print $NF}' | grep -E '^openssl-3\.[0-9.]+$' \
| sort -V | tail -n 1)
if [ -z "${OSSL:-}" ]; then
echo "::error::Could not resolve latest OpenSSL release tag"
exit 1
fi
echo "Latest stable wolfSSL: $LATEST"
echo "Latest OpenSSL: $OSSL"
echo "openssl-tag=$OSSL" >> "$GITHUB_OUTPUT"
# Caller can override the ref set (e.g. nightly Wave 2); default is
# master + latest -stable.
if [ -n "${INPUT_REFS:-}" ]; then
REFS=$(printf '%s' "$INPUT_REFS" | jq -r '.[]')
else
REFS=$(printf '%s\n%s\n' "master" "$LATEST")
fi
# PQC needs the wc_MlDsaKey_* seed/message API in v5.9.2-stable.
# master is always eligible; a stable ref must be at the floor or
# newer. A
# pre-floor ref (e.g. v5.8.4-stable from Wave 2) is dropped, since it
# would fail the --enable-pqc gate.
PQC_FLOOR="v5.9.2-stable"
ELIGIBLE=()
for ref in $REFS; do
if [ "$ref" = "master" ]; then
ELIGIBLE+=("$ref")
elif [ "$(printf '%s\n%s\n' "$PQC_FLOOR" "$ref" \
| sort -V | tail -n1)" = "$ref" ]; then
ELIGIBLE+=("$ref")
else
echo "::notice::Skipping pre-PQC-floor wolfSSL ref $ref (floor $PQC_FLOOR)"
fi
done
if [ ${#ELIGIBLE[@]} -eq 0 ]; then
REFS_JSON='[]'
else
REFS_JSON=$(printf '%s\n' "${ELIGIBLE[@]}" | jq -R . | jq -sc .)
fi
echo "Eligible wolfSSL refs: $REFS_JSON"
# Each eligible wolfSSL ref expands to 4 rows: replace-default and
# non-replace, each in normal and force-fail anti-test mode.
MATRIX=$(jq -nc --argjson refs "$REFS_JSON" '
def rows($ref; $lbl):
[ {"replace":true, "ff":"WOLFPROV_FORCE_FAIL=1",
"sfx":" [replace-default] [force-fail]"},
{"replace":true, "ff":"","sfx":" [replace-default]"},
{"replace":false, "ff":"WOLFPROV_FORCE_FAIL=1",
"sfx":" [non-replace] [force-fail]"},
{"replace":false, "ff":"","sfx":" [non-replace]"} ]
| map({"name":($lbl+.sfx), "wolfssl-ref":$ref,
"replace":.replace, "force_fail":.ff});
{ include: ( $refs
| map(rows(.; (if . == "master" then "master"
else "stable (" + . + ")" end)))
| add // [] ) }')
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"

libacvp-pqc:
name: ${{ matrix.name }}
needs: discover-versions
runs-on: ubuntu-22.04
timeout-minutes: 60
container:
image: ghcr.io/wolfssl/wolfprovider-test-deps:bookworm
env:
DEBIAN_FRONTEND: noninteractive
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.discover-versions.outputs.matrix) }}
steps:
- name: Checkout wolfProvider
uses: actions/checkout@v4
with:
fetch-depth: 1

- name: Cache build dependencies
id: deps
uses: ./.github/actions/oras-build-deps
with:
variant: libacvp-pqc-bookworm${{ matrix.replace && '-rd' || '' }}
openssl_ref: ${{ needs.discover-versions.outputs.openssl-tag }}
wolfssl_ref: ${{ matrix.wolfssl-ref }}
extra_key: --enable-pqc
cache_openssl_source: ${{ matrix.replace }}
github_token: ${{ secrets.GITHUB_TOKEN }}

- name: Build wolfProvider
run: |
OPENSSL_TAG=${{ needs.discover-versions.outputs.openssl-tag }} \
WOLFSSL_TAG=${{ matrix.wolfssl-ref }} \
./scripts/build-wolfprovider.sh --enable-pqc \
${{ matrix.replace && '--replace-default' || '' }}

- name: Push build dependencies
uses: ./.github/actions/oras-build-deps-push
with:
registry: ${{ steps.deps.outputs.registry }}
openssl_install_tag: ${{ steps.deps.outputs.openssl_install_tag }}
wolfssl_install_tag: ${{ steps.deps.outputs.wolfssl_install_tag }}
openssl_source_tag: ${{ steps.deps.outputs.openssl_source_tag }}
openssl_hit: ${{ steps.deps.outputs.openssl_hit }}
wolfssl_hit: ${{ steps.deps.outputs.wolfssl_hit }}
openssl_source_hit: ${{ steps.deps.outputs.openssl_source_hit }}
cache_openssl_source: ${{ steps.deps.outputs.cache_openssl_source }}

- name: Checkout libacvp v2.3.1
uses: actions/checkout@v4
with:
repository: cisco/libacvp
ref: v2.3.1
path: libacvp
fetch-depth: 1

- name: Checkout OSP
uses: actions/checkout@v4
with:
repository: aidangarske/osp
# TODO: switch to the upstream wolfSSL/osp ref when PR #351 merges.
ref: add-libacvp-pqc-tests
path: osp
fetch-depth: 1

- name: Build libacvp test suite
working-directory: libacvp
run: |
PATCH=$($GITHUB_WORKSPACE/scripts/resolve-osp-patch.sh \
"$GITHUB_WORKSPACE/osp" libacvp v2.3.1 \
"${{ matrix.wolfssl-ref }}")
patch -p1 < "$PATCH"
autoreconf -fiv
./configure --enable-unit-tests \
--with-ssl-dir="$GITHUB_WORKSPACE/openssl-install" \
--with-libcurl-dir=/usr
make -j"$(nproc)"

- name: Run full libacvp suite with PQC coverage
working-directory: libacvp/test
shell: bash
run: |
export LD_LIBRARY_PATH="$GITHUB_WORKSPACE/wolfprov-install/lib:$GITHUB_WORKSPACE/wolfssl-install/lib:$GITHUB_WORKSPACE/openssl-install/lib:$GITHUB_WORKSPACE/openssl-install/lib64"
export OPENSSL_MODULES="$GITHUB_WORKSPACE/wolfprov-install/lib"
if [ "${{ matrix.replace }}" = "true" ]; then
export OPENSSL_CONF="$GITHUB_WORKSPACE/openssl-install/ssl/openssl.cnf"
else
export OPENSSL_CONF="$GITHUB_WORKSPACE/provider.conf"
fi
set +e
export ${{ matrix.force_fail || 'WOLFPROV_NOOP=1' }}
if [ -n "${{ matrix.force_fail }}" ]; then
./runtest -g APP_PQC_HANDLER -v 2>&1 | tee libacvp-pqc.log
TEST_RESULT=${PIPESTATUS[0]}
else
./runtest -v 2>&1 | tee libacvp-pqc.log
TEST_RESULT=${PIPESTATUS[0]}
fi
$GITHUB_WORKSPACE/.github/scripts/check-workflow-result.sh \
$TEST_RESULT "${{ matrix.force_fail }}" libacvp-pqc
Loading
Loading