ci: ORAS-backed OpenSSL/wolfSSL dep cache for from-source builders #48
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: wolfSSL Versions (PQC) | |
| # Backward-compatibility matrix for ML-KEM and ML-DSA. Mirrors wolfTPM's | |
| # wolfssl-versions-pqc.yml pattern: a discover-versions job dynamically | |
| # resolves the latest -stable wolfSSL tag and decides if it is past the PQC | |
| # floor, then the build job runs three rows: pre-PQC floor, dynamically | |
| # resolved latest -stable, and master. | |
| # | |
| # PQC is opt-in (--enable-pqc). PQC_FLOOR is v5.9.1-stable: the wc_MlDsaKey_* | |
| # seed/message API wolfProvider's PQC code depends on lands post-v5.9.1-stable | |
| # (wolfSSL PR #10436), so v5.9.2-stable+ is the first PQC-eligible release. | |
| # PQC rows build with --enable-pqc against the latest OpenSSL (>= 3.6 required); | |
| # older/no-flag rows build without it and verify PQC is absent (opt-in). | |
| on: | |
| push: | |
| branches: [ 'master', 'main', 'release/**' ] | |
| pull_request: | |
| branches: [ '*' ] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| discover-versions: | |
| name: Resolve wolfSSL version matrix | |
| runs-on: ubuntu-22.04 | |
| outputs: | |
| matrix: ${{ steps.set-matrix.outputs.matrix }} | |
| latest-stable: ${{ steps.set-matrix.outputs.latest-stable }} | |
| openssl-tag: ${{ steps.set-matrix.outputs.openssl-tag }} | |
| steps: | |
| - name: Resolve latest -stable wolfSSL tag and latest OpenSSL release | |
| id: set-matrix | |
| 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 "latest-stable=$LATEST" >> "$GITHUB_OUTPUT" | |
| echo "openssl-tag=$OSSL" >> "$GITHUB_OUTPUT" | |
| # Enable PQC when $LATEST is strictly newer than v5.9.1-stable | |
| # (i.e. v5.9.2-stable, v5.10+, v6+, ...). Anything at or before | |
| # the floor lacks the wc_MlDsaKey_* / wc_dilithium_sign_ctx_msg | |
| # API and stays on the no-symbol path. | |
| PQC_FLOOR="v5.9.1-stable" | |
| if [ "$(printf '%s\n%s\n' "$PQC_FLOOR" "$LATEST" \ | |
| | sort -V | tail -n1)" != "$PQC_FLOOR" ]; then | |
| LATEST_PQC_ELIGIBLE=true | |
| else | |
| LATEST_PQC_ELIGIBLE=false | |
| fi | |
| echo "latest-stable PQC eligible: $LATEST_PQC_ELIGIBLE" | |
| # Each row carries the build flag (enable) and which PQC test families | |
| # must result (expect: both | mlkem | mldsa | none). This exercises the | |
| # combined, per-algorithm, and opt-in-absent paths. | |
| MATRIX=$(jq -nc \ | |
| --arg latest "$LATEST" \ | |
| --argjson latest_pqc "$LATEST_PQC_ELIGIBLE" '{ | |
| include: [ | |
| {"name":"pre-PQC (v5.8.0-stable)", | |
| "wolfssl-ref":"v5.8.0-stable","enable":"","expect":"none"}, | |
| {"name":("latest stable (" + $latest + ")"),"wolfssl-ref":$latest, | |
| "enable":(if $latest_pqc then "--enable-pqc" else "" end), | |
| "expect":(if $latest_pqc then "both" else "none" end)}, | |
| {"name":"master (--enable-pqc)", | |
| "wolfssl-ref":"master","enable":"--enable-pqc","expect":"both"}, | |
| {"name":"master (no flag, opt-in check)", | |
| "wolfssl-ref":"master","enable":"","expect":"none"}, | |
| {"name":"master (--enable-mlkem only)", | |
| "wolfssl-ref":"master","enable":"--enable-mlkem","expect":"mlkem"}, | |
| {"name":"master (--enable-mldsa only)", | |
| "wolfssl-ref":"master","enable":"--enable-mldsa","expect":"mldsa"} | |
| ] | |
| }') | |
| echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT" | |
| pqc-build-test: | |
| name: ${{ matrix.name }} | |
| needs: discover-versions | |
| runs-on: ubuntu-22.04 | |
| permissions: | |
| contents: read | |
| packages: write | |
| timeout-minutes: 30 | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{ fromJson(needs.discover-versions.outputs.matrix) }} | |
| steps: | |
| - name: Checkout wolfProvider | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| # Every row builds against the latest OpenSSL release. PQC needs OpenSSL | |
| # 3.6+ (and the enable flag enforces that floor); the interop step then | |
| # compares wolfProvider against that release's native ML-KEM/ML-DSA. | |
| - name: Cache build dependencies | |
| id: deps | |
| uses: ./.github/actions/oras-build-deps | |
| with: | |
| variant: pqc | |
| openssl_ref: ${{ needs.discover-versions.outputs.openssl-tag }} | |
| wolfssl_ref: ${{ matrix.wolfssl-ref }} | |
| extra_key: ${{ matrix.enable }} | |
| github_token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Build wolfProvider (${{ matrix.enable || 'no PQC flag' }}) | |
| run: | | |
| OPENSSL_TAG=${{ needs.discover-versions.outputs.openssl-tag }} \ | |
| WOLFSSL_TAG=${{ matrix.wolfssl-ref }} \ | |
| ./scripts/build-wolfprovider.sh ${{ matrix.enable }} | |
| - 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_hit: ${{ steps.deps.outputs.openssl_hit }} | |
| wolfssl_hit: ${{ steps.deps.outputs.wolfssl_hit }} | |
| # Opt-in is per-algorithm: assert exactly the expected PQC test families | |
| # are present (both / mlkem / mldsa / none). This catches a leaked | |
| # algorithm, a missing one, or PQC dragged in without a flag. | |
| - name: Verify PQC test presence matches opt-in (${{ matrix.expect }}) | |
| run: | | |
| tests=$(./test/unit.test --list) || exit 1 | |
| kem=0; dsa=0 | |
| printf '%s\n' "$tests" | grep -q 'test_mlkem_keygen' && kem=1 | |
| printf '%s\n' "$tests" | grep -q 'test_mldsa_sign_verify' && dsa=1 | |
| echo "expect=${{ matrix.expect }} mlkem=$kem mldsa=$dsa" | |
| case "${{ matrix.expect }}" in | |
| both) [ "$kem" = 1 ] && [ "$dsa" = 1 ] ;; | |
| mlkem) [ "$kem" = 1 ] && [ "$dsa" = 0 ] ;; | |
| mldsa) [ "$kem" = 0 ] && [ "$dsa" = 1 ] ;; | |
| none) [ "$kem" = 0 ] && [ "$dsa" = 0 ] ;; | |
| *) false ;; | |
| esac || { echo "ERROR: PQC test families do not match expect=${{ matrix.expect }}"; exit 1; } | |
| # Run the ML-KEM / ML-DSA / hybrid unit tests: keygen, sign/verify, | |
| # encap/decap, PEM encoder/decoder round-trip, X.509 signing, and the | |
| # hybrid-group KEM. Selected by index from --list so it tracks however | |
| # many PQC tests are registered. LD_LIBRARY_PATH carries libwolfprov's | |
| # deps; the provider module itself is found via the default .libs dir. | |
| - name: Run PQC unit tests | |
| if: matrix.expect != 'none' | |
| run: | | |
| export LD_LIBRARY_PATH="$(pwd)/wolfssl-install/lib:$(pwd)/openssl-install/lib:$(pwd)/openssl-install/lib64" | |
| idxs=$(./test/unit.test --list | grep -iE 'mlkem|mldsa|mlx' \ | |
| | grep -oE '^[0-9]+') | |
| if [ -z "$idxs" ]; then | |
| echo "::error::No PQC unit tests found" | |
| exit 1 | |
| fi | |
| for i in $idxs; do | |
| echo "== PQC unit test $i ==" | |
| ./test/unit.test "$i" || exit 1 | |
| done | |
| # Three-way interop: wolfProvider <-> OpenSSL default <-> wolfSSL direct. | |
| # Only runs on PQC-enabled rows; the latest OpenSSL (3.6+, the PQC floor) | |
| # has native ML-KEM/ML-DSA in the default provider, so this proves | |
| # wolfProvider's bytes are FIPS 203/204 standards-compliant against two | |
| # reference implementations. | |
| # Linux x86_64 OpenSSL installs to lib64 by default; LD_LIBRARY_PATH | |
| # must include both lib and lib64 or the dynamic linker falls through | |
| # to the system libcrypto/libssl (Ubuntu 22.04 ships 3.0.2, which has | |
| # no ML-KEM/ML-DSA in the default provider). | |
| - name: Three-way PQC interop validation | |
| if: matrix.expect == 'both' | |
| run: | | |
| LD_LIBRARY_PATH="$(pwd)/wolfssl-install/lib:$(pwd)/openssl-install/lib:$(pwd)/openssl-install/lib64" \ | |
| ./test/pqc_interop.test | |
| - name: Print errors on failure | |
| if: ${{ failure() }} | |
| run: | | |
| if [ -f test-suite.log ]; then | |
| cat test-suite.log | |
| fi |