Skip to content

Commit 1847c6e

Browse files
authored
Merge pull request #9721 from dgarske/x25519_nb
Add X25519 non-blocking support and async example improvements
2 parents cb169ca + bc12b75 commit 1847c6e

39 files changed

+2713
-550
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
name: Async Examples
2+
3+
on:
4+
push:
5+
branches: [ 'master', 'main', 'release/**' ]
6+
pull_request:
7+
branches: [ '*' ]
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
async_examples:
15+
if: github.repository_owner == 'wolfssl'
16+
runs-on: ubuntu-24.04
17+
timeout-minutes: 10
18+
strategy:
19+
fail-fast: false
20+
matrix:
21+
extra_cflags:
22+
- ''
23+
- '-DWOLFSSL_SMALL_CERT_VERIFY'
24+
- '-DWOLFSSL_STATIC_MEMORY'
25+
name: Async Examples (${{ matrix.extra_cflags || 'default' }})
26+
steps:
27+
- uses: actions/checkout@v4
28+
name: Checkout wolfSSL
29+
30+
- name: Build async examples (no configure)
31+
run: |
32+
make -C examples/async clean
33+
make -C examples/async EXTRA_CFLAGS="${{ matrix.extra_cflags }}"
34+
35+
- name: Run async examples
36+
run: |
37+
set -euo pipefail
38+
39+
MIN_PENDING=100
40+
41+
run_pair() {
42+
local label="$1"
43+
shift
44+
local args="$*"
45+
local ready="/tmp/wolfssl_async_ready_${label}"
46+
rm -f "$ready"
47+
48+
WOLFSSL_ASYNC_READYFILE="$ready" \
49+
./examples/async/async_server $args \
50+
> "/tmp/async_server_${label}.log" 2>&1 &
51+
local pid=$!
52+
53+
WOLFSSL_ASYNC_READYFILE="$ready" \
54+
./examples/async/async_client $args 127.0.0.1 11111 \
55+
> "/tmp/async_client_${label}.log" 2>&1
56+
local rc=$?
57+
58+
kill "$pid" >/dev/null 2>&1 || true
59+
wait "$pid" >/dev/null 2>&1 || true
60+
61+
if [ "$rc" -ne 0 ]; then
62+
echo "FAIL: $label (exit=$rc)"
63+
return 1
64+
fi
65+
66+
# Validate WC_PENDING_E count is a proper value
67+
local count
68+
count=$(awk '/WC_PENDING_E count:/ {print $NF}' \
69+
"/tmp/async_client_${label}.log")
70+
if [ -z "$count" ] || [ "$count" -lt "$MIN_PENDING" ]; then
71+
echo "FAIL: $label - WC_PENDING_E count too low:" \
72+
"${count:-missing} (expected >= $MIN_PENDING)"
73+
return 1
74+
fi
75+
echo "PASS: $label (WC_PENDING_E: $count)"
76+
return 0
77+
}
78+
79+
# TLS 1.3
80+
run_pair ecc_tls13 --ecc
81+
run_pair x25519_tls13 --x25519
82+
83+
# TLS 1.2
84+
run_pair ecc_tls12 --tls12 --ecc
85+
run_pair x25519_tls12 --tls12 --x25519
86+
87+
# TLS 1.3 mutual auth
88+
run_pair ecc_tls13_mutual --mutual --ecc
89+
run_pair x25519_tls13_mutual --mutual --x25519
90+
91+
# TLS 1.2 mutual auth
92+
run_pair ecc_tls12_mutual --mutual --tls12 --ecc
93+
run_pair x25519_tls12_mutual --mutual --tls12 --x25519
94+
95+
96+
- name: Print async logs
97+
if: ${{ failure() }}
98+
run: |
99+
for f in /tmp/async_server_*.log /tmp/async_client_*.log; do
100+
if [ -f "$f" ]; then
101+
echo "==> $f"
102+
cat "$f"
103+
fi
104+
done

.github/workflows/os-check.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ jobs:
8484
'--enable-all CPPFLAGS=-DWOLFSSL_NO_CLIENT_AUTH',
8585
'--enable-all CPPFLAGS=''-DNO_WOLFSSL_CLIENT -DWOLFSSL_NO_CLIENT_AUTH''',
8686
'--enable-all CPPFLAGS=''-DNO_WOLFSSL_SERVER -DWOLFSSL_NO_CLIENT_AUTH''',
87+
'--enable-curve25519=nonblock --enable-ecc=nonblock --enable-sp=yes,nonblock CPPFLAGS="-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DEBUG_NONBLOCK"',
88+
'--enable-certreq --enable-certext --enable-certgen --disable-secure-renegotiation-info CPPFLAGS="-DNO_TLS"',
8789
]
8890
name: make check
8991
if: github.repository_owner == 'wolfssl'
@@ -130,6 +132,7 @@ jobs:
130132
'examples/configs/user_settings_dtls13.h',
131133
'examples/configs/user_settings_EBSnet.h',
132134
'examples/configs/user_settings_eccnonblock.h',
135+
'examples/configs/user_settings_curve25519nonblock.h',
133136
'examples/configs/user_settings_min_ecc.h',
134137
'examples/configs/user_settings_openssl_compat.h',
135138
'examples/configs/user_settings_pkcs7.h',

.wolfssl_known_macro_extras

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ MUTEX_DURING_INIT
354354
NEED_THREADX_TYPES
355355
NETX_DUO
356356
NET_SECURE_MODULE_EN
357+
NET_GETDEVRANDOM
357358
NOTE_TRIGGER
358359
NO_AES_DECRYPT
359360
NO_ARDUINO_DEFAULT
@@ -619,13 +620,13 @@ WC_ASYNC_NO_SHA256
619620
WC_ASYNC_NO_SHA3
620621
WC_ASYNC_NO_SHA384
621622
WC_ASYNC_NO_SHA512
623+
WC_ASYNC_NO_X25519
622624
WC_ASYNC_THREAD_BIND
623625
WC_CACHE_RESISTANT_BASE64_TABLE
624626
WC_DILITHIUM_CACHE_PRIV_VECTORS
625627
WC_DILITHIUM_CACHE_PUB_VECTORS
626628
WC_DILITHIUM_FIXED_ARRAY
627629
WC_DISABLE_RADIX_ZERO_PAD
628-
WC_ECC_NONBLOCK_ONLY
629630
WC_FLAG_DONT_USE_AESNI
630631
WC_FORCE_LINUXKM_FORTIFY_SOURCE
631632
WC_LMS_FULL_HASH

configure.ac

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4847,11 +4847,18 @@ ENABLED_ED25519_SMALL=no
48474847

48484848
# CURVE25519
48494849
AC_ARG_ENABLE([curve25519],
4850-
[AS_HELP_STRING([--enable-curve25519],[Enable Curve25519 (default: disabled)])],
4850+
[AS_HELP_STRING([--enable-curve25519],[Enable Curve25519 (default: disabled). Set to "nonblock" to enable non-blocking support for key gen and shared secret])],
48514851
[ ENABLED_CURVE25519=$enableval ],
48524852
[ ENABLED_CURVE25519=no ]
48534853
)
48544854

4855+
# Handle curve25519 nonblock option - enable asynccrypt and asynccrypt-sw early
4856+
if test "$ENABLED_CURVE25519" = "nonblock"
4857+
then
4858+
test -z "$enable_asynccrypt" && enable_asynccrypt=yes
4859+
test -z "$enable_asynccrypt_sw" && enable_asynccrypt_sw=yes
4860+
fi
4861+
48554862
if test "$ENABLED_CURVE25519" = "no" && test "$ENABLED_QUIC" = "yes" && test "$ENABLED_FIPS" = "no"
48564863
then
48574864
ENABLED_CURVE25519=yes
@@ -10362,12 +10369,17 @@ fi
1036210369
1036310370
if test "$ENABLED_CURVE25519" != "no"
1036410371
then
10365-
if test "$ENABLED_CURVE25519" = "small" || test "$ENABLED_LOWRESOURCE" = "yes"
10372+
if test "$ENABLED_CURVE25519" = "small" || test "$ENABLED_CURVE25519" = "nonblock" || test "$ENABLED_LOWRESOURCE" = "yes"
1036610373
then
1036710374
AM_CFLAGS="$AM_CFLAGS -DCURVE25519_SMALL"
1036810375
ENABLED_CURVE25519_SMALL=yes
1036910376
fi
1037010377
10378+
if test "$ENABLED_CURVE25519" = "nonblock"
10379+
then
10380+
AM_CFLAGS="$AM_CFLAGS -DWC_X25519_NONBLOCK"
10381+
fi
10382+
1037110383
if test "$ENABLED_CURVE25519" = "no128bit" || test "$ENABLED_32BIT" = "yes"
1037210384
then
1037310385
AM_CFLAGS="$AM_CFLAGS -DNO_CURVED25519_128BIT"

doc/dox_comments/header_files/ecc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2093,7 +2093,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
20932093
\return 0 Returned upon successfully setting the callback context the input message
20942094
20952095
\param key pointer to the ecc_key object
2096-
\param ctx pointer to ecc_nb_ctx_t structure with stack data cache for SP
2096+
\param ctx pointer to ecc nb_ctx_t structure with stack data cache for SP
20972097
20982098
_Example_
20992099
\code

examples/async/Makefile

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
CC ?= gcc
2+
AR ?= ar
3+
RM ?= rm -f
4+
5+
WOLFSSL_TOP ?= $(abspath ../..)
6+
OBJDIR ?= build
7+
8+
CFLAGS ?= -O0 -g
9+
CFLAGS += -I.
10+
CFLAGS += -I$(WOLFSSL_TOP)
11+
CFLAGS += -I$(WOLFSSL_TOP)/wolfssl
12+
CFLAGS += -I$(WOLFSSL_TOP)/wolfssl/wolfcrypt
13+
CFLAGS += -Wall -Wextra -Wpedantic -Werror
14+
CFLAGS += -DWOLFSSL_USER_SETTINGS
15+
CFLAGS += -DHAVE_SYS_TIME_H
16+
CFLAGS += -DUSE_CERT_BUFFERS_256
17+
CFLAGS += $(EXTRA_CFLAGS)
18+
19+
LDFLAGS ?=
20+
LDLIBS ?=
21+
22+
TARGETS = async_client async_server
23+
24+
WOLFSSL_SRC := $(wildcard $(WOLFSSL_TOP)/src/*.c)
25+
WOLFCRYPT_SRC := $(wildcard $(WOLFSSL_TOP)/wolfcrypt/src/*.c)
26+
LOCAL_SRC := async_client.c async_server.c async_tls.c
27+
28+
WOLFSSL_OBJS := $(patsubst $(WOLFSSL_TOP)/%, $(OBJDIR)/%, $(WOLFSSL_SRC:.c=.o))
29+
WOLFCRYPT_OBJS := $(patsubst $(WOLFSSL_TOP)/%, $(OBJDIR)/%, $(WOLFCRYPT_SRC:.c=.o))
30+
LOCAL_OBJS := $(patsubst %.c, $(OBJDIR)/%.o, $(LOCAL_SRC))
31+
32+
ASYNC_CLIENT_OBJS := $(OBJDIR)/async_client.o $(OBJDIR)/async_tls.o
33+
ASYNC_SERVER_OBJS := $(OBJDIR)/async_server.o $(OBJDIR)/async_tls.o
34+
35+
all: $(TARGETS)
36+
37+
async_client: $(ASYNC_CLIENT_OBJS) $(WOLFSSL_OBJS) $(WOLFCRYPT_OBJS)
38+
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
39+
40+
async_server: $(ASYNC_SERVER_OBJS) $(WOLFSSL_OBJS) $(WOLFCRYPT_OBJS)
41+
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
42+
43+
$(OBJDIR)/%.o: %.c user_settings.h
44+
@mkdir -p $(dir $@)
45+
$(CC) $(CFLAGS) -c $< -o $@
46+
47+
$(OBJDIR)/%.o: $(WOLFSSL_TOP)/%.c
48+
@mkdir -p $(dir $@)
49+
$(CC) $(CFLAGS) -c $< -o $@
50+
51+
# Possibly empty files (avoids "warning: ISO C forbids an empty translation unit")
52+
$(OBJDIR)/wolfcrypt/src/ecc_fp.o: CFLAGS += -Wno-pedantic
53+
$(OBJDIR)/wolfcrypt/src/fips.o: CFLAGS += -Wno-pedantic
54+
$(OBJDIR)/wolfcrypt/src/fips_test.o: CFLAGS += -Wno-pedantic
55+
$(OBJDIR)/wolfcrypt/src/fipsv2.o: CFLAGS += -Wno-pedantic
56+
$(OBJDIR)/wolfcrypt/src/selftest.o: CFLAGS += -Wno-pedantic
57+
$(OBJDIR)/wolfcrypt/src/wolfcrypt_first.o: CFLAGS += -Wno-pedantic
58+
$(OBJDIR)/wolfcrypt/src/wolfcrypt_last.o: CFLAGS += -Wno-pedantic
59+
60+
clean:
61+
$(RM) -r $(OBJDIR) $(TARGETS)

examples/async/README.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,23 @@ Tested with:
1515
* `./configure --enable-asynccrypt --enable-pkcallbacks --disable-rsa --enable-ecc`
1616

1717
```
18-
make
19-
./examples/async/async_server
20-
./examples/async/async_client 127.0.0.1
18+
make -C examples/async
19+
./examples/async/async_server --ecc
20+
./examples/async/async_client --ecc 127.0.0.1 11111
21+
./examples/async/async_client --x25519 ecc256.badssl.com 443
2122
```
2223

24+
Optional ready-file sync (CI-friendly, avoids sleeps):
25+
```
26+
export WOLFSSL_ASYNC_READYFILE=/tmp/wolfssl_async_ready
27+
./examples/async/async_server --ecc
28+
WOLFSSL_ASYNC_READYFILE=/tmp/wolfssl_async_ready ./examples/async/async_client --ecc 127.0.0.1 11111
29+
```
30+
31+
Porting the TCP/IP stack:
32+
Define `NET_USER_HEADER` to include your network shim and provide the
33+
`NET_*` macros plus `NET_IO_SEND_CB` / `NET_IO_RECV_CB`.
34+
2335
## Asynchronous Cryptography Design
2436

2537
When a cryptographic call is handed off to hardware it return `WC_PENDING_E` up to caller. Then it can keep calling until the operation completes. For some platforms it is required to call `wolfSSL_AsyncPoll`. At the TLS layer a "devId" (Device ID) must be set using `wolfSSL_CTX_SetDevId` to indicate desire to offload cryptography.

0 commit comments

Comments
 (0)