-
Notifications
You must be signed in to change notification settings - Fork 74
addition of uart and uartns550 to swtpm #301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,270 @@ | ||
| name: Test UART Communication with SWTPM | ||
|
|
||
| on: | ||
| push: | ||
| branches: [ 'master', 'main', 'release/**' ] | ||
| pull_request: | ||
| branches: [ 'master', 'main', 'release/**' ] | ||
| workflow_dispatch: | ||
|
|
||
| jobs: | ||
| test-uart-swtpm: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Checkout code | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Install basic dependencies | ||
| run: | | ||
| sudo apt-get update | ||
| sudo apt-get install -y \ | ||
| automake \ | ||
| autotools-dev \ | ||
| libtool \ | ||
| pkg-config \ | ||
| gcc \ | ||
| make \ | ||
| git \ | ||
| socat \ | ||
| strace \ | ||
| acl | ||
|
|
||
| - name: Install swtpm | ||
| run: | | ||
| sudo apt-get install -y swtpm swtpm-tools | ||
|
|
||
| - name: Setup wolfSSL | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: wolfssl/wolfssl | ||
| path: wolfssl | ||
|
|
||
| - name: Build wolfSSL | ||
| working-directory: ./wolfssl | ||
| run: | | ||
| ./autogen.sh | ||
| ./configure --enable-wolftpm --prefix=${GITHUB_WORKSPACE}/wolfssl-install | ||
| make -j$(nproc) | ||
| make install | ||
|
|
||
| - name: Start swtpm in socket mode | ||
| run: | | ||
| mkdir -p /tmp/swtpm-state | ||
|
|
||
| # Start swtpm with socket backend (this works reliably in GitHub Actions) | ||
| swtpm socket \ | ||
| --tpm2 \ | ||
| --tpmstate dir=/tmp/swtpm-state \ | ||
| --ctrl type=tcp,port=2322 \ | ||
| --server type=tcp,port=2321 \ | ||
| --flags not-need-init & | ||
| SWTPM_PID=$! | ||
| echo $SWTPM_PID > /tmp/swtpm.pid | ||
|
|
||
| # Give swtpm time to start | ||
| sleep 3 | ||
|
|
||
| # Verify swtpm is running and socket is accessible | ||
| ps aux | grep swtpm | grep -v grep || exit 1 | ||
| timeout 2 bash -c 'until nc -z localhost 2321; do sleep 0.1; done' || exit 1 | ||
|
|
||
| - name: Create UART bridge | ||
| id: uart | ||
| run: | | ||
| # Create a PTY for wolfTPM to connect to as UART device | ||
| # Use socat to create a PTY with proper permissions | ||
| socat -d -d pty,raw,echo=0,link=/tmp/tpm-uart-client,perm=0666 pty,raw,echo=0,link=/tmp/tpm-uart-server,perm=0666 & | ||
| SOCAT_PID=$! | ||
| echo $SOCAT_PID > /tmp/socat.pid | ||
| sleep 2 | ||
|
|
||
| # Get the actual PTY device names | ||
| CLIENT_PTY=$(readlink -f /tmp/tpm-uart-client) | ||
| SERVER_PTY=$(readlink -f /tmp/tpm-uart-server) | ||
|
|
||
| echo "client_pty=$CLIENT_PTY" >> $GITHUB_OUTPUT | ||
| echo "server_pty=$SERVER_PTY" >> $GITHUB_OUTPUT | ||
|
|
||
| echo "Client PTY (for wolfTPM): $CLIENT_PTY" | ||
| echo "Server PTY (bridge endpoint): $SERVER_PTY" | ||
|
|
||
| # Verify PTYs exist | ||
| ls -la $CLIENT_PTY $SERVER_PTY || exit 1 | ||
|
|
||
| - name: Bridge socket to UART | ||
| run: | | ||
| SERVER_PTY="${{ steps.uart.outputs.server_pty }}" | ||
|
|
||
| # Ensure swtpm socket is ready before starting bridge | ||
| echo "Waiting for swtpm socket to be ready..." | ||
| timeout 5 bash -c 'until nc -z localhost 2321; do sleep 0.1; done' || { | ||
| echo "ERROR: swtpm socket not ready!" | ||
| exit 1 | ||
| } | ||
|
|
||
| # Bridge between swtpm socket (port 2321) and the server PTY | ||
| # Use TCP-CONNECT to connect to swtpm and bridge to PTY | ||
| # Add buffering and proper options for reliable data transfer | ||
| echo "Starting bridge from PTY $SERVER_PTY to socket localhost:2321" | ||
| # Use OPEN to open the existing PTY device directly | ||
| # Add readbytes=0 to read all available data, and setsockopt to handle socket properly | ||
| socat OPEN:$SERVER_PTY,raw,echo=0,readbytes=0 TCP:localhost:2321,keepalive,so-keepalive > /tmp/bridge.log 2>&1 & | ||
| BRIDGE_PID=$! | ||
| echo $BRIDGE_PID > /tmp/bridge.pid | ||
|
|
||
| sleep 2 | ||
|
|
||
| # Verify bridge is running | ||
| if ! ps -p $BRIDGE_PID > /dev/null 2>&1; then | ||
| echo "ERROR: Bridge process died!" | ||
| echo "Bridge log:" | ||
| cat /tmp/bridge.log || true | ||
| exit 1 | ||
| fi | ||
|
|
||
| # Also check if it shows up in ps | ||
| if ! ps aux | grep "socat.*2321" | grep -v grep > /dev/null; then | ||
| echo "WARNING: Bridge not found in ps, but PID file exists" | ||
| echo "Checking bridge log:" | ||
| cat /tmp/bridge.log || true | ||
| fi | ||
|
|
||
| echo "Bridge is running (PID: $BRIDGE_PID), connecting PTY $SERVER_PTY to socket localhost:2321" | ||
|
|
||
| - name: Build wolfTPM with UART support | ||
| env: | ||
| CLIENT_PTY: ${{ steps.uart.outputs.client_pty }} | ||
| run: | | ||
| cd ${{ github.workspace }} | ||
| ./autogen.sh | ||
| # Set UART device path via CPPFLAGS | ||
| # TPM2_SWTPM_PORT is already set by configure, so we only need to set HOST | ||
| # The quotes need to be passed through correctly to the C preprocessor | ||
| echo "Building with UART device: $CLIENT_PTY" | ||
| ./configure \ | ||
| --enable-swtpm=uart \ | ||
| --enable-debug \ | ||
| --with-wolfcrypt=${GITHUB_WORKSPACE}/wolfssl-install \ | ||
| CPPFLAGS="-DTPM2_SWTPM_HOST=\"${CLIENT_PTY}\"" | ||
| make -j$(nproc) | ||
|
|
||
| # Verify the define by checking the compiled code | ||
| echo "Verifying TPM2_SWTPM_HOST define..." | ||
| strings src/.libs/libwolftpm.so 2>/dev/null | grep -E "(ttyS0|pts)" | head -5 || echo "Cannot verify from library" | ||
|
|
||
| - name: Verify UART setup | ||
| env: | ||
| CLIENT_PTY: ${{ steps.uart.outputs.client_pty }} | ||
| SERVER_PTY: ${{ steps.uart.outputs.server_pty }} | ||
| run: | | ||
| echo "Verifying UART setup..." | ||
| echo "Client PTY: $CLIENT_PTY" | ||
| echo "Server PTY: $SERVER_PTY" | ||
|
|
||
| # Verify PTYs are still accessible | ||
| [ -c "$CLIENT_PTY" ] || (echo "Client PTY not found!" && exit 1) | ||
| [ -c "$SERVER_PTY" ] || (echo "Server PTY not found!" && exit 1) | ||
|
|
||
| # Verify swtpm is still running | ||
| ps aux | grep swtpm | grep -v grep || (echo "swtpm not running!" && exit 1) | ||
|
|
||
| # Verify bridge is running | ||
| ps aux | grep "socat.*2321" | grep -v grep || (echo "bridge not running!" && exit 1) | ||
|
|
||
| # Test socket connectivity to swtpm | ||
| timeout 2 bash -c 'until nc -z localhost 2321; do sleep 0.1; done' || (echo "Cannot connect to swtpm socket!" && exit 1) | ||
|
|
||
| echo "UART setup verified successfully" | ||
|
|
||
| - name: Run UART communication test | ||
| env: | ||
| CLIENT_PTY: ${{ steps.uart.outputs.client_pty }} | ||
| run: | | ||
| cd ${{ github.workspace }} | ||
|
|
||
| # Build the caps example with the same CPPFLAGS to ensure TPM2_SWTPM_HOST is defined | ||
| cd examples/wrap | ||
| # Re-export the CPPFLAGS to ensure the example build uses them | ||
| export CPPFLAGS="-DTPM2_SWTPM_HOST=\"${CLIENT_PTY}\"" | ||
| echo "Building caps with CPPFLAGS: $CPPFLAGS" | ||
| make caps CPPFLAGS="$CPPFLAGS" | ||
|
|
||
| echo "Running UART communication test..." | ||
| echo "Using UART device: $CLIENT_PTY" | ||
|
|
||
| # Verify bridge is still running | ||
| echo "Checking bridge status..." | ||
| if [ -f /tmp/bridge.pid ]; then | ||
| BRIDGE_PID=$(cat /tmp/bridge.pid) | ||
| if ps -p $BRIDGE_PID > /dev/null 2>&1; then | ||
| echo "Bridge is running (PID: $BRIDGE_PID)" | ||
| else | ||
| echo "WARNING: Bridge PID file exists but process is not running" | ||
| echo "Bridge log:" | ||
| cat /tmp/bridge.log 2>/dev/null || echo "No bridge log found" | ||
| fi | ||
| else | ||
| echo "WARNING: Bridge PID file not found" | ||
| fi | ||
| ps aux | grep "socat.*2321" | grep -v grep || echo "WARNING: Bridge process not found in ps" | ||
|
|
||
| # Test basic PTY connectivity | ||
| echo "Testing PTY connectivity..." | ||
| timeout 1 cat $CLIENT_PTY > /dev/null 2>&1 || echo "PTY read test (may timeout, that's ok)" | ||
|
|
||
| # Run the test with a timeout and capture all output | ||
| # The test should connect to the PTY as if it were a UART device | ||
| echo "Starting caps test..." | ||
| set +e # Don't exit on error so we can capture output | ||
| # Run with stderr to stdout to capture all output | ||
| timeout 30 ./caps > /tmp/caps_output.log 2>&1 | ||
| CAPS_RC=$? | ||
| set -e | ||
|
|
||
| # Also check if we can manually test the connection | ||
| echo "Testing manual connection..." | ||
| echo "test" | timeout 1 cat $CLIENT_PTY > /dev/null 2>&1 || echo "Manual PTY test (may timeout)" | ||
|
|
||
| if [ $CAPS_RC -ne 0 ]; then | ||
| echo "Test failed with exit code $CAPS_RC" | ||
| echo "=== Test output ===" | ||
| cat /tmp/caps_output.log || true | ||
| echo "=== Checking processes ===" | ||
| echo "swtpm:" | ||
| ps aux | grep swtpm | grep -v grep || echo "swtpm is not running" | ||
| echo "bridge:" | ||
| ps aux | grep "socat.*2321" | grep -v grep || echo "bridge is not running" | ||
| echo "PTY pair:" | ||
| ps aux | grep "socat.*pty" | grep -v grep || echo "PTY pair is not running" | ||
| echo "PTY devices:" | ||
| ls -la $CLIENT_PTY || echo "Client PTY not found" | ||
| exit 1 | ||
| else | ||
| echo "=== Test output ===" | ||
| cat /tmp/caps_output.log || true | ||
| fi | ||
|
|
||
| echo "UART communication test passed!" | ||
|
|
||
| - name: Cleanup | ||
| if: always() | ||
| run: | | ||
| # Kill bridge | ||
| if [ -f /tmp/bridge.pid ]; then | ||
| kill $(cat /tmp/bridge.pid) 2>/dev/null || true | ||
| fi | ||
|
|
||
| # Kill socat PTY pair | ||
| if [ -f /tmp/socat.pid ]; then | ||
| kill $(cat /tmp/socat.pid) 2>/dev/null || true | ||
| fi | ||
|
|
||
| # Kill swtpm | ||
| if [ -f /tmp/swtpm.pid ]; then | ||
| kill $(cat /tmp/swtpm.pid) 2>/dev/null || true | ||
| pkill -f "swtpm socket" 2>/dev/null || true | ||
| fi | ||
|
|
||
| # Clean up PTY links | ||
| rm -f /tmp/tpm-uart-server /tmp/tpm-uart-client |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -242,7 +242,7 @@ AC_ARG_WITH([swtpm-port], | |||||
| ] | ||||||
| ) | ||||||
|
|
||||||
| if test "x$ENABLED_SWTPM" = "xyes" | ||||||
| if test "x$ENABLED_SWTPM" != "xno" | ||||||
| then | ||||||
| if test "x$ENABLED_DEVTPM" = "xyes" | ||||||
| then | ||||||
|
|
@@ -252,6 +252,16 @@ then | |||||
| AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_SWTPM" | ||||||
| AM_CFLAGS="$AM_CFLAGS -DTPM2_SWTPM_PORT=$SWTPM_PORT" | ||||||
|
|
||||||
| if test "x$ENABLED_SWTPM" = "xuart" | ||||||
| then | ||||||
| AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_SWTPM_UART" | ||||||
| fi | ||||||
|
|
||||||
| if test "x$ENABLED_SWTPM" = "xuartns550" | ||||||
| then | ||||||
| AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_SWTPM_UARTNS550" | ||||||
| fi | ||||||
|
|
||||||
| # Set distcheck flag if port is not default (only when SWTPM is enabled) | ||||||
| if test "x$SWTPM_PORT" != "x2321"; then | ||||||
| DISTCHECK_SWTPM_PORT_FLAG="--with-swtpm-port=$SWTPM_PORT" | ||||||
|
|
@@ -278,7 +288,7 @@ AC_ARG_ENABLE([winapi], | |||||
|
|
||||||
| if test "x$ENABLED_WINAPI" = "xyes" || test "x$ENABLED_WINTBS" = "xyes" | ||||||
| then | ||||||
| if test "x$ENABLED_DEVTPM" = "xyes" -o "x$ENABLED_SWTPM" = "xyes" | ||||||
| if test "x$ENABLED_DEVTPM" = "xyes" -o "x$ENABLED_SWTPM" != "xno" | ||||||
| then | ||||||
| AC_MSG_ERROR([Cannot enable swtpm or devtpm with windows API]) | ||||||
| fi | ||||||
|
|
@@ -425,7 +435,7 @@ AC_ARG_ENABLE([hal], | |||||
| [ ENABLED_EXAMPLE_HAL=$enableval ], | ||||||
| [ ENABLED_EXAMPLE_HAL=yes ] | ||||||
| ) | ||||||
| if test "x$ENABLED_EXAMPLE_HAL" = "xyes" | ||||||
| if test "x$ENABLED_EXAMPLE_HAL" = "xyes" || test "x$ENABLED_MMIO" = "xyes" | ||||||
| then | ||||||
| AM_CFLAGS="$AM_CFLAGS -DWOLFTPM_EXAMPLE_HAL" | ||||||
| fi | ||||||
|
|
@@ -485,13 +495,13 @@ AM_CONDITIONAL([BUILD_ST], [test "x$ENABLED_ST" = "xyes"]) | |||||
| AM_CONDITIONAL([BUILD_MICROCHIP], [test "x$ENABLED_MICROCHIP" = "xyes"]) | ||||||
| AM_CONDITIONAL([BUILD_INFINEON], [test "x$ENABLED_INFINEON" != "xno"]) | ||||||
| AM_CONDITIONAL([BUILD_DEVTPM], [test "x$ENABLED_DEVTPM" = "xyes"]) | ||||||
| AM_CONDITIONAL([BUILD_SWTPM], [test "x$ENABLED_SWTPM" = "xyes"]) | ||||||
| AM_CONDITIONAL([BUILD_SWTPM], [test "x$ENABLED_SWTPM" != "xno"]) | ||||||
| AM_CONDITIONAL([BUILD_WINAPI], [test "x$ENABLED_WINAPI" = "xyes"]) | ||||||
| AM_CONDITIONAL([BUILD_NUVOTON], [test "x$ENABLED_NUVOTON" = "xyes"]) | ||||||
| AM_CONDITIONAL([BUILD_CHECKWAITSTATE], [test "x$ENABLED_CHECKWAITSTATE" = "xyes"]) | ||||||
| AM_CONDITIONAL([BUILD_AUTODETECT], [test "x$ENABLED_AUTODETECT" = "xyes"]) | ||||||
| AM_CONDITIONAL([BUILD_FIRMWARE], [test "x$ENABLED_FIRMWARE" = "xyes"]) | ||||||
| AM_CONDITIONAL([BUILD_HAL], [test "x$ENABLED_EXAMPLE_HAL" = "xyes" || test "x$ENABLED_MMIO" = "xyes"]) | ||||||
| AM_CONDITIONAL([BUILD_HAL], [test "x$ENABLED_EXAMPLE_HAL" = "xyes"]) | ||||||
|
||||||
| AM_CONDITIONAL([BUILD_HAL], [test "x$ENABLED_EXAMPLE_HAL" = "xyes"]) | |
| AM_CONDITIONAL([BUILD_HAL], [test "x$ENABLED_EXAMPLE_HAL" = "xyes" -o "x$ENABLED_MMIO" = "xyes"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change from "x$ENABLED_EXAMPLE_HAL" = "xyes" on line 438 now includes "|| test x$ENABLED_MMIO = xyes", but line 504 removes the same MMIO check from BUILD_HAL. This creates an inconsistency: WOLFTPM_EXAMPLE_HAL will be defined when MMIO is enabled (line 440), but BUILD_HAL won't be set for MMIO. This will cause build issues where the HAL code is conditionally compiled but not linked.