Skip to content
Open
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
97 changes: 97 additions & 0 deletions .github/workflows/wolfssl-versions-pqc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
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

jobs:
pqc-build-test:
name: wolfSSL ${{ matrix.wolfssl-version }}
runs-on: ubuntu-latest
timeout-minutes: 25
strategy:
fail-fast: false
matrix:
include:
# Lowest supported: exercises all version-gated workarounds in
# fwtpm_crypto.c (RSA cast, H-set, wc_ForceZero shim).
- wolfssl-version: 'v5.8.0-stable'
Comment thread
aidangarske marked this conversation as resolved.
wolfssl-ref: 'v5.8.0-stable'
cache-key: 'wolfssl-pqc-v5.8.0-v1'
# Latest stable: workarounds gated off via VERSION_HEX.
- wolfssl-version: 'v5.9.1-stable'
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need a dynamic way to get the latest -stable tag...

wolfssl-ref: 'v5.9.1-stable'
cache-key: 'wolfssl-pqc-v5.9.1-v1'
# master always rebuilds (no cache) so wolfSSL upstream renames /
# API breaks surface within ~24h on the next scheduled run.
- wolfssl-version: 'master'
wolfssl-ref: 'master'

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
10 changes: 10 additions & 0 deletions wolftpm/tpm2_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,16 @@ typedef int64_t INT64;
/* The wc_HashFree was added in v3.15.4, so use stub to allow building */
#define wc_HashFree(h, t) (0)
#endif
#if defined(LIBWOLFSSL_VERSION_HEX) && LIBWOLFSSL_VERSION_HEX < 0x05008004
/* wc_ForceZero was first declared in wolfssl/wolfcrypt/memory.h at
* v5.8.4. Mirror the upstream byte-wise volatile zero so older
* wolfSSL releases still build wolfTPM. */
static WC_INLINE void wc_ForceZero(void* mem, size_t len)
{
volatile byte* z = (volatile byte*)mem;
while (len--) *z++ = 0;
}
#endif

#define ENCODING_TYPE_PEM 1 /* CTC_FILETYPE_PEM */
#define ENCODING_TYPE_ASN1 2 /* CTC_FILETYPE_ASN1 */
Expand Down
Loading