Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions .github/workflows/cmake-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]
repository_dispatch:
types: [nightly-trigger]

jobs:
build:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/codespell.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]
repository_dispatch:
types: [nightly-trigger]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/fwtpm-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]
repository_dispatch:
types: [nightly-trigger]

jobs:
# ----------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/make-test-swtpm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]
repository_dispatch:
types: [nightly-trigger]

jobs:
build:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/multi-compiler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]
repository_dispatch:
types: [nightly-trigger]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
40 changes: 40 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Nightly CI

# Daily fan-out to every wolfTPM workflow that listens for the
# 'nightly-trigger' repository_dispatch event. Catches upstream wolfSSL
# drift (e.g. header renames, API breaks) within ~24h.
#
# Workflows opt in by adding the listener to their `on:` block:
# repository_dispatch:
# types: [nightly-trigger]
#
# repository_dispatch is API-only — there is no UI button to trigger
# these workflows by hand. Maintainers cannot accidentally fire them.
# Workflows that should never be batch-triggered (e.g. hw-spdm-test on
# the self-hosted Pi runner) simply don't add the listener.

on:
schedule:
# 02:00 UTC daily (offset from typical top-of-hour congestion).
- cron: '17 2 * * *'

permissions:
contents: write

jobs:
fan-out:
name: Dispatch nightly-trigger to all listening workflows
runs-on: ubuntu-latest
if: github.repository == 'wolfSSL/wolfTPM'

steps:
- name: Send repository_dispatch event
uses: actions/github-script@v7
with:
script: |
await github.rest.repos.createDispatchEvent({
owner: context.repo.owner,
repo: context.repo.repo,
event_type: 'nightly-trigger',
});
core.info('Dispatched nightly-trigger; all listening workflows will fire.');
2 changes: 2 additions & 0 deletions .github/workflows/pqc-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]
repository_dispatch:
types: [nightly-trigger]

jobs:
pqc-examples:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/release-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ on:
branches: [ 'master', 'main', 'release/**', 'rel_v*_prep' ]
pull_request:
branches: [ '**' ]
repository_dispatch:
types: [nightly-trigger]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/sanitizer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]
repository_dispatch:
types: [nightly-trigger]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/seal-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ on:
- 'src/tpm2_wrap.c'
- 'src/fwtpm/**'
- 'wolftpm/tpm2_wrap.h'
repository_dispatch:
types: [nightly-trigger]

jobs:
seal-test:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/win-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]
repository_dispatch:
types: [nightly-trigger]

jobs:
build:
Expand Down
122 changes: 122 additions & 0 deletions .github/workflows/wolfssl-versions-pqc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
name: wolfSSL Version Matrix (PQC)

on:
push:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]
repository_dispatch:
types: [nightly-trigger]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
# Resolve the latest -stable wolfSSL tag at run time so we don't have to
# bump this workflow every release. Floor (v5.8.0) and master are fixed:
# v5.8.0 exercises every version-gated workaround in fwtpm_crypto.c, and
# master surfaces upstream drift on the nightly run.
discover-versions:
name: Resolve wolfSSL version matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
latest-stable: ${{ steps.set-matrix.outputs.latest-stable }}
steps:
- name: Resolve latest -stable wolfSSL tag
id: set-matrix
run: |
set -euo pipefail
# List remote v*-stable tags, version-sort, take the highest.
# Equivalent to `git tag -l 'v*-stable' | sort -V | tail -1` in a
# local clone, but avoids cloning just to read tag names.
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 from remote"
exit 1
fi
echo "Latest stable wolfSSL: $LATEST"
echo "latest-stable=$LATEST" >> "$GITHUB_OUTPUT"
MATRIX=$(jq -nc --arg latest "$LATEST" '{
include: [
{"wolfssl-version":"v5.8.0-stable","wolfssl-ref":"v5.8.0-stable","cache-key":"wolfssl-pqc-v5.8.0-v1"},
{"wolfssl-version":$latest,"wolfssl-ref":$latest,"cache-key":("wolfssl-pqc-" + $latest + "-v1")},
{"wolfssl-version":"master","wolfssl-ref":"master","cache-key":""}
]
}')
echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"

pqc-build-test:
name: wolfSSL ${{ matrix.wolfssl-version }}
needs: discover-versions
runs-on: ubuntu-latest
timeout-minutes: 25
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.discover-versions.outputs.matrix) }}

steps:
- name: Checkout wolfTPM
uses: actions/checkout@v4

- name: Install build deps
run: |
sudo apt-get update
sudo apt-get install -y autoconf automake libtool

- name: Cache wolfSSL ${{ matrix.wolfssl-version }}
if: matrix.wolfssl-version != 'master'
id: cache-wolfssl
uses: actions/cache@v4
with:
path: ~/wolfssl-install
key: ${{ matrix.cache-key }}

- name: Build wolfSSL ${{ matrix.wolfssl-version }} with PQC
if: matrix.wolfssl-version == 'master' || steps.cache-wolfssl.outputs.cache-hit != 'true'
run: |
cd ~
git clone --depth 1 --branch ${{ matrix.wolfssl-ref }} \
https://github.com/wolfSSL/wolfssl.git
cd wolfssl
./autogen.sh
./configure --enable-wolftpm --enable-pkcallbacks --enable-keygen \
--enable-dilithium --enable-mlkem --enable-experimental \
--enable-harden CFLAGS="-DWC_RSA_NO_PADDING" \
--prefix=$HOME/wolfssl-install
make -j"$(nproc)"
make install

- name: wolfSSL version info
run: |
grep LIBWOLFSSL_VERSION_STRING $HOME/wolfssl-install/include/wolfssl/version.h
grep LIBWOLFSSL_VERSION_HEX $HOME/wolfssl-install/include/wolfssl/version.h

- name: Build wolfTPM with v1.85 + fwTPM
run: |
./autogen.sh
CPPFLAGS="-I$HOME/wolfssl-install/include" \
LDFLAGS="-L$HOME/wolfssl-install/lib -Wl,-rpath,$HOME/wolfssl-install/lib" \
./configure --enable-v185 --enable-fwtpm --enable-debug=verbose
make -j"$(nproc)"

- name: Run fwtpm_unit.test (PQC KAT block)
run: |
export LD_LIBRARY_PATH=$HOME/wolfssl-install/lib
./tests/fwtpm_unit.test

- name: Upload failure logs
if: failure()
uses: actions/upload-artifact@v4
with:
name: wolfssl-versions-${{ matrix.wolfssl-version }}-logs
path: |
config.log
tests/*.log
test-suite.log
retention-days: 5
2 changes: 2 additions & 0 deletions .github/workflows/zephyr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]
repository_dispatch:
types: [nightly-trigger]

jobs:
run_test:
Expand Down
29 changes: 21 additions & 8 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -714,11 +714,11 @@ else
test "x$ENABLED_WOLFCRYPT" = "xyes"
then
# Probe the actual symbols, not just the headers. wolfSSL ships
# dilithium.h / mlkem.h even without the implementation compiled
# (function decls are gated behind HAVE_DILITHIUM / HAVE_MLKEM
# which only get defined via wolfssl/options.h after the right
# --enable-* flags). Include options.h first so the gate is set
# before the header decls are parsed.
# dilithium.h and wc_mlkem.h even without the implementation
# compiled (function decls are gated behind HAVE_DILITHIUM /
# HAVE_MLKEM which only get defined via wolfssl/options.h after
# the right --enable-* flags). Include options.h first so the
# gate is set before the header decls are parsed.
AC_CHECK_DECL([wc_dilithium_init],
[WOLFTPM_HAVE_DILITHIUM_FN=yes],
[WOLFTPM_HAVE_DILITHIUM_FN=no],
Expand All @@ -728,7 +728,7 @@ else
[WOLFTPM_HAVE_MLKEM_FN=yes],
[WOLFTPM_HAVE_MLKEM_FN=no],
[[#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/mlkem.h>]])
#include <wolfssl/wolfcrypt/wc_mlkem.h>]])
if test "x$WOLFTPM_HAVE_DILITHIUM_FN" = "xyes" && \
test "x$WOLFTPM_HAVE_MLKEM_FN" = "xyes"
then
Expand All @@ -754,9 +754,22 @@ then
[[#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/dilithium.h>]])
AC_CHECK_DECL([wc_MlKemKey_Init], [],
[AC_MSG_ERROR([--enable-v185/--enable-pqc requires wolfSSL built with --enable-mlkem --enable-experimental])],
[AC_MSG_ERROR([--enable-v185/--enable-pqc requires wolfSSL >= v5.8.0-stable built with --enable-mlkem --enable-experimental])],
[[#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/mlkem.h>]])
#include <wolfssl/wolfcrypt/wc_mlkem.h>]])
Comment thread
dgarske marked this conversation as resolved.

AC_MSG_CHECKING([wolfSSL version >= v5.8.0 for PQC])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
#include <wolfssl/version.h>
#if LIBWOLFSSL_VERSION_HEX < 0x05008000
#error "wolfSSL < v5.8.0"
#endif
int main(void) { return 0; }
]])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
AC_MSG_ERROR([wolfTPM PQC requires wolfSSL >= v5.8.0-stable. Please upgrade wolfSSL.])])

AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_V185"
fi
AM_CONDITIONAL([BUILD_V185], [test "x$ENABLED_V185" = "xyes"])
Expand Down
29 changes: 27 additions & 2 deletions src/fwtpm/fwtpm_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@
#endif
#include <wolfssl/wolfcrypt/hmac.h>
#ifdef WOLFTPM_V185
#include <wolfssl/version.h>
#include <wolfssl/wolfcrypt/dilithium.h>
#include <wolfssl/wolfcrypt/mlkem.h>
#include <wolfssl/wolfcrypt/wc_mlkem.h>
#endif
Comment thread
dgarske marked this conversation as resolved.

/* ================================================================== */
Expand Down Expand Up @@ -1003,6 +1004,27 @@ TPM_RC FwDecapsulateMlkem(TPMI_MLKEM_PARAMETER_SET parameterSet,
if (rc == 0 && ssSz > sizeof(sharedSecretOut->buffer)) {
rc = TPM_RC_SIZE;
}
#if LIBWOLFSSL_VERSION_HEX < 0x05009000
/* Workaround: wolfSSL < v5.9.0 Decapsulate does not compute H (hash of
* public key) when the key was generated from a seed via MakeKey. Encode
* the public key once to trigger H caching before Decapsulate. */
if (rc == 0) {
word32 pubLen = 0;
wcRet = wc_MlKemKey_PublicKeySize(mlkemKey, &pubLen);
if (wcRet == 0 && pubLen > 0) {
byte tmpPub[WC_ML_KEM_MAX_PUBLIC_KEY_SIZE];
if (pubLen <= sizeof(tmpPub)) {
wcRet = wc_MlKemKey_EncodePublicKey(mlkemKey, tmpPub, pubLen);
}
else {
wcRet = BUFFER_E;
}
}
if (wcRet != 0) {
rc = TPM_RC_FAILURE;
}
}
#endif
if (rc == 0) {
wcRet = wc_MlKemKey_Decapsulate(mlkemKey,
sharedSecretOut->buffer, ctBuf, ctSize);
Expand Down Expand Up @@ -3588,8 +3610,11 @@ TPM_RC FwVerifySignatureCore(FWTPM_Object* obj,
sig->signature.rsassa.hash);
int mgf = FwGetMgfType(sig->signature.rsassa.hash);
FWTPM_ALLOC_BUF(decSig, FWTPM_MAX_PUB_BUF);
/* Cast: wc_RsaPSS_VerifyCheck took byte* (non-const) in
* wolfSSL <= v5.8.0; the input buffer is const here.
* v5.8.4+ accepts const byte* and the cast is a no-op. */
wcRc = wc_RsaPSS_VerifyCheck(
sig->signature.rsapss.sig.buffer,
(byte*)(uintptr_t)sig->signature.rsapss.sig.buffer,
sig->signature.rsapss.sig.size,
decSig, (word32)FWTPM_MAX_PUB_BUF,
digest, digestSz,
Expand Down
10 changes: 3 additions & 7 deletions src/tpm2_wrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2285,14 +2285,10 @@ static int wolfTPM2_EncryptSecret_RSA(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* tpm
#if defined(WOLFTPM_V185) && !defined(WOLFTPM2_NO_WOLFCRYPT) && \
(defined(WOLFSSL_HAVE_MLKEM) || defined(WOLFSSL_KYBER512) || \
defined(WOLFSSL_KYBER768) || defined(WOLFSSL_KYBER1024))
#include <wolfssl/wolfcrypt/mlkem.h>
/* mlkem.h only forward-declares struct MlKemKey; pull the impl header
* for the full struct so callers can stack-allocate. Pattern mirrors
* wolfssl/wolfcrypt/cryptocb.h. */
#ifdef WOLFSSL_WC_MLKEM
#include <wolfssl/wolfcrypt/wc_mlkem.h>
#elif defined(HAVE_LIBOQS)
#if defined(HAVE_LIBOQS)
#include <wolfssl/wolfcrypt/ext_mlkem.h>
#else
#include <wolfssl/wolfcrypt/wc_mlkem.h>
Comment thread
dgarske marked this conversation as resolved.
#endif

/* ML-KEM session-salt path per TCG TPM 2.0 Library v1.85 Part 1 Sec.24
Expand Down
2 changes: 1 addition & 1 deletion tests/fwtpm_unit_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -2920,7 +2920,7 @@ static void test_fwtpm_mldsa_sequence_roundtrip(void)

#include "pqc_kat_vectors.h"
#include <wolfssl/wolfcrypt/dilithium.h>
#include <wolfssl/wolfcrypt/mlkem.h>
#include <wolfssl/wolfcrypt/wc_mlkem.h>
Comment thread
dgarske marked this conversation as resolved.

/* Layer A: wolfCrypt-only verify against NIST ACVP MLDSA-44 pinned vector. */
static void test_fwtpm_mldsa_nist_kat_verify(void)
Expand Down
Loading
Loading