Skip to content

Commit 5f49d65

Browse files
add uart CI test
1 parent dc2caed commit 5f49d65

3 files changed

Lines changed: 268 additions & 1 deletion

File tree

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
name: Test UART Communication with SWTPM
2+
3+
on:
4+
push:
5+
branches: [ 'master', 'main', 'release/**' ]
6+
pull_request:
7+
branches: [ 'master', 'main', 'release/**' ]
8+
workflow_dispatch:
9+
10+
jobs:
11+
test-uart-swtpm:
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
18+
- name: Install basic dependencies
19+
run: |
20+
sudo apt-get update
21+
sudo apt-get install -y \
22+
automake \
23+
autotools-dev \
24+
libtool \
25+
pkg-config \
26+
gcc \
27+
make \
28+
git \
29+
socat \
30+
strace \
31+
acl
32+
33+
- name: Install swtpm
34+
run: |
35+
sudo apt-get install -y swtpm swtpm-tools
36+
37+
- name: Setup wolfSSL
38+
uses: actions/checkout@v4
39+
with:
40+
repository: wolfssl/wolfssl
41+
path: wolfssl
42+
43+
- name: Build wolfSSL
44+
working-directory: ./wolfssl
45+
run: |
46+
./autogen.sh
47+
./configure --enable-wolftpm --prefix=$PWD/../wolfssl-install
48+
make -j$(nproc)
49+
make install
50+
51+
- name: Create virtual UART pair
52+
id: uart
53+
run: |
54+
echo "=== Debug: Current user and groups ==="
55+
id
56+
whoami
57+
groups
58+
59+
echo "=== Debug: /dev/pts mount and permissions ==="
60+
mount | grep pts || true
61+
ls -la /dev/pts/ || true
62+
cat /proc/mounts | grep pts || true
63+
64+
# Create a PTY pair for UART simulation using socat
65+
# This creates two pseudo-terminals that are connected
66+
# One end will be used by swtpm (server side)
67+
# The other end will be used by wolfTPM (client side, as UART device)
68+
socat -d -d pty,raw,echo=0,link=/tmp/tpm-uart-server pty,raw,echo=0,link=/tmp/tpm-uart-client &
69+
SOCAT_PID=$!
70+
echo $SOCAT_PID > /tmp/socat.pid
71+
sleep 2
72+
73+
# Get the actual PTY device names
74+
SERVER_PTY=$(readlink -f /tmp/tpm-uart-server)
75+
CLIENT_PTY=$(readlink -f /tmp/tpm-uart-client)
76+
77+
echo "server_pty=$SERVER_PTY" >> $GITHUB_OUTPUT
78+
echo "client_pty=$CLIENT_PTY" >> $GITHUB_OUTPUT
79+
80+
echo "=== Debug: PTY details ==="
81+
echo "Server PTY (for swtpm): $SERVER_PTY"
82+
echo "Client PTY (for wolfTPM): $CLIENT_PTY"
83+
84+
# Detailed PTY info
85+
ls -la $SERVER_PTY $CLIENT_PTY || exit 1
86+
stat $SERVER_PTY $CLIENT_PTY || true
87+
88+
# Check if we can actually read/write to PTYs
89+
echo "=== Debug: Testing PTY access ==="
90+
test -r $SERVER_PTY && echo "Server PTY is readable" || echo "Server PTY NOT readable"
91+
test -w $SERVER_PTY && echo "Server PTY is writable" || echo "Server PTY NOT writable"
92+
test -r $CLIENT_PTY && echo "Client PTY is readable" || echo "Client PTY NOT readable"
93+
test -w $CLIENT_PTY && echo "Client PTY is writable" || echo "Client PTY NOT writable"
94+
95+
# Check getfacl if available
96+
echo "=== Debug: ACLs (if available) ==="
97+
getfacl $SERVER_PTY 2>/dev/null || echo "getfacl not available"
98+
99+
# Check socat process
100+
echo "=== Debug: socat process ==="
101+
ps aux | grep socat | grep -v grep || true
102+
103+
- name: Start swtpm with chardev (UART)
104+
run: |
105+
SERVER_PTY="${{ steps.uart.outputs.server_pty }}"
106+
mkdir -p /tmp/swtpm-state
107+
108+
echo "=== Debug: Pre-swtpm checks ==="
109+
echo "SERVER_PTY=$SERVER_PTY"
110+
ls -la $SERVER_PTY
111+
stat $SERVER_PTY
112+
113+
echo "=== Debug: Current user context ==="
114+
id
115+
116+
echo "=== Debug: Try to open PTY with dd (test access) ==="
117+
timeout 1 dd if=$SERVER_PTY of=/dev/null bs=1 count=0 2>&1 || echo "dd read test completed (may timeout, that's ok)"
118+
119+
echo "=== Debug: Check /dev/pts mount options ==="
120+
cat /proc/mounts | grep devpts
121+
122+
echo "=== Debug: swtpm version and help ==="
123+
swtpm --version || true
124+
swtpm chardev --help 2>&1 | head -20 || true
125+
126+
echo "=== Debug: Starting swtpm with strace (if available) ==="
127+
# Try with strace first to see exact syscall failure
128+
if command -v strace &> /dev/null; then
129+
strace -f -e trace=open,openat,access -o /tmp/swtpm_strace.log swtpm chardev \
130+
--tpm2 \
131+
--tpmstate dir=/tmp/swtpm-state \
132+
--chardev $SERVER_PTY \
133+
--flags not-need-init \
134+
--log level=20 &
135+
SWTPM_PID=$!
136+
sleep 3
137+
echo "=== Debug: strace output ==="
138+
cat /tmp/swtpm_strace.log || true
139+
else
140+
echo "strace not available, running without it"
141+
swtpm chardev \
142+
--tpm2 \
143+
--tpmstate dir=/tmp/swtpm-state \
144+
--chardev $SERVER_PTY \
145+
--flags not-need-init \
146+
--log level=20 &
147+
SWTPM_PID=$!
148+
sleep 3
149+
fi
150+
151+
echo $SWTPM_PID > /tmp/swtpm.pid
152+
153+
echo "=== Debug: Check if swtpm is running ==="
154+
ps aux | grep swtpm | grep -v grep
155+
156+
# Check for any error output
157+
echo "=== Debug: Check dmesg for PTY errors ==="
158+
dmesg | tail -20 2>/dev/null || echo "Cannot read dmesg"
159+
160+
# Verify swtpm is running
161+
if ! ps aux | grep swtpm | grep -v grep > /dev/null; then
162+
echo "ERROR: swtpm failed to start!"
163+
echo "=== Attempting alternative: test simple chardev open ==="
164+
# Try a simple C program to open the device
165+
cat > /tmp/test_open.c << 'CEOF'
166+
#include <stdio.h>
167+
#include <fcntl.h>
168+
#include <errno.h>
169+
#include <string.h>
170+
int main(int argc, char *argv[]) {
171+
if (argc < 2) return 1;
172+
int fd = open(argv[1], O_RDWR | O_NOCTTY);
173+
if (fd < 0) {
174+
printf("open(%s) failed: %s (errno=%d)\n", argv[1], strerror(errno), errno);
175+
return 1;
176+
}
177+
printf("open(%s) succeeded, fd=%d\n", argv[1], fd);
178+
close(fd);
179+
return 0;
180+
}
181+
CEOF
182+
gcc -o /tmp/test_open /tmp/test_open.c
183+
/tmp/test_open $SERVER_PTY
184+
exit 1
185+
fi
186+
187+
- name: Build wolfTPM with UART support
188+
env:
189+
CLIENT_PTY: ${{ steps.uart.outputs.client_pty }}
190+
run: |
191+
cd ${{ github.workspace }}
192+
./autogen.sh
193+
# Set UART device path and baud rate via CFLAGS
194+
# The device path needs to be properly quoted in the C define
195+
export CFLAGS="-DTPM2_SWTPM_HOST=\\\"$CLIENT_PTY\\\" -DTPM2_SWTPM_PORT=115200"
196+
echo "Building with UART device: $CLIENT_PTY"
197+
./configure \
198+
--enable-swtpm=uart \
199+
--with-wolfcrypt=$PWD/../wolfssl-install
200+
make -j$(nproc)
201+
202+
- name: Verify UART setup
203+
env:
204+
CLIENT_PTY: ${{ steps.uart.outputs.client_pty }}
205+
SERVER_PTY: ${{ steps.uart.outputs.server_pty }}
206+
run: |
207+
echo "Verifying UART setup..."
208+
echo "Client PTY: $CLIENT_PTY"
209+
echo "Server PTY: $SERVER_PTY"
210+
211+
# Verify PTYs are still accessible
212+
[ -c "$CLIENT_PTY" ] || (echo "Client PTY not found!" && exit 1)
213+
[ -c "$SERVER_PTY" ] || (echo "Server PTY not found!" && exit 1)
214+
215+
# Verify swtpm is still running
216+
ps aux | grep swtpm | grep -v grep || (echo "swtpm not running!" && exit 1)
217+
218+
echo "UART setup verified successfully"
219+
220+
- name: Run UART communication test
221+
env:
222+
CLIENT_PTY: ${{ steps.uart.outputs.client_pty }}
223+
run: |
224+
cd ${{ github.workspace }}
225+
226+
# Build the caps example
227+
cd examples/wrap
228+
make caps
229+
230+
echo "Running UART communication test..."
231+
echo "Using UART device: $CLIENT_PTY"
232+
233+
# Run the test with a timeout
234+
# The test should connect to the PTY as if it were a UART device
235+
timeout 30 ./caps || {
236+
echo "Test failed!"
237+
echo "Checking if swtpm is still running..."
238+
ps aux | grep swtpm | grep -v grep || echo "swtpm is not running"
239+
exit 1
240+
}
241+
242+
echo "UART communication test passed!"
243+
244+
- name: Cleanup
245+
if: always()
246+
run: |
247+
# Kill swtpm
248+
if [ -f /tmp/swtpm.pid ]; then
249+
kill $(cat /tmp/swtpm.pid) 2>/dev/null || true
250+
# Also try to kill any remaining swtpm processes
251+
pkill -f "swtpm chardev" 2>/dev/null || true
252+
fi
253+
254+
# Kill socat PTY pair
255+
if [ -f /tmp/socat.pid ]; then
256+
kill $(cat /tmp/socat.pid) 2>/dev/null || true
257+
fi
258+
259+
# Clean up PTY links
260+
rm -f /tmp/tpm-uart-server /tmp/tpm-uart-client

src/tpm2_swtpm.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,14 @@
4747
#ifdef WOLFTPM_ZEPHYR
4848
#include <zephyr/posix/unistd.h>
4949
#include <zephyr/net/socket.h>
50+
#include <zephyr/posix/sys/select.h>
5051
#elif defined(HAVE_UNISTD_H)
5152
#include <unistd.h>
5253
#endif
54+
/* select() is used for TCP socket mode, not UART mode */
55+
#if !defined(WOLFTPM_ZEPHYR) && !defined(WOLFTPM_SWTPM_UART) && !defined(WOLFTPM_SWTPM_UARTNS550)
56+
#include <sys/select.h>
57+
#endif
5358
#include <errno.h>
5459
#include <string.h> /* necessary for memset */
5560
#include <stdio.h> /* standard in/out procedures */

wolftpm/tpm2_types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,11 @@ typedef int64_t INT64;
298298

299299
/* Helper to convert macro to string */
300300
#ifndef XSTRINGIFY
301-
#define XSTRINGIFY(s) STRINGIFY(s)
301+
#ifndef STRINGIFY
302302
#define STRINGIFY(s) #s
303303
#endif
304+
#define XSTRINGIFY(s) STRINGIFY(s)
305+
#endif
304306

305307
/* ---------------------------------------------------------------------------*/
306308
/* TPM HARDWARE TYPE */

0 commit comments

Comments
 (0)