Merge pull request #9721 from dgarske/x25519_nb

Add X25519 non-blocking support and async example improvements
This commit is contained in:
Sean Parkinson
2026-02-12 07:56:58 +10:00
committed by GitHub
39 changed files with 2727 additions and 564 deletions
+104
View File
@@ -0,0 +1,104 @@
name: Async Examples
on:
push:
branches: [ 'master', 'main', 'release/**' ]
pull_request:
branches: [ '*' ]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
async_examples:
if: github.repository_owner == 'wolfssl'
runs-on: ubuntu-24.04
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
extra_cflags:
- ''
- '-DWOLFSSL_SMALL_CERT_VERIFY'
- '-DWOLFSSL_STATIC_MEMORY'
name: Async Examples (${{ matrix.extra_cflags || 'default' }})
steps:
- uses: actions/checkout@v4
name: Checkout wolfSSL
- name: Build async examples (no configure)
run: |
make -C examples/async clean
make -C examples/async EXTRA_CFLAGS="${{ matrix.extra_cflags }}"
- name: Run async examples
run: |
set -euo pipefail
MIN_PENDING=100
run_pair() {
local label="$1"
shift
local args="$*"
local ready="/tmp/wolfssl_async_ready_${label}"
rm -f "$ready"
WOLFSSL_ASYNC_READYFILE="$ready" \
./examples/async/async_server $args \
> "/tmp/async_server_${label}.log" 2>&1 &
local pid=$!
WOLFSSL_ASYNC_READYFILE="$ready" \
./examples/async/async_client $args 127.0.0.1 11111 \
> "/tmp/async_client_${label}.log" 2>&1
local rc=$?
kill "$pid" >/dev/null 2>&1 || true
wait "$pid" >/dev/null 2>&1 || true
if [ "$rc" -ne 0 ]; then
echo "FAIL: $label (exit=$rc)"
return 1
fi
# Validate WC_PENDING_E count is a proper value
local count
count=$(awk '/WC_PENDING_E count:/ {print $NF}' \
"/tmp/async_client_${label}.log")
if [ -z "$count" ] || [ "$count" -lt "$MIN_PENDING" ]; then
echo "FAIL: $label - WC_PENDING_E count too low:" \
"${count:-missing} (expected >= $MIN_PENDING)"
return 1
fi
echo "PASS: $label (WC_PENDING_E: $count)"
return 0
}
# TLS 1.3
run_pair ecc_tls13 --ecc
run_pair x25519_tls13 --x25519
# TLS 1.2
run_pair ecc_tls12 --tls12 --ecc
run_pair x25519_tls12 --tls12 --x25519
# TLS 1.3 mutual auth
run_pair ecc_tls13_mutual --mutual --ecc
run_pair x25519_tls13_mutual --mutual --x25519
# TLS 1.2 mutual auth
run_pair ecc_tls12_mutual --mutual --tls12 --ecc
run_pair x25519_tls12_mutual --mutual --tls12 --x25519
- name: Print async logs
if: ${{ failure() }}
run: |
for f in /tmp/async_server_*.log /tmp/async_client_*.log; do
if [ -f "$f" ]; then
echo "==> $f"
cat "$f"
fi
done
+3
View File
@@ -84,6 +84,8 @@ jobs:
'--enable-all CPPFLAGS=-DWOLFSSL_NO_CLIENT_AUTH',
'--enable-all CPPFLAGS=''-DNO_WOLFSSL_CLIENT -DWOLFSSL_NO_CLIENT_AUTH''',
'--enable-all CPPFLAGS=''-DNO_WOLFSSL_SERVER -DWOLFSSL_NO_CLIENT_AUTH''',
'--enable-curve25519=nonblock --enable-ecc=nonblock --enable-sp=yes,nonblock CPPFLAGS="-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DEBUG_NONBLOCK"',
'--enable-certreq --enable-certext --enable-certgen --disable-secure-renegotiation-info CPPFLAGS="-DNO_TLS"',
]
name: make check
if: github.repository_owner == 'wolfssl'
@@ -130,6 +132,7 @@ jobs:
'examples/configs/user_settings_dtls13.h',
'examples/configs/user_settings_EBSnet.h',
'examples/configs/user_settings_eccnonblock.h',
'examples/configs/user_settings_curve25519nonblock.h',
'examples/configs/user_settings_min_ecc.h',
'examples/configs/user_settings_openssl_compat.h',
'examples/configs/user_settings_pkcs7.h',
+2 -1
View File
@@ -354,6 +354,7 @@ MUTEX_DURING_INIT
NEED_THREADX_TYPES
NETX_DUO
NET_SECURE_MODULE_EN
NET_GETDEVRANDOM
NOTE_TRIGGER
NO_AES_DECRYPT
NO_ARDUINO_DEFAULT
@@ -619,13 +620,13 @@ WC_ASYNC_NO_SHA256
WC_ASYNC_NO_SHA3
WC_ASYNC_NO_SHA384
WC_ASYNC_NO_SHA512
WC_ASYNC_NO_X25519
WC_ASYNC_THREAD_BIND
WC_CACHE_RESISTANT_BASE64_TABLE
WC_DILITHIUM_CACHE_PRIV_VECTORS
WC_DILITHIUM_CACHE_PUB_VECTORS
WC_DILITHIUM_FIXED_ARRAY
WC_DISABLE_RADIX_ZERO_PAD
WC_ECC_NONBLOCK_ONLY
WC_FLAG_DONT_USE_AESNI
WC_FORCE_LINUXKM_FORTIFY_SOURCE
WC_LMS_FULL_HASH
+14 -2
View File
@@ -4847,11 +4847,18 @@ ENABLED_ED25519_SMALL=no
# CURVE25519
AC_ARG_ENABLE([curve25519],
[AS_HELP_STRING([--enable-curve25519],[Enable Curve25519 (default: disabled)])],
[AS_HELP_STRING([--enable-curve25519],[Enable Curve25519 (default: disabled). Set to "nonblock" to enable non-blocking support for key gen and shared secret])],
[ ENABLED_CURVE25519=$enableval ],
[ ENABLED_CURVE25519=no ]
)
# Handle curve25519 nonblock option - enable asynccrypt and asynccrypt-sw early
if test "$ENABLED_CURVE25519" = "nonblock"
then
test -z "$enable_asynccrypt" && enable_asynccrypt=yes
test -z "$enable_asynccrypt_sw" && enable_asynccrypt_sw=yes
fi
if test "$ENABLED_CURVE25519" = "no" && test "$ENABLED_QUIC" = "yes" && test "$ENABLED_FIPS" = "no"
then
ENABLED_CURVE25519=yes
@@ -10362,12 +10369,17 @@ fi
if test "$ENABLED_CURVE25519" != "no"
then
if test "$ENABLED_CURVE25519" = "small" || test "$ENABLED_LOWRESOURCE" = "yes"
if test "$ENABLED_CURVE25519" = "small" || test "$ENABLED_CURVE25519" = "nonblock" || test "$ENABLED_LOWRESOURCE" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DCURVE25519_SMALL"
ENABLED_CURVE25519_SMALL=yes
fi
if test "$ENABLED_CURVE25519" = "nonblock"
then
AM_CFLAGS="$AM_CFLAGS -DWC_X25519_NONBLOCK"
fi
if test "$ENABLED_CURVE25519" = "no128bit" || test "$ENABLED_32BIT" = "yes"
then
AM_CFLAGS="$AM_CFLAGS -DNO_CURVED25519_128BIT"
+1 -1
View File
@@ -2093,7 +2093,7 @@ int wc_ecc_decrypt(ecc_key* privKey, ecc_key* pubKey, const byte* msg,
\return 0 Returned upon successfully setting the callback context the input message
\param key pointer to the ecc_key object
\param ctx pointer to ecc_nb_ctx_t structure with stack data cache for SP
\param ctx pointer to ecc nb_ctx_t structure with stack data cache for SP
_Example_
\code
+61
View File
@@ -0,0 +1,61 @@
CC ?= gcc
AR ?= ar
RM ?= rm -f
WOLFSSL_TOP ?= $(abspath ../..)
OBJDIR ?= build
CFLAGS ?= -O0 -g
CFLAGS += -I.
CFLAGS += -I$(WOLFSSL_TOP)
CFLAGS += -I$(WOLFSSL_TOP)/wolfssl
CFLAGS += -I$(WOLFSSL_TOP)/wolfssl/wolfcrypt
CFLAGS += -Wall -Wextra -Wpedantic -Werror
CFLAGS += -DWOLFSSL_USER_SETTINGS
CFLAGS += -DHAVE_SYS_TIME_H
CFLAGS += -DUSE_CERT_BUFFERS_256
CFLAGS += $(EXTRA_CFLAGS)
LDFLAGS ?=
LDLIBS ?=
TARGETS = async_client async_server
WOLFSSL_SRC := $(wildcard $(WOLFSSL_TOP)/src/*.c)
WOLFCRYPT_SRC := $(wildcard $(WOLFSSL_TOP)/wolfcrypt/src/*.c)
LOCAL_SRC := async_client.c async_server.c async_tls.c
WOLFSSL_OBJS := $(patsubst $(WOLFSSL_TOP)/%, $(OBJDIR)/%, $(WOLFSSL_SRC:.c=.o))
WOLFCRYPT_OBJS := $(patsubst $(WOLFSSL_TOP)/%, $(OBJDIR)/%, $(WOLFCRYPT_SRC:.c=.o))
LOCAL_OBJS := $(patsubst %.c, $(OBJDIR)/%.o, $(LOCAL_SRC))
ASYNC_CLIENT_OBJS := $(OBJDIR)/async_client.o $(OBJDIR)/async_tls.o
ASYNC_SERVER_OBJS := $(OBJDIR)/async_server.o $(OBJDIR)/async_tls.o
all: $(TARGETS)
async_client: $(ASYNC_CLIENT_OBJS) $(WOLFSSL_OBJS) $(WOLFCRYPT_OBJS)
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
async_server: $(ASYNC_SERVER_OBJS) $(WOLFSSL_OBJS) $(WOLFCRYPT_OBJS)
$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
$(OBJDIR)/%.o: %.c user_settings.h
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR)/%.o: $(WOLFSSL_TOP)/%.c
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) -c $< -o $@
# Possibly empty files (avoids "warning: ISO C forbids an empty translation unit")
$(OBJDIR)/wolfcrypt/src/ecc_fp.o: CFLAGS += -Wno-pedantic
$(OBJDIR)/wolfcrypt/src/fips.o: CFLAGS += -Wno-pedantic
$(OBJDIR)/wolfcrypt/src/fips_test.o: CFLAGS += -Wno-pedantic
$(OBJDIR)/wolfcrypt/src/fipsv2.o: CFLAGS += -Wno-pedantic
$(OBJDIR)/wolfcrypt/src/selftest.o: CFLAGS += -Wno-pedantic
$(OBJDIR)/wolfcrypt/src/wolfcrypt_first.o: CFLAGS += -Wno-pedantic
$(OBJDIR)/wolfcrypt/src/wolfcrypt_last.o: CFLAGS += -Wno-pedantic
clean:
$(RM) -r $(OBJDIR) $(TARGETS)
+15 -3
View File
@@ -15,11 +15,23 @@ Tested with:
* `./configure --enable-asynccrypt --enable-pkcallbacks --disable-rsa --enable-ecc`
```
make
./examples/async/async_server
./examples/async/async_client 127.0.0.1
make -C examples/async
./examples/async/async_server --ecc
./examples/async/async_client --ecc 127.0.0.1 11111
./examples/async/async_client --x25519 ecc256.badssl.com 443
```
Optional ready-file sync (CI-friendly, avoids sleeps):
```
export WOLFSSL_ASYNC_READYFILE=/tmp/wolfssl_async_ready
./examples/async/async_server --ecc
WOLFSSL_ASYNC_READYFILE=/tmp/wolfssl_async_ready ./examples/async/async_client --ecc 127.0.0.1 11111
```
Porting the TCP/IP stack:
Define `NET_USER_HEADER` to include your network shim and provide the
`NET_*` macros plus `NET_IO_SEND_CB` / `NET_IO_RECV_CB`.
## Asynchronous Cryptography Design
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.
+479 -155
View File
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* TLS client demonstrating asynchronous cryptography features and optionally
* using the crypto or PK callbacks */
/* TLS client demonstrating asynchronous cryptography features and non-blocking
* operation using WOLFSSL_USER_IO callbacks. */
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -30,209 +30,533 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
/* socket */
#ifndef NET_USER_HEADER
#include <fcntl.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/select.h>
#include <unistd.h>
#endif
/* wolfSSL */
#ifndef WOLFSSL_USER_SETTINGS
#ifdef WOLFSSL_USER_SETTINGS
#include "user_settings.h"
#else
#include <wolfssl/options.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/ssl.h>
#include <wolfssl/wolfio.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/certs_test.h>
#include "examples/async/async_tls.h"
/* Test certificates and keys for RSA and ECC */
#ifndef NO_RSA
#define CERT_FILE "./certs/client-cert.pem"
#define KEY_FILE "./certs/client-key.pem"
#define CA_FILE "./certs/ca-cert.pem"
#elif defined(HAVE_ECC)
#define CERT_FILE "./certs/client-ecc-cert.pem"
#define KEY_FILE "./certs/ecc-client-key.pem"
#define CA_FILE "./certs/ca-ecc-cert.pem"
#else
#error No authentication algorithm (ECC/RSA)
/* ------------------------------------------------------------------ */
/* POSIX transport helpers (replace with your BSP/port layer). */
/* ------------------------------------------------------------------ */
#ifndef NET_USER_HEADER
static int posix_set_nonblocking(int fd)
{
int flags = fcntl(fd, F_GETFL, 0);
if (flags < 0) {
return -1;
}
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
static int posix_connect_nonblock(int fd, const struct sockaddr* sa,
socklen_t sa_len, int timeout_ms)
{
int ret = connect(fd, sa, sa_len);
if (ret == 0) {
return 0;
}
if (ret < 0 && errno != EINPROGRESS) {
return -1;
}
/* Wait for connect to finish. */
fd_set wfds;
struct timeval tv;
FD_ZERO(&wfds);
FD_SET(fd, &wfds);
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec = (timeout_ms % 1000) * 1000;
ret = select(fd + 1, NULL, &wfds, NULL, &tv);
if (ret <= 0) {
return -1;
}
if (FD_ISSET(fd, &wfds)) {
int so_err = 0;
socklen_t len = sizeof(so_err);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &so_err, &len) < 0) {
return -1;
}
if (so_err != 0) {
errno = so_err;
return -1;
}
return 0;
}
return -1;
}
static int posix_net_connect(const char* host, int port)
{
char port_str[8];
struct addrinfo hints;
struct addrinfo* res = NULL;
struct addrinfo* it = NULL;
int fd = -1;
int ret;
snprintf(port_str, sizeof(port_str), "%d", port);
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(host, port_str, &hints, &res) != 0) {
return -1;
}
for (it = res; it != NULL; it = it->ai_next) {
fd = socket(it->ai_family, it->ai_socktype, it->ai_protocol);
if (fd < 0) {
continue;
}
if (posix_set_nonblocking(fd) != 0) {
close(fd);
fd = -1;
continue;
}
ret = posix_connect_nonblock(fd, it->ai_addr,
(socklen_t)it->ai_addrlen, 5000);
if (ret == 0) {
break;
}
close(fd);
fd = -1;
}
if (res != NULL) {
freeaddrinfo(res);
}
return fd;
}
#endif
/* ------------------------------------------------------------------ */
/* WOLFSSL_USER_IO callbacks. */
/* ------------------------------------------------------------------ */
static void usage(const char* prog)
{
printf("usage: %s [--ecc|--x25519] [--mutual] [--tls12] [host] [port]\n",
prog);
}
static const char* group_name(word16 group)
{
switch (group) {
case WOLFSSL_ECC_SECP256R1:
return "secp256r1";
case WOLFSSL_ECC_X25519:
return "x25519";
default:
return "unknown";
}
}
static int parse_client_args(int argc, char** argv,
const char** host, int* port, word16* group, int* mutual, int* tls12)
{
int i;
int host_set = 0;
int port_set = 0;
*host = DEFAULT_TLS_HOST;
*port = DEFAULT_TLS_PORT;
*group = WOLFSSL_ECC_SECP256R1;
*mutual = 0;
*tls12 = 0;
for (i = 1; i < argc; i++) {
if (XSTRCMP(argv[i], "--ecc") == 0) {
*group = WOLFSSL_ECC_SECP256R1;
}
else if (XSTRCMP(argv[i], "--x25519") == 0) {
*group = WOLFSSL_ECC_X25519;
}
else if (XSTRCMP(argv[i], "--mutual") == 0) {
*mutual = 1;
}
else if (XSTRCMP(argv[i], "--tls12") == 0) {
*tls12 = 1;
}
else if (XSTRCMP(argv[i], "--help") == 0) {
return -1;
}
else if (!host_set) {
*host = argv[i];
host_set = 1;
}
else if (!port_set) {
*port = atoi(argv[i]);
port_set = 1;
}
else {
return -1;
}
}
return 0;
}
int client_async_test(int argc, char** argv)
{
int ret = 0;
int sockfd = SOCKET_INVALID;
struct sockaddr_in servAddr;
char buff[TEST_BUF_SZ];
size_t len;
int devId = 1; /* anything besides -2 (INVALID_DEVID) */
#ifdef WOLF_CRYPTO_CB
AsyncTlsCryptoCbCtx myCtx;
#endif
int err;
char errBuff[WOLFSSL_MAX_ERROR_SZ];
/* declare wolfSSL objects */
int ret = -1;
int net = -1;
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
WOLFSSL* ssl = NULL;
char rx[128];
char tx[256];
int tx_len = 0;
int err = 0;
#ifdef WOLFSSL_ASYNC_CRYPT
int devId = INVALID_DEVID;
#endif
#ifdef WOLFSSL_DEBUG_NONBLOCK
int wouldblock_count = 0;
int pending_count = 0;
#endif
#ifdef WOLFSSL_STATIC_MEMORY
static byte memory[300000];
static byte memoryIO[34500];
#if !defined(WOLFSSL_STATIC_MEMORY_LEAN)
WOLFSSL_MEM_CONN_STATS ssl_stats;
#endif
#endif
const char* host = NULL;
int port = 0;
word16 group = WOLFSSL_ECC_SECP256R1;
const char* mode = NULL;
int mutual = 0;
int tls12 = 0;
/* Check for proper calling convention */
if (argc != 2) {
printf("usage: %s <IPv4 address>\n", argv[0]);
if (parse_client_args(argc, argv, &host, &port, &group, &mutual,
&tls12) != 0) {
usage(argv[0]);
return 0;
}
mode = group_name(group);
printf("Async client mode: %s, TLS %s%s\n", mode,
tls12 ? "1.2" : "1.3", mutual ? ", mutual auth" : "");
/* Create a socket that uses an internet IPv4 address,
* Sets the socket to be stream based (TCP),
* 0 means choose the default protocol. */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "ERROR: failed to create the socket\n");
ret = -1; goto exit;
{
const char* ready = getenv(WOLFSSL_ASYNC_READYFILE_ENV);
if (ready != NULL) {
(void)async_readyfile_wait(ready,
WOLFSSL_ASYNC_READYFILE_TIMEOUT_MS);
}
}
net = NET_CONNECT(host, port);
if (net < 0) {
return -1;
}
/* Initialize the server address struct with zeros */
memset(&servAddr, 0, sizeof(servAddr));
/* Fill in the server address */
servAddr.sin_family = AF_INET; /* using IPv4 */
servAddr.sin_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */
/* Get the server IPv4 address from the command line call */
if (inet_pton(AF_INET, argv[1], &servAddr.sin_addr) != 1) {
fprintf(stderr, "ERROR: invalid address\n");
ret = -1; goto exit;
if (wolfSSL_Init() != WOLFSSL_SUCCESS) {
return -1;
}
/* Connect to the server */
if ((ret = connect(sockfd, (struct sockaddr*) &servAddr, sizeof(servAddr)))
== -1) {
fprintf(stderr, "ERROR: failed to connect\n");
goto exit;
}
/*---------------------------------*/
/* Start of wolfSSL initialization and configuration */
/*---------------------------------*/
#ifdef DEBUG_WOLFSSL
wolfSSL_Debugging_ON();
#endif
/* Initialize wolfSSL */
if ((ret = wolfSSL_Init()) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: Failed to initialize the library\n");
goto exit;
}
/* Create and initialize WOLFSSL_CTX */
if ((ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n");
ret = -1; goto exit;
}
#ifdef WOLF_CRYPTO_CB
XMEMSET(&myCtx, 0, sizeof(myCtx));
/* register a devID for crypto callbacks */
ret = wc_CryptoCb_RegisterDevice(devId, AsyncTlsCryptoCb, &myCtx);
if (ret != 0) {
fprintf(stderr, "wc_CryptoCb_RegisterDevice: error %d", ret);
goto exit;
#ifdef WOLFSSL_ASYNC_CRYPT
if (wolfAsync_DevOpenThread(&devId, NULL) != 0) {
goto out;
}
#endif
/* register a devID for crypto callbacks */
#ifdef WOLFSSL_STATIC_MEMORY
{
wolfSSL_method_func method;
#ifndef WOLFSSL_NO_TLS12
if (tls12)
method = wolfTLSv1_2_client_method_ex;
else
#endif
method = wolfSSLv23_client_method_ex;
if (wolfSSL_CTX_load_static_memory(&ctx, method, memory,
sizeof(memory), 0, 1) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: unable to load static memory\n");
goto out;
}
if (wolfSSL_CTX_load_static_memory(&ctx, NULL, memoryIO,
sizeof(memoryIO),
WOLFMEM_IO_POOL_FIXED | WOLFMEM_TRACK_STATS, 1)
!= WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: unable to load static IO memory\n");
goto out;
}
}
#else
#ifndef WOLFSSL_NO_TLS12
if (tls12)
ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
else
#endif
ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
#endif /* WOLFSSL_STATIC_MEMORY */
if (ctx == NULL) {
goto out;
}
#ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL_CTX_SetDevId(ctx, devId);
#endif
/* Load client certificate into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, WOLFSSL_FILETYPE_PEM))
!= WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
CERT_FILE);
goto exit;
if (mutual) {
if (group == WOLFSSL_ECC_X25519) {
#ifdef HAVE_ED25519
ret = wolfSSL_CTX_load_verify_buffer(ctx, ca_ed25519_cert,
sizeof_ca_ed25519_cert, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load ED25519 CA cert.\n");
goto out;
}
ret = wolfSSL_CTX_use_certificate_buffer(ctx, client_ed25519_cert,
sizeof_client_ed25519_cert, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load ED25519 client cert.\n");
goto out;
}
ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, client_ed25519_key,
sizeof_client_ed25519_key, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load ED25519 client key.\n");
goto out;
}
#else
fprintf(stderr,
"ERROR: --x25519 --mutual requires HAVE_ED25519\n");
goto out;
#endif
}
else {
ret = wolfSSL_CTX_load_verify_buffer(ctx, ca_ecc_cert_der_256,
sizeof_ca_ecc_cert_der_256, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load ECC CA cert.\n");
goto out;
}
ret = wolfSSL_CTX_use_certificate_buffer(ctx, cliecc_cert_der_256,
sizeof_cliecc_cert_der_256, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load ECC client cert.\n");
goto out;
}
ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, ecc_clikey_der_256,
sizeof_ecc_clikey_der_256, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load ECC client key.\n");
goto out;
}
}
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_PEER, NULL);
}
else {
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL);
}
/* Load client key into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, WOLFSSL_FILETYPE_PEM))
!= WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
KEY_FILE);
goto exit;
wolfSSL_SetIORecv(ctx, NET_IO_RECV_CB);
wolfSSL_SetIOSend(ctx, NET_IO_SEND_CB);
wolfSSL_CTX_UseSNI(ctx, WOLFSSL_SNI_HOST_NAME, host,
(word16)XSTRLEN(host));
ssl = wolfSSL_new(ctx);
if (ssl == NULL) {
goto out;
}
/* Load CA certificate into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CA_FILE, NULL))
!= WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
CA_FILE);
goto exit;
wolfSSL_SetIOReadCtx(ssl, (void*)(intptr_t)net);
wolfSSL_SetIOWriteCtx(ssl, (void*)(intptr_t)net);
(void)wolfSSL_UseSNI(ssl, WOLFSSL_SNI_HOST_NAME, host,
(word16)XSTRLEN(host));
/* UseKeyShare is TLS 1.3 only */
if (!tls12) {
for (;;) {
ret = wolfSSL_UseKeyShare(ssl, group);
if (ret == WOLFSSL_SUCCESS) {
break;
}
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
#ifdef WOLFSSL_DEBUG_NONBLOCK
pending_count++;
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
if (wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW) < 0) {
goto out;
}
#endif
continue;
}
goto out;
}
}
/* Create a WOLFSSL object */
if ((ssl = wolfSSL_new(ctx)) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL object\n");
ret = -1; goto exit;
/* Non-blocking style loop. */
for (;;) {
ret = wolfSSL_connect(ssl);
if (ret == WOLFSSL_SUCCESS) {
break;
}
err = wolfSSL_get_error(ssl, 0);
if (err == WC_NO_ERR_TRACE(WC_PENDING_E) ||
err == WOLFSSL_ERROR_WANT_READ ||
err == WOLFSSL_ERROR_WANT_WRITE) {
if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
#ifdef WOLFSSL_DEBUG_NONBLOCK
pending_count++;
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
if (wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW) < 0) {
goto out;
}
#endif
}
else {
#ifdef WOLFSSL_DEBUG_NONBLOCK
wouldblock_count++;
#endif
}
continue;
}
fprintf(stderr, "ERROR: wolfSSL_connect failed: %d (%s)\n",
err, wolfSSL_ERR_reason_error_string(err));
goto out;
}
/* Attach wolfSSL to the socket */
if ((ret = wolfSSL_set_fd(ssl, sockfd)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: Failed to set the file descriptor\n");
goto exit;
{
const char* cipher = wolfSSL_get_cipher_name(ssl);
const char* curve = wolfSSL_get_curve_name(ssl);
printf("Negotiated cipher: %s\n", cipher != NULL ? cipher : "unknown");
printf("Negotiated group: %s\n", curve != NULL ? curve : "unknown");
}
/* Connect to wolfSSL on the server side */
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_connect(ssl),
ret != WOLFSSL_SUCCESS);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "wolfSSL_connect error %d: %s\n",
err, wolfSSL_ERR_error_string(err, errBuff));
goto exit;
tx_len = XSNPRINTF(tx, sizeof(tx),
"GET / HTTP/1.1\r\n"
"Host: %s\r\n"
"User-Agent: wolfSSL-async\r\n"
"Connection: close\r\n"
"\r\n",
host);
if (tx_len <= 0 || tx_len >= (int)sizeof(tx)) {
goto out;
}
/* Get a message for the server from stdin */
printf("Message for server: ");
memset(buff, 0, sizeof(buff));
if (fgets(buff, sizeof(buff), stdin) == NULL) {
fprintf(stderr, "ERROR: failed to get message for server\n");
ret = -1; goto exit;
}
len = strnlen(buff, sizeof(buff));
/* Send the message to the server */
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_write(ssl, buff, (int)len),
ret <= 0);
if (ret != (int)len) {
fprintf(stderr, "wolfSSL_write error %d: %s\n",
err, wolfSSL_ERR_error_string(err, errBuff));
goto exit;
for (;;) {
ret = wolfSSL_write(ssl, tx, tx_len);
if (ret > 0) {
break;
}
err = wolfSSL_get_error(ssl, 0);
if (err == WC_NO_ERR_TRACE(WC_PENDING_E) ||
err == WOLFSSL_ERROR_WANT_READ ||
err == WOLFSSL_ERROR_WANT_WRITE) {
if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
#ifdef WOLFSSL_DEBUG_NONBLOCK
pending_count++;
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
if (wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW) < 0) {
goto out;
}
#endif
}
else {
#ifdef WOLFSSL_DEBUG_NONBLOCK
wouldblock_count++;
#endif
}
continue;
}
goto out;
}
/* Read the server data into our buff array */
memset(buff, 0, sizeof(buff));
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_read(ssl, buff, sizeof(buff)-1),
ret <= 0);
if (ret < 0) {
fprintf(stderr, "wolfSSL_read error %d: %s\n",
err, wolfSSL_ERR_error_string(err, errBuff));
goto exit;
XMEMSET(rx, 0, sizeof(rx));
for (;;) {
ret = wolfSSL_read(ssl, rx, (int)sizeof(rx) - 1);
if (ret > 0) {
rx[ret] = '\0';
printf("RX: %s\n", rx);
break;
}
err = wolfSSL_get_error(ssl, 0);
if (err == WC_NO_ERR_TRACE(WC_PENDING_E) ||
err == WOLFSSL_ERROR_WANT_READ ||
err == WOLFSSL_ERROR_WANT_WRITE) {
if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
#ifdef WOLFSSL_DEBUG_NONBLOCK
pending_count++;
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
if (wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW) < 0) {
goto out;
}
#endif
}
else {
#ifdef WOLFSSL_DEBUG_NONBLOCK
wouldblock_count++;
#endif
}
continue;
}
goto out;
}
/* Print to stdout any data the server sends */
printf("Server: %s\n", buff);
/* Return reporting a success */
#ifdef WOLFSSL_DEBUG_NONBLOCK
printf("WANT_READ/WRITE count: %d\n", wouldblock_count);
printf("WC_PENDING_E count: %d\n", pending_count);
#endif
ret = 0;
exit:
/* Cleanup and return */
if (sockfd != SOCKET_INVALID)
close(sockfd); /* Close the connection to the server */
if (ssl)
wolfSSL_free(ssl); /* Free the wolfSSL object */
if (ctx)
wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */
wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */
(void)argc;
(void)argv;
out:
#if defined(WOLFSSL_STATIC_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY_LEAN)
if (ssl != NULL &&
wolfSSL_is_static_memory(ssl, &ssl_stats) == 1) {
fprintf(stderr, "peak connection memory = %d\n",
ssl_stats.peakMem);
fprintf(stderr, "current memory in use = %d\n",
ssl_stats.curMem);
fprintf(stderr, "peak connection allocs = %d\n",
ssl_stats.peakAlloc);
fprintf(stderr, "total connection allocs = %d\n",
ssl_stats.totalAlloc);
fprintf(stderr, "total connection frees = %d\n",
ssl_stats.totalFr);
}
#endif
if (ssl != NULL) {
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl);
}
if (ctx != NULL) {
wolfSSL_CTX_free(ctx);
}
#ifdef WOLFSSL_ASYNC_CRYPT
if (devId != INVALID_DEVID) {
wolfAsync_DevClose(&devId);
}
#endif
wolfSSL_Cleanup();
if (net >= 0) {
NET_CLOSE(net);
}
return ret;
}
+397 -91
View File
@@ -19,8 +19,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* TLS server demonstrating asynchronous cryptography features and optionally
* using the crypto or PK callbacks */
/* TLS server demonstrating asynchronous cryptography features and non-blocking
* operation using WOLFSSL_USER_IO callbacks. */
#ifdef HAVE_CONFIG_H
#include <config.h>
@@ -30,12 +30,17 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
/* socket */
#ifndef NET_USER_HEADER
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#define HAVE_SIGNAL
#ifdef HAVE_SIGNAL
@@ -43,25 +48,26 @@
#endif
/* wolfSSL */
#ifndef WOLFSSL_USER_SETTINGS
#ifdef WOLFSSL_USER_SETTINGS
#include "user_settings.h"
#else
#include <wolfssl/options.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/ssl.h>
#include <wolfssl/wolfio.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/certs_test.h>
#include "examples/async/async_tls.h"
/* Test certificates and keys for RSA and ECC */
#ifndef NO_RSA
#define CERT_FILE "./certs/server-cert.pem"
#define KEY_FILE "./certs/server-key.pem"
#define CA_FILE "./certs/client-cert.pem"
#elif defined(HAVE_ECC)
#define CERT_FILE "./certs/server-ecc.pem"
#define KEY_FILE "./certs/ecc-key.pem"
#define CA_FILE "./certs/client-ecc-cert.pem"
#if ASYNC_ECC_ONLY
#ifndef HAVE_ECC
#error ASYNC_ECC_ONLY requires HAVE_ECC
#endif
#else
#error No authentication algorithm (ECC/RSA)
#ifndef NO_RSA
#error RSA not supported in this example configuration
#endif
#endif
static int mSockfd = SOCKET_INVALID;
@@ -79,19 +85,92 @@ static void sig_handler(const int sig)
mShutdown = 1;
if (mConnd != SOCKET_INVALID) {
close(mConnd); /* Close the connection to the client */
NET_CLOSE(mConnd);
mConnd = SOCKET_INVALID;
}
if (mSockfd != SOCKET_INVALID) {
close(mSockfd); /* Close the socket listening for clients */
NET_CLOSE(mSockfd);
mSockfd = SOCKET_INVALID;
}
}
#endif
/* ------------------------------------------------------------------ */
/* POSIX transport helpers (replace with your BSP/port layer). */
/* ------------------------------------------------------------------ */
#ifndef NET_USER_HEADER
static int posix_set_nonblocking(int fd)
{
int flags = fcntl(fd, F_GETFL, 0);
if (flags < 0) {
return -1;
}
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
#endif
/* ------------------------------------------------------------------ */
/* WOLFSSL_USER_IO callbacks. */
/* ------------------------------------------------------------------ */
static void usage(const char* prog)
{
printf("usage: %s [--ecc|--x25519] [--mutual] [--tls12] [port]\n", prog);
}
static const char* group_name(word16 group)
{
switch (group) {
case WOLFSSL_ECC_SECP256R1:
return "secp256r1";
case WOLFSSL_ECC_X25519:
return "x25519";
default:
return "unknown";
}
}
static int parse_server_args(int argc, char** argv, int* port, word16* group,
int* mutual, int* tls12)
{
int i;
int port_set = 0;
*port = DEFAULT_PORT;
*group = WOLFSSL_ECC_SECP256R1;
*mutual = 0;
*tls12 = 0;
for (i = 1; i < argc; i++) {
if (XSTRCMP(argv[i], "--ecc") == 0) {
*group = WOLFSSL_ECC_SECP256R1;
}
else if (XSTRCMP(argv[i], "--x25519") == 0) {
*group = WOLFSSL_ECC_X25519;
}
else if (XSTRCMP(argv[i], "--mutual") == 0) {
*mutual = 1;
}
else if (XSTRCMP(argv[i], "--tls12") == 0) {
*tls12 = 1;
}
else if (XSTRCMP(argv[i], "--help") == 0) {
return -1;
}
else if (!port_set) {
*port = atoi(argv[i]);
port_set = 1;
}
else {
return -1;
}
}
return 0;
}
int server_async_test(int argc, char** argv)
{
int ret = 0;
int ret = -1;
struct sockaddr_in servAddr;
struct sockaddr_in clientAddr;
socklen_t size = sizeof(clientAddr);
@@ -99,12 +178,26 @@ int server_async_test(int argc, char** argv)
size_t len;
const char* reply = "I hear ya fa shizzle!\n";
int on;
int devId = 1; /* anything besides -2 (INVALID_DEVID) */
#ifdef WOLF_CRYPTO_CB
AsyncTlsCryptoCbCtx myCtx;
int port = DEFAULT_PORT;
word16 group = WOLFSSL_ECC_SECP256R1;
int err = 0;
const char* mode = NULL;
int mutual = 0;
int tls12 = 0;
#ifdef WOLFSSL_ASYNC_CRYPT
int devId = INVALID_DEVID;
#endif
#ifdef WOLFSSL_DEBUG_NONBLOCK
int wouldblock_count = 0;
int pending_count = 0;
#endif
#ifdef WOLFSSL_STATIC_MEMORY
static byte memory[300000];
static byte memoryIO[34500];
#if !defined(WOLFSSL_STATIC_MEMORY_LEAN)
WOLFSSL_MEM_CONN_STATS ssl_stats;
#endif
#endif
int err;
char errBuff[WOLFSSL_MAX_ERROR_SZ];
/* declare wolfSSL objects */
WOLFSSL_CTX* ctx = NULL;
@@ -117,14 +210,21 @@ int server_async_test(int argc, char** argv)
}
#endif
if (parse_server_args(argc, argv, &port, &group, &mutual, &tls12) != 0) {
usage(argv[0]);
return 0;
}
mode = group_name(group);
printf("Async server mode: %s, TLS %s%s\n", mode,
tls12 ? "1.2" : "1.3", mutual ? ", mutual auth" : "");
/* Initialize the server address struct with zeros */
memset(&servAddr, 0, sizeof(servAddr));
/* Fill in the server address */
servAddr.sin_family = AF_INET; /* using IPv4 */
servAddr.sin_port = htons(DEFAULT_PORT); /* on DEFAULT_PORT */
servAddr.sin_addr.s_addr = INADDR_ANY; /* from anywhere */
servAddr.sin_family = AF_INET; /* using IPv4 */
servAddr.sin_port = htons(port);
servAddr.sin_addr.s_addr = INADDR_ANY; /* from anywhere */
/* Create a socket that uses an internet IPv4 address,
* Sets the socket to be stream based (TCP),
@@ -160,6 +260,12 @@ int server_async_test(int argc, char** argv)
fprintf(stderr, "ERROR: failed to listen\n");
goto exit;
}
{
const char* ready = getenv(WOLFSSL_ASYNC_READYFILE_ENV);
if (ready != NULL) {
(void)async_readyfile_touch(ready);
}
}
/*---------------------------------*/
/* Start of wolfSSL initialization and configuration */
@@ -169,57 +275,125 @@ int server_async_test(int argc, char** argv)
#endif
/* Initialize wolfSSL */
if ((ret = wolfSSL_Init()) != WOLFSSL_SUCCESS) {
if (wolfSSL_Init() != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: Failed to initialize the library\n");
goto exit;
}
/* Create and initialize WOLFSSL_CTX */
if ((ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())) == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n");
ret = -1;
goto exit;
}
#ifdef WOLF_CRYPTO_CB
XMEMSET(&myCtx, 0, sizeof(myCtx));
/* register a devID for crypto callbacks */
ret = wc_CryptoCb_RegisterDevice(devId, AsyncTlsCryptoCb, &myCtx);
if (ret != 0) {
fprintf(stderr, "wc_CryptoCb_RegisterDevice: error %d", ret);
#ifdef WOLFSSL_ASYNC_CRYPT
if (wolfAsync_DevOpenThread(&devId, NULL) != 0) {
goto exit;
}
#endif
/* register a devID for crypto callbacks */
/* Create and initialize WOLFSSL_CTX */
#ifdef WOLFSSL_STATIC_MEMORY
{
wolfSSL_method_func method;
#ifndef WOLFSSL_NO_TLS12
if (tls12)
method = wolfTLSv1_2_server_method_ex;
else
#endif
method = wolfSSLv23_server_method_ex;
if (wolfSSL_CTX_load_static_memory(&ctx, method, memory,
sizeof(memory), 0, 1) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: unable to load static memory\n");
goto exit;
}
if (wolfSSL_CTX_load_static_memory(&ctx, NULL, memoryIO,
sizeof(memoryIO),
WOLFMEM_IO_POOL_FIXED | WOLFMEM_TRACK_STATS, 1)
!= WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: unable to load static IO memory\n");
goto exit;
}
}
#else
#ifndef WOLFSSL_NO_TLS12
if (tls12)
ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method());
else
#endif
ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
#endif /* WOLFSSL_STATIC_MEMORY */
if (ctx == NULL) {
fprintf(stderr, "ERROR: failed to create WOLFSSL_CTX\n");
ret = -1;
goto exit;
}
#ifdef WOLFSSL_ASYNC_CRYPT
wolfSSL_CTX_SetDevId(ctx, devId);
#endif
/* Require mutual authentication */
wolfSSL_CTX_set_verify(ctx,
WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
wolfSSL_SetIORecv(ctx, NET_IO_RECV_CB);
wolfSSL_SetIOSend(ctx, NET_IO_SEND_CB);
/* Load server certificates into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE,
WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
CERT_FILE);
if (group == WOLFSSL_ECC_X25519) {
#ifdef HAVE_ED25519
ret = wolfSSL_CTX_use_certificate_buffer(ctx, server_ed25519_cert,
sizeof_server_ed25519_cert, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr,
"ERROR: failed to load ED25519 server cert buffer.\n");
goto exit;
}
ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, server_ed25519_key,
sizeof_server_ed25519_key, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr,
"ERROR: failed to load ED25519 server key buffer.\n");
goto exit;
}
if (mutual) {
/* client-ed25519 is self-signed, so load it as its own CA */
ret = wolfSSL_CTX_load_verify_buffer(ctx, client_ed25519_cert,
sizeof_client_ed25519_cert, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr,
"ERROR: failed to load ED25519 client CA cert.\n");
goto exit;
}
}
#else
fprintf(stderr, "ERROR: --x25519 requires HAVE_ED25519 for certs\n");
goto exit;
#endif
}
else {
ret = wolfSSL_CTX_use_certificate_buffer(ctx, serv_ecc_der_256,
sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load ECC server cert buffer.\n");
goto exit;
}
ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, ecc_key_der_256,
sizeof_ecc_key_der_256, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load ECC server key buffer.\n");
goto exit;
}
if (mutual) {
/* client-ecc-cert is self-signed, so load it as its own CA */
ret = wolfSSL_CTX_load_verify_buffer(ctx, cliecc_cert_der_256,
sizeof_cliecc_cert_der_256, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr,
"ERROR: failed to load ECC client CA cert.\n");
goto exit;
}
}
}
/* Load server key into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE,
WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
KEY_FILE);
goto exit;
if (mutual) {
wolfSSL_CTX_set_verify(ctx,
WOLFSSL_VERIFY_PEER | WOLFSSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
}
/* Load client certificate as "trusted" into WOLFSSL_CTX */
if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CA_FILE, NULL))
!= WOLFSSL_SUCCESS) {
fprintf(stderr, "ERROR: failed to load %s, please check the file.\n",
CA_FILE);
goto exit;
else {
wolfSSL_CTX_set_verify(ctx, WOLFSSL_VERIFY_NONE, NULL);
}
/* Continue to accept clients until mShutdown is issued */
@@ -227,11 +401,16 @@ int server_async_test(int argc, char** argv)
printf("Waiting for a connection...\n");
/* Accept client connections */
if ((mConnd = accept(mSockfd, (struct sockaddr*)&clientAddr, &size))
if ((mConnd = NET_ACCEPT(mSockfd,
(struct sockaddr*)&clientAddr, &size))
== -1) {
fprintf(stderr, "ERROR: failed to accept the connection\n\n");
ret = -1; goto exit;
}
if (NET_SET_NONBLOCKING(mConnd) != 0) {
fprintf(stderr, "ERROR: failed to set non-blocking socket\n");
ret = -1; goto exit;
}
/* Create a WOLFSSL object */
if ((ssl = wolfSSL_new(ctx)) == NULL) {
@@ -239,28 +418,101 @@ int server_async_test(int argc, char** argv)
ret = -1; goto exit;
}
/* Attach wolfSSL to the socket */
wolfSSL_set_fd(ssl, mConnd);
wolfSSL_SetIOReadCtx(ssl, (void*)(intptr_t)mConnd);
wolfSSL_SetIOWriteCtx(ssl, (void*)(intptr_t)mConnd);
/* UseKeyShare is TLS 1.3 only */
if (!tls12) {
for (;;) {
ret = wolfSSL_UseKeyShare(ssl, group);
if (ret == WOLFSSL_SUCCESS) {
break;
}
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
#ifdef WOLFSSL_DEBUG_NONBLOCK
pending_count++;
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
if (wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW) < 0) {
goto exit;
}
#endif
continue;
}
goto exit;
}
}
/* Establish TLS connection */
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_accept(ssl),
ret != WOLFSSL_SUCCESS);
if (ret != WOLFSSL_SUCCESS) {
fprintf(stderr, "wolfSSL_accept error %d: %s\n",
err, wolfSSL_ERR_error_string(err, errBuff));
for (;;) {
ret = wolfSSL_accept(ssl);
if (ret == WOLFSSL_SUCCESS) {
break;
}
err = wolfSSL_get_error(ssl, 0);
if (err == WC_NO_ERR_TRACE(WC_PENDING_E) ||
err == WOLFSSL_ERROR_WANT_READ ||
err == WOLFSSL_ERROR_WANT_WRITE) {
if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
#ifdef WOLFSSL_DEBUG_NONBLOCK
pending_count++;
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
if (wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW) < 0) {
goto exit;
}
#endif
}
else {
#ifdef WOLFSSL_DEBUG_NONBLOCK
wouldblock_count++;
#endif
}
continue;
}
fprintf(stderr, "ERROR: wolfSSL_accept failed: %d (%s)\n",
err, wolfSSL_ERR_reason_error_string(err));
goto exit;
}
{
const char* cipher = wolfSSL_get_cipher_name(ssl);
const char* curve = wolfSSL_get_curve_name(ssl);
printf("Negotiated cipher: %s\n",
cipher != NULL ? cipher : "unknown");
printf("Negotiated group: %s\n",
curve != NULL ? curve : "unknown");
}
printf("Client connected successfully\n");
/* Read the client data into our buff array */
memset(buff, 0, sizeof(buff));
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_read(ssl, buff, sizeof(buff)-1),
ret <= 0);
if (ret < 0) {
fprintf(stderr, "wolfSSL_read error %d: %s\n",
err, wolfSSL_ERR_error_string(err, errBuff));
for (;;) {
ret = wolfSSL_read(ssl, buff, sizeof(buff) - 1);
if (ret > 0) {
break;
}
err = wolfSSL_get_error(ssl, 0);
if (err == WC_NO_ERR_TRACE(WC_PENDING_E) ||
err == WOLFSSL_ERROR_WANT_READ ||
err == WOLFSSL_ERROR_WANT_WRITE) {
if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
#ifdef WOLFSSL_DEBUG_NONBLOCK
pending_count++;
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
if (wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW) < 0) {
goto exit;
}
#endif
}
else {
#ifdef WOLFSSL_DEBUG_NONBLOCK
wouldblock_count++;
#endif
}
continue;
}
goto exit;
}
@@ -279,46 +531,100 @@ int server_async_test(int argc, char** argv)
len = strnlen(buff, sizeof(buff));
/* Reply back to the client */
WOLFSSL_ASYNC_WHILE_PENDING(ret = wolfSSL_write(ssl, buff, (int)len),
ret <= 0);
if (ret != (int)len) {
fprintf(stderr, "wolfSSL_write error %d: %s\n",
err, wolfSSL_ERR_error_string(err, errBuff));
for (;;) {
ret = wolfSSL_write(ssl, buff, (int)len);
if (ret > 0) {
break;
}
err = wolfSSL_get_error(ssl, 0);
if (err == WC_NO_ERR_TRACE(WC_PENDING_E) ||
err == WOLFSSL_ERROR_WANT_READ ||
err == WOLFSSL_ERROR_WANT_WRITE) {
if (err == WC_NO_ERR_TRACE(WC_PENDING_E)) {
#ifdef WOLFSSL_DEBUG_NONBLOCK
pending_count++;
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
if (wolfSSL_AsyncPoll(ssl, WOLF_POLL_FLAG_CHECK_HW) < 0) {
goto exit;
}
#endif
}
else {
#ifdef WOLFSSL_DEBUG_NONBLOCK
wouldblock_count++;
#endif
}
continue;
}
goto exit;
}
#ifdef WOLFSSL_DEBUG_NONBLOCK
printf("WANT_READ/WRITE count: %d\n", wouldblock_count);
printf("WC_PENDING_E count: %d\n", pending_count);
#endif
/* Cleanup after this connection */
#if defined(WOLFSSL_STATIC_MEMORY) && !defined(WOLFSSL_STATIC_MEMORY_LEAN)
if (ssl != NULL &&
wolfSSL_is_static_memory(ssl, &ssl_stats) == 1) {
fprintf(stderr, "peak connection memory = %d\n",
ssl_stats.peakMem);
fprintf(stderr, "current memory in use = %d\n",
ssl_stats.curMem);
fprintf(stderr, "peak connection allocs = %d\n",
ssl_stats.peakAlloc);
fprintf(stderr, "total connection allocs = %d\n",
ssl_stats.totalAlloc);
fprintf(stderr, "total connection frees = %d\n",
ssl_stats.totalFr);
}
#endif
wolfSSL_shutdown(ssl);
if (ssl) {
wolfSSL_free(ssl); /* Free the wolfSSL object */
wolfSSL_free(ssl);
ssl = NULL;
}
if (mConnd != SOCKET_INVALID) {
close(mConnd); /* Close the connection to the client */
NET_CLOSE(mConnd);
mConnd = SOCKET_INVALID;
}
}
printf("Shutdown complete\n");
#ifdef WOLFSSL_DEBUG_NONBLOCK
printf("WANT_READ/WRITE count: %d\n", wouldblock_count);
printf("WC_PENDING_E count: %d\n", pending_count);
#endif
ret = 0;
exit:
/* Cleanup and return */
if (ssl)
wolfSSL_free(ssl); /* Free the wolfSSL object */
wolfSSL_free(ssl);
if (mConnd != SOCKET_INVALID) {
close(mConnd); /* Close the connection to the client */
NET_CLOSE(mConnd);
mConnd = SOCKET_INVALID;
}
if (mSockfd != SOCKET_INVALID) {
close(mSockfd); /* Close the socket listening for clients */
NET_CLOSE(mSockfd);
mSockfd = SOCKET_INVALID;
}
if (ctx)
wolfSSL_CTX_free(ctx); /* Free the wolfSSL context object */
wolfSSL_Cleanup(); /* Cleanup the wolfSSL environment */
(void)argc;
(void)argv;
wolfSSL_CTX_free(ctx);
#ifdef WOLFSSL_ASYNC_CRYPT
if (devId != INVALID_DEVID) {
wolfAsync_DevClose(&devId);
}
#endif
{
const char* ready = getenv(WOLFSSL_ASYNC_READYFILE_ENV);
if (ready != NULL) {
async_readyfile_clear(ready);
}
}
wolfSSL_Cleanup();
return ret;
}
+120 -2
View File
@@ -26,10 +26,129 @@
#ifndef WOLFSSL_USER_SETTINGS
#include <wolfssl/options.h>
#endif
#include "examples/async/async_tls.h"
#include <wolfssl/ssl.h>
#include <wolfssl/wolfio.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include "examples/async/async_tls.h"
#ifndef NET_CUSTOM
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#endif
/* ---------------------------------------------------------------------------*/
/* --- Ready file helpers (CI/automation sync) --- */
/* ---------------------------------------------------------------------------*/
#include <stdio.h>
#include <sys/stat.h>
#include <sys/select.h>
static int async_readyfile_exists(const char* path)
{
struct stat st;
if (path == NULL || path[0] == '\0') {
return 0;
}
return (stat(path, &st) == 0);
}
int async_readyfile_touch(const char* path)
{
FILE* f;
if (path == NULL || path[0] == '\0') {
return -1;
}
f = fopen(path, "w");
if (f == NULL) {
return -1;
}
fclose(f);
return 0;
}
void async_readyfile_clear(const char* path)
{
if (path == NULL || path[0] == '\0') {
return;
}
(void)remove(path);
}
int async_readyfile_wait(const char* path, int timeout_ms)
{
int waited_ms = 0;
const int step_ms = 50;
struct timeval tv;
while (waited_ms < timeout_ms) {
if (async_readyfile_exists(path)) {
return 0;
}
tv.tv_sec = 0;
tv.tv_usec = step_ms * 1000;
(void)select(0, NULL, NULL, NULL, &tv);
waited_ms += step_ms;
}
return -1;
}
/* ---------------------------------------------------------------------------*/
/* --- Default POSIX transport callbacks --- */
/* ---------------------------------------------------------------------------*/
#ifndef NET_CUSTOM
int async_posix_send_cb(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
(void)ssl;
int fd = (int)(intptr_t)ctx;
int ret = (int)NET_SEND(fd, buf, sz);
if (ret >= 0) {
return ret;
}
if (errno == EAGAIN || errno == EWOULDBLOCK) {
return WOLFSSL_CBIO_ERR_WANT_WRITE;
}
return WOLFSSL_CBIO_ERR_GENERAL;
}
int async_posix_recv_cb(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
(void)ssl;
int fd = (int)(intptr_t)ctx;
int ret = (int)NET_RECV(fd, buf, sz);
if (ret >= 0) {
return ret;
}
if (errno == EAGAIN || errno == EWOULDBLOCK) {
return WOLFSSL_CBIO_ERR_WANT_READ;
}
return WOLFSSL_CBIO_ERR_GENERAL;
}
int async_posix_getdevrandom(unsigned char *out, unsigned int sz)
{
ssize_t ret;
int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) {
return -1;
}
ret = read(fd, out, sz);
close(fd);
if (ret != (ssize_t)sz) {
return -1;
}
return 0;
}
#endif /* !NET_CUSTOM */
int posix_getdevrandom(unsigned char *out, unsigned int sz)
{
#ifdef NET_CUSTOM
return NET_GETDEVRANDOM(out, sz);
#else
return async_posix_getdevrandom(out, sz);
#endif
}
/* ---------------------------------------------------------------------------*/
/* --- Example Crypto Callback --- */
@@ -159,4 +278,3 @@ int AsyncTlsCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
#ifdef HAVE_PK_CALLBACKS
#endif
+78
View File
@@ -23,8 +23,26 @@
#ifndef WOLFSSL_ASYNC_TLS_EXAMPLES_H
#define WOLFSSL_ASYNC_TLS_EXAMPLES_H
typedef struct WOLFSSL WOLFSSL;
#ifdef WOLF_CRYPTO_CB
typedef struct wc_CryptoInfo wc_CryptoInfo;
#endif
#define DEFAULT_PORT 11111
#define DEFAULT_TLS_PORT 11111
#define DEFAULT_TLS_HOST "127.0.0.1"
#define TEST_BUF_SZ 256
#define WOLFSSL_ASYNC_READYFILE_ENV "WOLFSSL_ASYNC_READYFILE"
#define WOLFSSL_ASYNC_READYFILE_TIMEOUT_MS 5000
/* Force ECC-only certs/keys for these async TLS examples. */
#ifndef ASYNC_ECC_ONLY
#if defined(WC_ECC_NONBLOCK)
#define ASYNC_ECC_ONLY 1
#else
#define ASYNC_ECC_ONLY 0
#endif
#endif
#ifdef WOLF_CRYPTO_CB
/* Example custom context for crypto callback */
@@ -34,6 +52,66 @@ typedef struct {
int AsyncTlsCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx);
#endif /* WOLF_CRYPTO_CB */
/* Override transport by defining NET_USER_HEADER and/or NET_*.
* Example: -DNET_USER_HEADER='"my_net_port.h"' */
#ifdef NET_USER_HEADER
#include NET_USER_HEADER
#define NET_CUSTOM 1
#endif
int async_readyfile_touch(const char* path);
int async_readyfile_wait(const char* path, int timeout_ms);
void async_readyfile_clear(const char* path);
/* Default POSIX transport hooks (override with NET_* macros). */
#ifndef NET_CUSTOM
#ifndef NET_CONNECT
#define NET_CONNECT(host, port) posix_net_connect((host), (port))
#define NET_SET_NONBLOCKING(fd) posix_set_nonblocking((fd))
#define NET_ACCEPT(fd, addr, len) accept((fd), (addr), (len))
#define NET_SEND(fd, buf, sz) send((fd), (buf), (size_t)(sz), 0)
#define NET_RECV(fd, buf, sz) recv((fd), (buf), (size_t)(sz), 0)
#define NET_CLOSE(fd) close((fd))
#endif
#endif
int async_posix_send_cb(WOLFSSL* ssl, char* buf, int sz, void* ctx);
int async_posix_recv_cb(WOLFSSL* ssl, char* buf, int sz, void* ctx);
int async_posix_getdevrandom(unsigned char *out, unsigned int sz);
#ifndef NET_CUSTOM
#define NET_IO_SEND_CB async_posix_send_cb
#define NET_IO_RECV_CB async_posix_recv_cb
#else
#ifndef NET_IO_SEND_CB
#error NET_IO_SEND_CB must be defined when NET_USER_HEADER is used
#endif
#ifndef NET_IO_RECV_CB
#error NET_IO_RECV_CB must be defined when NET_USER_HEADER is used
#endif
#ifndef NET_CONNECT
#error NET_CONNECT must be defined when NET_USER_HEADER is used
#endif
#ifndef NET_SET_NONBLOCKING
#error NET_SET_NONBLOCKING must be defined when NET_USER_HEADER is used
#endif
#ifndef NET_ACCEPT
#error NET_ACCEPT must be defined when NET_USER_HEADER is used
#endif
#ifndef NET_SEND
#error NET_SEND must be defined when NET_USER_HEADER is used
#endif
#ifndef NET_RECV
#error NET_RECV must be defined when NET_USER_HEADER is used
#endif
#ifndef NET_CLOSE
#error NET_CLOSE must be defined when NET_USER_HEADER is used
#endif
#ifndef NET_GETDEVRANDOM
#error NET_GETDEVRANDOM must be defined when NET_USER_HEADER is used
#endif
#endif
int client_async_test(int argc, char** argv);
int server_async_test(int argc, char** argv);
+7 -26
View File
@@ -1,29 +1,10 @@
# vim:ft=automake
# All paths should be given relative to the root
if BUILD_ASYNCCRYPT
noinst_HEADERS += examples/async/async_tls.h
if BUILD_EXAMPLE_CLIENTS
noinst_PROGRAMS += examples/async/async_client
examples_async_async_client_SOURCES = examples/async/async_client.c examples/async/async_tls.c
examples_async_async_client_LDADD = src/libwolfssl@LIBSUFFIX@.la $(LIB_STATIC_ADD)
examples_async_async_client_DEPENDENCIES = src/libwolfssl@LIBSUFFIX@.la
examples_async_async_client_CFLAGS = $(AM_CFLAGS)
endif
if BUILD_EXAMPLE_SERVERS
noinst_PROGRAMS += examples/async/async_server
examples_async_async_server_SOURCES = examples/async/async_server.c examples/async/async_tls.c
examples_async_async_server_LDADD = src/libwolfssl@LIBSUFFIX@.la $(LIB_STATIC_ADD)
examples_async_async_server_DEPENDENCIES = src/libwolfssl@LIBSUFFIX@.la
examples_async_async_server_CFLAGS = $(AM_CFLAGS)
endif
endif
dist_example_DATA+= examples/async/async_server.c
dist_example_DATA+= examples/async/async_client.c
DISTCLEANFILES+= examples/async/.libs/async_server
DISTCLEANFILES+= examples/async/.libs/async_client
EXTRA_DIST += examples/async/README.md
EXTRA_DIST += examples/async/README.md \
examples/async/async_client.c \
examples/async/async_server.c \
examples/async/async_tls.c \
examples/async/async_tls.h \
examples/async/Makefile \
examples/async/user_settings.h
+91
View File
@@ -0,0 +1,91 @@
/* user_settings.h
*
* Copyright (C) 2006-2026 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Bare-metal user settings for TLS 1.3 client with WOLFSSL_USER_IO. */
#ifndef WOLFSSL_USER_SETTINGS_H
#define WOLFSSL_USER_SETTINGS_H
#define WOLFSSL_USER_IO
#define SINGLE_THREADED
#define NO_FILESYSTEM
#define WOLFSSL_IGNORE_FILE_WARN
#define HAVE_ECC
#define WC_ECC_NONBLOCK
#define WC_ECC_NONBLOCK_ONLY
#define ECC_USER_CURVES /* P256 only */
#define WOLFSSL_HAVE_SP_ECC
#define WOLFSSL_SP_SMALL
#define WOLFSSL_SP_NONBLOCK
#define WOLFSSL_SP_NO_MALLOC
#define ECC_TIMING_RESISTANT
#define HAVE_ED25519
#define HAVE_CURVE25519
#define CURVE25519_SMALL
#define ED25519_SMALL
#define WC_X25519_NONBLOCK
#define WOLFSSL_ASYNC_CRYPT
#define WOLFSSL_ASYNC_CRYPT_SW
#define WC_NO_ASYNC_THREADING
#define HAVE_WOLF_BIGINT
#define HAVE_AESGCM
#define WOLFSSL_SHA512
#define WOLFSSL_TLS13
#define HAVE_HKDF
#define HAVE_TLS_EXTENSIONS
#define HAVE_SUPPORTED_CURVES
#define HAVE_SERVER_RENEGOTIATION_INFO
#define HAVE_ENCRYPT_THEN_MAC
#define HAVE_SNI
#define HAVE_SESSION_TICKET
extern int posix_getdevrandom(unsigned char *out, unsigned int sz);
#ifndef HAVE_HASHDRBG
#define CUSTOM_RAND_GENERATE_BLOCK posix_getdevrandom
#else
#define CUSTOM_RAND_GENERATE_SEED posix_getdevrandom
#endif
/* Minimal feature set - explicitly disable unwanted algorithms */
#define NO_RSA
#define NO_DH
#define NO_DSA
#define WOLFSSL_NO_SHAKE256
#define WOLFSSL_NO_SHAKE128
#define NO_MD4
#define NO_MD5
#define NO_DES3
#define NO_SHA
#define NO_OLD_TLS
/* Debugging */
#if 0
#define DEBUG_WOLFSSL
#endif
#define WOLFSSL_DEBUG_NONBLOCK
#endif /* WOLFSSL_USER_SETTINGS_H */
+1
View File
@@ -12,6 +12,7 @@ Example wolfSSL configuration file templates for use when autoconf is not availa
* `user_settings_espressif.h`: Example configuration for Espressif ESP32. See also [wolfSSL/IDE/Espressif](https://github.com/wolfSSL/wolfssl/tree/master/IDE/Espressif).
* `user_settings_fipsv2.h`: The FIPS v2 (3389) 140-2 certificate build options.
* `user_settings_fipsv5.h`: The FIPS v5 (ready) 140-3 build options. Equivalent to `./configure --enable-fips=v5-dev`.
* `user_settings_curve25519nonblock.h`: Example Curve25519 (X25519) non-blocking configuration.
* `user_settings_min_ecc.h`: Minimal ECC and SHA-256 only (no TLS). For ECC verify only add `NO_ECC_SIGN`.
* `user_settings_platformio.h`: An example for PlatformIO library. See also [platformio/wolfssl](https://registry.platformio.org/libraries/wolfssl/wolfssl).
* `user_settings_stm32.h`: Example configuration file generated from the wolfSSL STM32 Cube pack.
+1
View File
@@ -6,6 +6,7 @@ EXTRA_DIST += examples/configs/user_settings_all.h
EXTRA_DIST += examples/configs/user_settings_arduino.h
EXTRA_DIST += examples/configs/user_settings_baremetal.h
EXTRA_DIST += examples/configs/user_settings_ca.h
EXTRA_DIST += examples/configs/user_settings_curve25519nonblock.h
EXTRA_DIST += examples/configs/user_settings_dtls13.h
EXTRA_DIST += examples/configs/user_settings_EBSnet.h
EXTRA_DIST += examples/configs/user_settings_eccnonblock.h
@@ -0,0 +1,88 @@
/* user_settings_curve25519nonblock.h
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* Example wolfSSL user_settings.h file for Curve25519 (X25519) non-blocking.
* See doc/dox_comments/header_files/curve25519.h wc_curve25519_set_nonblock.
*/
/* Settings based on this configure:
./configure --enable-curve25519=nonblock --enable-ecc=nonblock \
--enable-sp=yes,nonblock \
CFLAGS="-DWOLFSSL_PUBLIC_MP -DWOLFSSL_DEBUG_NONBLOCK"
*/
/* Tested using:
cp ./examples/configs/user_settings_curve25519nonblock.h user_settings.h
./configure --enable-usersettings --enable-debug --disable-examples
make
./wolfcrypt/test/testwolfcrypt
*/
/* Example test results:
CURVE25519 non-block key gen: 1273 times
CURVE25519 non-block shared secret: 1275 times
CURVE25519 test passed!
*/
#ifndef WOLFSSL_USER_SETTINGS_H
#define WOLFSSL_USER_SETTINGS_H
#ifdef __cplusplus
extern "C" {
#endif
/* Features */
#define WOLFCRYPT_ONLY
#define WOLFSSL_ASN_TEMPLATE
#define WOLFSSL_PUBLIC_MP /* expose mp_ math API's */
#define HAVE_HASHDRBG
/* Curve25519 (X25519) */
#define HAVE_CURVE25519
#define CURVE25519_SMALL
#define WC_X25519_NONBLOCK
/* Debugging */
#if 1
#undef DEBUG_WOLFSSL
#define DEBUG_WOLFSSL
#define WOLFSSL_DEBUG_NONBLOCK
#endif
/* Disabled algorithms */
#define NO_OLD_TLS
#define NO_RSA
#define NO_DH
#define NO_PSK
#define NO_MD4
#define NO_MD5
#define NO_SHA
#define NO_DSA
#define NO_DES3
#define NO_RC4
#define WOLFSSL_NO_SHAKE128
#define WOLFSSL_NO_SHAKE256
#ifdef __cplusplus
}
#endif
#endif /* WOLFSSL_USER_SETTINGS_H */
+2 -2
View File
@@ -40,10 +40,10 @@ my @fileList_ecc = (
# Used with HAVE_ED25519 define.
my @fileList_ed = (
[ "./certs/ed25519/server-ed25519.der", "server_ed25519_cert" ],
[ "./certs/ed25519/server-ed25519-key.der", "server_ed25519_key" ],
[ "./certs/ed25519/server-ed25519-priv.der", "server_ed25519_key" ],
[ "./certs/ed25519/ca-ed25519.der", "ca_ed25519_cert" ],
[ "./certs/ed25519/client-ed25519.der", "client_ed25519_cert" ],
[ "./certs/ed25519/client-ed25519-key.der", "client_ed25519_key" ]
[ "./certs/ed25519/client-ed25519-priv.der", "client_ed25519_key" ]
);
# x25519 keys and certs
+51 -15
View File
@@ -6117,7 +6117,7 @@ static int X25519SharedSecret(WOLFSSL* ssl, curve25519_key* priv_key,
#ifdef WOLFSSL_ASYNC_CRYPT
/* initialize event */
ret = wolfSSL_AsyncInit(ssl, &priv_key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN);
ret = wolfSSL_AsyncInit(ssl, &priv_key->asyncDev, WC_ASYNC_FLAG_NONE);
if (ret != 0)
return ret;
#endif
@@ -8189,6 +8189,13 @@ void FreeKey(WOLFSSL* ssl, int type, void** pKey)
#endif /* HAVE_ED25519 */
#ifdef HAVE_CURVE25519
case DYNAMIC_TYPE_CURVE25519:
#if defined(WC_X25519_NONBLOCK) && \
defined(WOLFSSL_ASYNC_CRYPT_SW)
if (((curve25519_key*)*pKey)->nb_ctx != NULL) {
XFREE(((curve25519_key*)*pKey)->nb_ctx, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
}
#endif
wc_curve25519_free((curve25519_key*)*pKey);
break;
#endif /* HAVE_CURVE25519 */
@@ -8236,8 +8243,14 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
#endif /* HAVE_ECC */
#if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_ECC)
ecc_nb_ctx_t* nbCtx;
#endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW && WC_ASYNC_ENABLE_ECC*/
ecc_nb_ctx_t* eccNbCtx;
#endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW && WC_ASYNC_ENABLE_ECC */
#ifdef HAVE_CURVE25519
curve25519_key* x25519Key;
#endif /* HAVE_CURVE25519 */
#if defined(WC_X25519_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW)
x25519_nb_ctx_t* x25519NbCtx;
#endif /* WC_X25519_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW */
if (ssl == NULL || pKey == NULL) {
return BAD_FUNC_ARG;
@@ -8323,23 +8336,26 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
case DYNAMIC_TYPE_ECC:
eccKey = (ecc_key*)*pKey;
ret = wc_ecc_init_ex(eccKey, ssl->heap, ssl->devId);
if (ret == 0) {
#if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_ECC)
nbCtx = (ecc_nb_ctx_t*)XMALLOC(sizeof(ecc_nb_ctx_t),
eccKey->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (nbCtx == NULL) {
#if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_ECC)
/* Only set non-blocking context when async device is active. With
* INVALID_DEVID there is no async loop to retry on FP_WOULDBLOCK, so
* let the WC_ECC_NONBLOCK_ONLY blocking fallback handle it instead. */
if (ret == 0 && ssl->devId != INVALID_DEVID) {
eccNbCtx = (ecc_nb_ctx_t*)XMALLOC(sizeof(ecc_nb_ctx_t),
eccKey->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (eccNbCtx == NULL) {
ret = MEMORY_E;
}
else {
ret = wc_ecc_set_nonblock(eccKey, nbCtx);
ret = wc_ecc_set_nonblock(eccKey, eccNbCtx);
if (ret != 0) {
XFREE(nbCtx, eccKey->heap, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(eccNbCtx, eccKey->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
}
#endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
WC_ASYNC_ENABLE_ECC */
}
#endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
WC_ASYNC_ENABLE_ECC */
break;
#endif /* HAVE_ECC */
#ifdef HAVE_ED25519
@@ -8350,8 +8366,28 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey)
#endif /* HAVE_CURVE25519 */
#ifdef HAVE_CURVE25519
case DYNAMIC_TYPE_CURVE25519:
wc_curve25519_init_ex((curve25519_key*)*pKey, ssl->heap, ssl->devId);
ret = 0;
x25519Key = (curve25519_key*)*pKey;
ret = wc_curve25519_init_ex(x25519Key, ssl->heap, ssl->devId);
#if defined(WC_X25519_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_X25519)
/* Only set non-blocking context when async device is active. With
* INVALID_DEVID there is no async loop to retry on FP_WOULDBLOCK, so
* skip non-blocking setup and use blocking mode instead. */
if (ret == 0 && ssl->devId != INVALID_DEVID) {
x25519NbCtx = (x25519_nb_ctx_t*)XMALLOC(sizeof(x25519_nb_ctx_t),
ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (x25519NbCtx == NULL) {
ret = MEMORY_E;
}
else {
ret = wc_curve25519_set_nonblock(x25519Key, x25519NbCtx);
if (ret != 0) {
XFREE(x25519NbCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
}
}
#endif /* WC_X25519_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
WC_ASYNC_ENABLE_X25519 */
break;
#endif /* HAVE_CURVE25519 */
#ifdef HAVE_ED448
+5
View File
@@ -31,6 +31,7 @@
#include <wolfssl/internal.h>
#include <wolfssl/error-ssl.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/coding.h>
#include <wolfssl/wolfcrypt/kdf.h>
#ifdef NO_INLINE
@@ -3904,6 +3905,10 @@ int wolfSSL_get_error(WOLFSSL* ssl, int ret)
return WOLFSSL_ERROR_SYSCALL; /* convert to OpenSSL type */
else if (ssl->error == WC_NO_ERR_TRACE(SOCKET_PEER_CLOSED_E))
return WOLFSSL_ERROR_SYSCALL; /* convert to OpenSSL type */
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
else if (ssl->error == WC_NO_ERR_TRACE(MP_WOULDBLOCK))
return WC_PENDING_E; /* map non-blocking crypto */
#endif
return ssl->error;
}
+178 -44
View File
@@ -8002,18 +8002,54 @@ static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse)
/* Make an Curve25519 key. */
ret = wc_curve25519_init_ex((curve25519_key*)kse->key, ssl->heap,
INVALID_DEVID);
ssl->devId);
if (ret == 0) {
/* setting "key" means okay to call wc_curve25519_free */
key = (curve25519_key*)kse->key;
kse->keyLen = CURVE25519_KEYSIZE;
}
#if defined(WC_X25519_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_X25519)
/* Only set non-blocking context when async device is active. With
* INVALID_DEVID there is no async loop to retry on FP_WOULDBLOCK, so
* skip non-blocking setup and use blocking mode instead. */
if (ret == 0 && ssl->devId != INVALID_DEVID) {
x25519_nb_ctx_t* nb_ctx = (x25519_nb_ctx_t*)XMALLOC(
sizeof(x25519_nb_ctx_t), ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (nb_ctx == NULL) {
ret = MEMORY_E;
}
else {
ret = wc_curve25519_set_nonblock(key, nb_ctx);
if (ret != 0) {
XFREE(nb_ctx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
}
}
#endif /* WC_X25519_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
WC_ASYNC_ENABLE_X25519 */
if (ret == 0) {
#ifdef WOLFSSL_STATIC_EPHEMERAL
ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_CURVE25519, kse->key);
if (ret != 0)
if (ret != 0) /* on failure, fallback to local key generation */
#endif
{
#ifdef WOLFSSL_ASYNC_CRYPT
/* initialize event */
ret = wolfSSL_AsyncInit(ssl, &key->asyncDev,
WC_ASYNC_FLAG_NONE);
if (ret != 0)
return ret;
#endif
ret = wc_curve25519_make_key(ssl->rng, CURVE25519_KEYSIZE, key);
/* Handle async pending response */
#ifdef WOLFSSL_ASYNC_CRYPT
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
return wolfSSL_AsyncPush(ssl, &key->asyncDev);
}
#endif /* WOLFSSL_ASYNC_CRYPT */
}
}
}
@@ -8050,8 +8086,14 @@ static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse)
/* Data owned by key share entry otherwise. */
XFREE(kse->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
kse->pubKey = NULL;
if (key != NULL)
if (key != NULL) {
#if defined(WC_X25519_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW)
if (key->nb_ctx != NULL) {
XFREE(key->nb_ctx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
#endif
wc_curve25519_free(key);
}
XFREE(kse->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
kse->key = NULL;
}
@@ -8237,6 +8279,28 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse)
/* Initialize an ECC key struct for the ephemeral key */
ret = wc_ecc_init_ex((ecc_key*)kse->key, ssl->heap, ssl->devId);
#if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_ECC)
/* Only set non-blocking context when async device is active. With
* INVALID_DEVID there is no async loop to retry on FP_WOULDBLOCK, so
* skip non-blocking setup and use blocking mode instead. */
if (ret == 0 && ssl->devId != INVALID_DEVID) {
ecc_nb_ctx_t* eccNbCtx = (ecc_nb_ctx_t*)XMALLOC(
sizeof(ecc_nb_ctx_t), ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (eccNbCtx == NULL) {
ret = MEMORY_E;
}
else {
ret = wc_ecc_set_nonblock((ecc_key*)kse->key, eccNbCtx);
if (ret != 0) {
XFREE(eccNbCtx, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER);
}
}
}
#endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
WC_ASYNC_ENABLE_ECC */
if (ret == 0) {
kse->keyLen = keySize;
kse->pubKeyLen = keySize * 2 + 1;
@@ -8808,6 +8872,13 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
}
else if (current->group == WOLFSSL_ECC_X25519) {
#ifdef HAVE_CURVE25519
#if defined(WC_X25519_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW)
if (current->key != NULL &&
((curve25519_key*)current->key)->nb_ctx != NULL) {
XFREE(((curve25519_key*)current->key)->nb_ctx, heap,
DYNAMIC_TYPE_TMP_BUFFER);
}
#endif
wc_curve25519_free((curve25519_key*)current->key);
#endif
}
@@ -8851,6 +8922,15 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
}
else {
#ifdef HAVE_ECC
#if defined(WC_ECC_NONBLOCK) && \
defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_ECC)
if (current->key != NULL &&
((ecc_key*)current->key)->nb_ctx != NULL) {
XFREE(((ecc_key*)current->key)->nb_ctx, heap,
DYNAMIC_TYPE_TMP_BUFFER);
}
#endif
wc_ecc_free((ecc_key*)current->key);
#endif
}
@@ -8858,6 +8938,14 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
#endif
else {
#ifdef HAVE_ECC
#if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_ECC)
if (current->key != NULL &&
((ecc_key*)current->key)->nb_ctx != NULL) {
XFREE(((ecc_key*)current->key)->nb_ctx, heap,
DYNAMIC_TYPE_TMP_BUFFER);
}
#endif
wc_ecc_free((ecc_key*)current->key);
#endif
}
@@ -9101,67 +9189,113 @@ static int TLSX_KeyShare_ProcessX25519_ex(WOLFSSL* ssl,
unsigned char* ssOutput,
word32* ssOutSz)
{
int ret;
int ret = 0;
#ifdef HAVE_CURVE25519
curve25519_key* key = (curve25519_key*)keyShareEntry->key;
curve25519_key* peerX25519Key;
#ifdef HAVE_ECC
if (ssl->peerEccKey != NULL) {
wc_ecc_free(ssl->peerEccKey);
ssl->peerEccKey = NULL;
ssl->peerEccKeyPresent = 0;
}
#ifdef WOLFSSL_ASYNC_CRYPT
if (keyShareEntry->lastRet == 0) /* don't enter here if WC_PENDING_E */
#endif
{
#ifdef HAVE_ECC
if (ssl->peerEccKey != NULL) {
wc_ecc_free(ssl->peerEccKey);
ssl->peerEccKey = NULL;
ssl->peerEccKeyPresent = 0;
}
#endif
peerX25519Key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), ssl->heap,
DYNAMIC_TYPE_TLSX);
if (peerX25519Key == NULL) {
WOLFSSL_MSG("PeerEccKey Memory error");
return MEMORY_ERROR;
}
ret = wc_curve25519_init(peerX25519Key);
if (ret != 0) {
XFREE(peerX25519Key, ssl->heap, DYNAMIC_TYPE_TLSX);
return ret;
}
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Peer Curve25519 Key");
WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
#endif
ssl->peerX25519Key = (curve25519_key*)XMALLOC(sizeof(curve25519_key),
ssl->heap, DYNAMIC_TYPE_TLSX);
if (ssl->peerX25519Key == NULL) {
WOLFSSL_MSG("PeerX25519Key Memory error");
return MEMORY_ERROR;
}
ret = wc_curve25519_init(ssl->peerX25519Key);
if (ret != 0) {
XFREE(ssl->peerX25519Key, ssl->heap, DYNAMIC_TYPE_TLSX);
ssl->peerX25519Key = NULL;
return ret;
}
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Peer Curve25519 Key");
WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
#endif
if (wc_curve25519_check_public(keyShareEntry->ke, keyShareEntry->keLen,
if (wc_curve25519_check_public(keyShareEntry->ke, keyShareEntry->keLen,
EC25519_LITTLE_ENDIAN) != 0) {
ret = ECC_PEERKEY_ERROR;
WOLFSSL_ERROR_VERBOSE(ret);
}
if (ret == 0) {
if (wc_curve25519_import_public_ex(keyShareEntry->ke,
keyShareEntry->keLen, peerX25519Key,
EC25519_LITTLE_ENDIAN) != 0) {
ret = ECC_PEERKEY_ERROR;
WOLFSSL_ERROR_VERBOSE(ret);
}
if (ret == 0) {
if (wc_curve25519_import_public_ex(keyShareEntry->ke,
keyShareEntry->keLen,
ssl->peerX25519Key,
EC25519_LITTLE_ENDIAN) != 0) {
ret = ECC_PEERKEY_ERROR;
WOLFSSL_ERROR_VERBOSE(ret);
}
}
if (ret == 0) {
ssl->ecdhCurveOID = ECC_X25519_OID;
ssl->peerX25519KeyPresent = 1;
}
}
if (ret == 0 && key == NULL)
ret = BAD_FUNC_ARG;
if (ret == 0) {
ssl->ecdhCurveOID = ECC_X25519_OID;
#ifdef WOLFSSL_CURVE25519_BLINDING
ret = wc_curve25519_set_rng(key, ssl->rng);
}
if (ret == 0) {
#endif
ret = wc_curve25519_shared_secret_ex(key, peerX25519Key,
ssOutput, ssOutSz, EC25519_LITTLE_ENDIAN);
#ifdef WOLFSSL_ASYNC_CRYPT
if (keyShareEntry->lastRet != WC_NO_ERR_TRACE(WC_PENDING_E))
#endif
{
#ifdef WOLFSSL_ASYNC_CRYPT
/* initialize event */
ret = wolfSSL_AsyncInit(ssl, &key->asyncDev,
WC_ASYNC_FLAG_CALL_AGAIN);
if (ret != 0)
return ret;
#endif
ret = wc_curve25519_shared_secret_ex(key, ssl->peerX25519Key,
ssOutput, ssOutSz, EC25519_LITTLE_ENDIAN);
#ifdef WOLFSSL_ASYNC_CRYPT
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) {
return wolfSSL_AsyncPush(ssl, &key->asyncDev);
}
#endif
}
/* On CALL_AGAIN re-entry (lastRet == PENDING): the block above
* is skipped entirely, so wc_curve25519_shared_secret_ex is not
* called again. ret stays 0 from initialization, and execution
* falls through to the cleanup code below. */
}
wc_curve25519_free(peerX25519Key);
XFREE(peerX25519Key, ssl->heap, DYNAMIC_TYPE_TLSX);
wc_curve25519_free((curve25519_key*)keyShareEntry->key);
XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
keyShareEntry->key = NULL;
/* done with key share, release resources */
if (ssl->peerX25519Key != NULL) {
wc_curve25519_free(ssl->peerX25519Key);
XFREE(ssl->peerX25519Key, ssl->heap, DYNAMIC_TYPE_TLSX);
ssl->peerX25519Key = NULL;
ssl->peerX25519KeyPresent = 0;
}
if (keyShareEntry->key != NULL) {
#if defined(WC_X25519_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW)
if (((curve25519_key*)keyShareEntry->key)->nb_ctx != NULL) {
XFREE(((curve25519_key*)keyShareEntry->key)->nb_ctx, ssl->heap,
DYNAMIC_TYPE_TMP_BUFFER);
}
#endif
wc_curve25519_free((curve25519_key*)keyShareEntry->key);
XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
keyShareEntry->key = NULL;
}
XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
keyShareEntry->ke = NULL;
#else
+11 -4
View File
@@ -59,6 +59,7 @@
#include <wolfssl/ssl.h> /* compatibility layer */
#include <wolfssl/error-ssl.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/test.h>
#include <tests/utils.h>
@@ -4811,8 +4812,11 @@ int test_ssl_memio_do_handshake(test_ssl_memio_ctx* ctx, int max_rounds,
}
else {
err = wolfSSL_get_error(ctx->c_ssl, ret);
if (err != WOLFSSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_WANT_WRITE) {
if (err == WC_NO_ERR_TRACE(MP_WOULDBLOCK)) {
/* retry non-blocking math */
}
else if (err != WOLFSSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_WANT_WRITE) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "error = %d, %s\n", err,
wolfSSL_ERR_error_string((word32)err, buff));
@@ -4833,8 +4837,11 @@ int test_ssl_memio_do_handshake(test_ssl_memio_ctx* ctx, int max_rounds,
}
else {
err = wolfSSL_get_error(ctx->s_ssl, ret);
if (err != WOLFSSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_WANT_WRITE) {
if (err == WC_NO_ERR_TRACE(MP_WOULDBLOCK)) {
/* retry non-blocking math */
}
else if (err != WOLFSSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_WANT_WRITE) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "error = %d, %s\n", err,
wolfSSL_ERR_error_string((word32)err, buff));
+19 -5
View File
@@ -21,6 +21,7 @@
#include <tests/unit.h>
#include <tests/utils.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#ifdef HAVE_MANUAL_MEMIO_TESTS_DEPENDENCIES
@@ -182,9 +183,16 @@ int test_memio_do_handshake(WOLFSSL *ssl_c, WOLFSSL *ssl_s,
}
else {
err = wolfSSL_get_error(ssl_c, ret);
if (err != WOLFSSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_WANT_WRITE)
if (err == WC_NO_ERR_TRACE(MP_WOULDBLOCK)) {
/* retry non-blocking math */
}
else if (err != WOLFSSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_WANT_WRITE) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "memio client error = %d, %s\n", err,
wolfSSL_ERR_error_string((word32)err, buff));
return -1;
}
}
}
if (!hs_s) {
@@ -196,9 +204,16 @@ int test_memio_do_handshake(WOLFSSL *ssl_c, WOLFSSL *ssl_s,
}
else {
err = wolfSSL_get_error(ssl_s, ret);
if (err != WOLFSSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_WANT_WRITE)
if (err == WC_NO_ERR_TRACE(MP_WOULDBLOCK)) {
/* retry non-blocking math */
}
else if (err != WOLFSSL_ERROR_WANT_READ &&
err != WOLFSSL_ERROR_WANT_WRITE) {
char buff[WOLFSSL_MAX_ERROR_SZ];
fprintf(stderr, "memio server error = %d, %s\n", err,
wolfSSL_ERR_error_string((word32)err, buff));
return -1;
}
}
}
handshake_complete = hs_c && hs_s;
@@ -792,4 +807,3 @@ void DEBUG_WRITE_DER(const byte* der, int derSz, const char* fileName)
}
}
#endif
+17 -10
View File
@@ -18467,7 +18467,7 @@ int ConfirmSignature(SignatureCtx* sigCtx,
word32 idx = 0;
#if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_ECC)
ecc_nb_ctx_t* nbCtx;
ecc_nb_ctx_t* nb_ctx;
#endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
WC_ASYNC_ENABLE_ECC */
@@ -18485,17 +18485,24 @@ int ConfirmSignature(SignatureCtx* sigCtx,
}
#if defined(WC_ECC_NONBLOCK) && defined(WOLFSSL_ASYNC_CRYPT_SW) && \
defined(WC_ASYNC_ENABLE_ECC)
nbCtx = (ecc_nb_ctx_t*)XMALLOC(sizeof(ecc_nb_ctx_t),
sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (nbCtx == NULL) {
ERROR_OUT(MEMORY_E, exit_cs);
}
/* Only set non-blocking context when async device is
* active. With INVALID_DEVID there is no async loop to
* retry on FP_WOULDBLOCK, so let the WC_ECC_NONBLOCK_ONLY
* blocking fallback handle it instead. */
if (sigCtx->devId != INVALID_DEVID) {
nb_ctx = (ecc_nb_ctx_t*)XMALLOC(sizeof(ecc_nb_ctx_t),
sigCtx->heap, DYNAMIC_TYPE_TMP_BUFFER);
if (nb_ctx == NULL) {
ERROR_OUT(MEMORY_E, exit_cs);
}
ret = wc_ecc_set_nonblock(sigCtx->key.ecc, nbCtx);
if (ret != 0) {
goto exit_cs;
ret = wc_ecc_set_nonblock(sigCtx->key.ecc, nb_ctx);
if (ret != 0) {
XFREE(nb_ctx, sigCtx->heap,
DYNAMIC_TYPE_TMP_BUFFER);
goto exit_cs;
}
}
#endif /* WC_ECC_NONBLOCK && WOLFSSL_ASYNC_CRYPT_SW &&
WC_ASYNC_ENABLE_ECC */
ret = wc_EccPublicKeyDecode(key, &idx, sigCtx->key.ecc,
+22
View File
@@ -268,6 +268,28 @@ static int wolfAsync_DoSw(WC_ASYNC_DEV* asyncDev)
break;
}
#endif /* !NO_DES3 */
#ifdef HAVE_CURVE25519
case ASYNC_SW_X25519_MAKE:
{
ret = wc_curve25519_make_key(
(WC_RNG*)sw->x25519Make.rng,
sw->x25519Make.size,
(curve25519_key*)sw->x25519Make.key
);
break;
}
case ASYNC_SW_X25519_SHARED_SEC:
{
ret = wc_curve25519_shared_secret_ex(
(curve25519_key*)sw->x25519SharedSec.priv,
(curve25519_key*)sw->x25519SharedSec.pub,
sw->x25519SharedSec.out,
sw->x25519SharedSec.outLen,
sw->x25519SharedSec.endian
);
break;
}
#endif /* HAVE_CURVE25519 */
default:
WOLFSSL_MSG("Invalid async crypt SW type!");
ret = BAD_FUNC_ARG;
+277 -74
View File
@@ -22,7 +22,14 @@
/* Based On Daniel J Bernstein's curve25519 Public Domain ref10 work. */
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
/*
* X25519 configuration macros:
*
* WC_X25519_NONBLOCK: Enable non-blocking support for key gen and shared
* secret. Requires CURVE25519_SMALL. Default: off.
*/
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#ifdef NO_CURVED25519_X64
#undef USE_INTEL_SPEEDUP
@@ -32,6 +39,8 @@
#include <wolfssl/wolfcrypt/curve25519.h>
#include <wolfssl/wolfcrypt/ge_operations.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
@@ -77,7 +86,8 @@ const curve25519_set_type curve25519_sets[] = {
#if (!defined(WOLFSSL_CURVE25519_USE_ED25519) && \
!(defined(CURVED25519_X64) || (defined(WOLFSSL_ARMASM) && \
defined(__aarch64__)))) || defined(WOLFSSL_CURVE25519_BLINDING)
defined(__aarch64__)))) || defined(WOLFSSL_CURVE25519_BLINDING) || \
defined(WC_X25519_NONBLOCK)
static const word32 kCurve25519BasePoint[CURVE25519_KEYSIZE/sizeof(word32)] = {
#ifdef BIG_ENDIAN_ORDER
0x09000000
@@ -440,6 +450,85 @@ int wc_curve25519_make_priv(WC_RNG* rng, int keysize, byte* key)
return ret;
}
#ifdef WC_X25519_NONBLOCK
static int wc_curve25519_make_pub_nb(curve25519_key* key)
{
int ret = 0;
if (key == NULL) {
ret = BAD_FUNC_ARG;
}
else if (key->nb_ctx == NULL) {
WOLFSSL_MSG("wc_curve25519_make_pub_nb called with NULL non-blocking "
"context.");
ret = BAD_FUNC_ARG;
}
if (ret == 0 && key->nb_ctx->state == 0) {
/* check clamping */
ret = curve25519_priv_clamp_check(key->k);
if (ret == 0) {
fe_init();
}
}
if (ret == 0) {
ret = curve25519_nb(key->p.point, key->k, (byte*)kCurve25519BasePoint,
key->nb_ctx);
}
return ret;
}
static int wc_curve25519_make_key_nb(WC_RNG* rng, int keysize,
curve25519_key* key)
{
int ret = 0;
if (key == NULL || rng == NULL) {
ret = BAD_FUNC_ARG;
}
else if (key->nb_ctx == NULL) {
WOLFSSL_MSG("wc_curve25519_make_key_nb called with NULL non-blocking "
"context.");
ret = BAD_FUNC_ARG;
}
if (ret == 0 && key->nb_ctx->state == 0) {
ret = wc_curve25519_make_priv(rng, keysize, key->k);
if (ret == 0) {
key->privSet = 1;
}
}
if (ret == 0) {
ret = wc_curve25519_make_pub_nb(key);
if (ret == 0) {
key->pubSet = 1;
}
}
return ret;
}
int wc_curve25519_set_nonblock(curve25519_key* key, x25519_nb_ctx_t* ctx)
{
if (key == NULL) {
return BAD_FUNC_ARG;
}
/* If a different context is already set, clear it before replacing.
* The caller is responsible for freeing any heap-allocated context. */
if (key->nb_ctx != NULL && key->nb_ctx != ctx) {
XMEMSET(key->nb_ctx, 0, sizeof(x25519_nb_ctx_t));
}
if (ctx != NULL) {
XMEMSET(ctx, 0, sizeof(x25519_nb_ctx_t));
}
key->nb_ctx = ctx;
return 0;
}
#endif /* WC_X25519_NONBLOCK */
/* generate a new keypair.
*
* return value is propagated from wc_curve25519_make_private() or
@@ -461,26 +550,48 @@ int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key)
}
#endif
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_X25519) && \
defined(WOLFSSL_ASYNC_CRYPT_SW)
if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_X25519) {
if (wc_AsyncSwInit(&key->asyncDev, ASYNC_SW_X25519_MAKE)) {
WC_ASYNC_SW* sw = &key->asyncDev.sw;
sw->x25519Make.rng = rng;
sw->x25519Make.size = keysize;
sw->x25519Make.key = key;
return WC_PENDING_E;
}
}
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_X25519 &&
* WOLFSSL_ASYNC_CRYPT_SW */
#ifdef WOLFSSL_SE050
ret = se050_curve25519_create_key(key, keysize);
#else
ret = wc_curve25519_make_priv(rng, keysize, key->k);
if (ret == 0) {
key->privSet = 1;
#ifdef WOLFSSL_CURVE25519_BLINDING
ret = wc_curve25519_make_pub_blind((int)sizeof(key->p.point),
key->p.point, (int)sizeof(key->k),
key->k, rng);
if (ret == 0) {
ret = wc_curve25519_set_rng(key, rng);
}
#else
ret = wc_curve25519_make_pub((int)sizeof(key->p.point), key->p.point,
(int)sizeof(key->k), key->k);
#endif
key->pubSet = (ret == 0);
#elif defined(WC_X25519_NONBLOCK)
if (key->nb_ctx != NULL) {
ret = wc_curve25519_make_key_nb(rng, keysize, key);
}
else
#endif
#if !defined(WOLFSSL_SE050)
{
ret = wc_curve25519_make_priv(rng, keysize, key->k);
if (ret == 0) {
key->privSet = 1;
#ifdef WOLFSSL_CURVE25519_BLINDING
ret = wc_curve25519_make_pub_blind((int)sizeof(key->p.point),
key->p.point, (int)sizeof(key->k), key->k, rng);
if (ret == 0) {
ret = wc_curve25519_set_rng(key, rng);
}
#else
ret = wc_curve25519_make_pub((int)sizeof(key->p.point),
key->p.point, (int)sizeof(key->k), key->k);
#endif
key->pubSet = (ret == 0);
}
}
#endif /* !WOLFSSL_SE050 */
return ret;
}
@@ -494,12 +605,65 @@ int wc_curve25519_shared_secret(curve25519_key* private_key,
out, outlen, EC25519_BIG_ENDIAN);
}
#ifdef WC_X25519_NONBLOCK
static int wc_curve25519_shared_secret_nb(curve25519_key* privKey,
curve25519_key* pubKey, byte* out, word32* outlen, int endian)
{
int ret = FP_WOULDBLOCK;
switch (privKey->nb_ctx->ssState) {
case 0:
XMEMSET(&privKey->nb_ctx->o, 0, sizeof(privKey->nb_ctx->o));
privKey->nb_ctx->ssState = 1;
break;
case 1:
ret = curve25519_nb(privKey->nb_ctx->o.point, privKey->k,
pubKey->p.point, privKey->nb_ctx);
if (ret == 0) {
ret = FP_WOULDBLOCK;
privKey->nb_ctx->ssState = 2;
}
break;
case 2:
#ifdef WOLFSSL_ECDHX_SHARED_NOT_ZERO
{
int i;
byte t = 0;
for (i = 0; i < CURVE25519_KEYSIZE; i++) {
t |= privKey->nb_ctx->o.point[i];
}
if (t == 0) {
ret = ECC_OUT_OF_RANGE_E;
}
else
#endif /* WOLFSSL_ECDHX_SHARED_NOT_ZERO */
{
curve25519_copy_point(out, privKey->nb_ctx->o.point, endian);
*outlen = CURVE25519_KEYSIZE;
ret = 0;
}
#ifdef WOLFSSL_ECDHX_SHARED_NOT_ZERO
}
#endif
break;
}
if (ret != FP_WOULDBLOCK) {
XMEMSET(privKey->nb_ctx, 0, sizeof(x25519_nb_ctx_t));
}
return ret;
}
#endif /* WC_X25519_NONBLOCK */
int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
curve25519_key* public_key,
byte* out, word32* outlen, int endian)
{
int ret;
ECPoint o;
int ret = 0;
/* sanity check */
if (private_key == NULL || public_key == NULL ||
@@ -531,51 +695,80 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key,
}
#endif
XMEMSET(&o, 0, sizeof(o));
#ifdef WC_X25519_NONBLOCK
#ifdef FREESCALE_LTC_ECC
/* input point P on Curve25519 */
ret = nxp_ltc_curve25519(&o, private_key->k, &public_key->p,
kLTC_Curve25519);
#else
#ifdef WOLFSSL_SE050
if (!private_key->privSet) {
/* use NXP SE050: "privSet" is not set */
ret = se050_curve25519_shared_secret(private_key, public_key, &o);
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_X25519) && \
defined(WOLFSSL_ASYNC_CRYPT_SW)
if (private_key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_X25519) {
if (wc_AsyncSwInit(&private_key->asyncDev,
ASYNC_SW_X25519_SHARED_SEC)) {
WC_ASYNC_SW* sw = &private_key->asyncDev.sw;
sw->x25519SharedSec.priv = private_key;
sw->x25519SharedSec.pub = public_key;
sw->x25519SharedSec.out = out;
sw->x25519SharedSec.outLen = outlen;
sw->x25519SharedSec.endian = endian;
return WC_PENDING_E;
}
}
#endif /* WOLFSSL_ASYNC_CRYPT && WC_ASYNC_ENABLE_X25519 &&
* WOLFSSL_ASYNC_CRYPT_SW */
if (private_key->nb_ctx != NULL) {
ret = wc_curve25519_shared_secret_nb(private_key, public_key, out,
outlen, endian);
}
else
#endif
#endif /* WC_X25519_NONBLOCK */
{
#ifndef WOLFSSL_CURVE25519_BLINDING
SAVE_VECTOR_REGISTERS(return _svr_ret;);
ECPoint o;
ret = curve25519(o.point, private_key->k, public_key->p.point);
XMEMSET(&o, 0, sizeof(o));
RESTORE_VECTOR_REGISTERS();
#ifdef FREESCALE_LTC_ECC
/* input point P on Curve25519 */
ret = nxp_ltc_curve25519(&o, private_key->k, &public_key->p,
kLTC_Curve25519);
#else
ret = curve25519_smul_blind(o.point, private_key->k, public_key->p.point,
private_key->rng);
#endif
}
#endif
#ifdef WOLFSSL_ECDHX_SHARED_NOT_ZERO
if (ret == 0) {
int i;
byte t = 0;
for (i = 0; i < CURVE25519_KEYSIZE; i++) {
t |= o.point[i];
#ifdef WOLFSSL_SE050
if (!private_key->privSet) {
/* use NXP SE050: "privSet" is not set */
ret = se050_curve25519_shared_secret(private_key, public_key, &o);
}
if (t == 0) {
ret = ECC_OUT_OF_RANGE_E;
}
}
#endif
if (ret == 0) {
curve25519_copy_point(out, o.point, endian);
*outlen = CURVE25519_KEYSIZE;
}
else
#endif /* WOLFSSL_SE050 */
{
#ifndef WOLFSSL_CURVE25519_BLINDING
SAVE_VECTOR_REGISTERS(return _svr_ret;);
ForceZero(&o, sizeof(o));
ret = curve25519(o.point, private_key->k, public_key->p.point);
RESTORE_VECTOR_REGISTERS();
#else
ret = curve25519_smul_blind(o.point, private_key->k,
public_key->p.point, private_key->rng);
#endif
}
#endif /* FREESCALE_LTC_ECC */
#ifdef WOLFSSL_ECDHX_SHARED_NOT_ZERO
if (ret == 0) {
int i;
byte t = 0;
for (i = 0; i < CURVE25519_KEYSIZE; i++) {
t |= o.point[i];
}
if (t == 0) {
ret = ECC_OUT_OF_RANGE_E;
}
}
#endif /* WOLFSSL_ECDHX_SHARED_NOT_ZERO */
if (ret == 0) {
curve25519_copy_point(out, o.point, endian);
*outlen = CURVE25519_KEYSIZE;
}
ForceZero(&o, sizeof(o));
}
return ret;
}
@@ -931,30 +1124,40 @@ int wc_curve25519_delete(curve25519_key* key, curve25519_key** key_p) {
int wc_curve25519_init_ex(curve25519_key* key, void* heap, int devId)
{
if (key == NULL)
return BAD_FUNC_ARG;
int ret = 0;
XMEMSET(key, 0, sizeof(*key));
if (key == NULL) {
ret = BAD_FUNC_ARG;
}
else {
XMEMSET(key, 0, sizeof(*key));
/* currently the format for curve25519 */
key->dp = &curve25519_sets[0];
/* currently the format for curve25519 */
key->dp = &curve25519_sets[0];
#ifdef WOLF_CRYPTO_CB
key->devId = devId;
#else
(void)devId;
#endif
(void)heap; /* if needed for XMALLOC/XFREE in future */
#ifdef WOLF_CRYPTO_CB
key->devId = devId;
#else
(void)devId;
#endif
(void)heap; /* if needed for XMALLOC/XFREE in future */
#ifndef FREESCALE_LTC_ECC
fe_init();
#endif
#ifndef FREESCALE_LTC_ECC
fe_init();
#endif
#ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Add("wc_curve25519_init_ex key->k", key->k, CURVE25519_KEYSIZE);
#endif
#ifdef WOLFSSL_CHECK_MEM_ZERO
wc_MemZero_Add("wc_curve25519_init_ex key->k", key->k,
CURVE25519_KEYSIZE);
#endif
return 0;
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_X25519)
ret = wolfAsync_DevCtxInit(&key->asyncDev, WOLFSSL_ASYNC_MARKER_X25519,
heap, devId);
#endif
}
return ret;
}
int wc_curve25519_init(curve25519_key* key)
+12 -6
View File
@@ -55,7 +55,7 @@ Possible ECC enable options:
* WOLFSSL_ECC_CURVE_STATIC: default off (on for windows)
* For the ECC curve parameters `ecc_set_type` use fixed
* array for hex string
* WC_ECC_NONBLOCK: Enable non-blocking support for sign/verify.
* WC_ECC_NONBLOCK: Enable non-blocking support for sign/verify/keygen/secret.
* Requires SP with WOLFSSL_SP_NONBLOCK
* WC_ECC_NONBLOCK_ONLY Enable the non-blocking function only, no fall-back to
* normal blocking API's
@@ -15627,12 +15627,18 @@ int wc_ecc_get_key_id(ecc_key* key, word32* keyId)
/* Enable ECC support for non-blocking operations */
int wc_ecc_set_nonblock(ecc_key *key, ecc_nb_ctx_t* ctx)
{
if (key) {
if (ctx) {
XMEMSET(ctx, 0, sizeof(ecc_nb_ctx_t));
}
key->nb_ctx = ctx;
if (key == NULL) {
return BAD_FUNC_ARG;
}
/* If a different context is already set, clear it before replacing.
* The caller is responsible for freeing any heap-allocated context. */
if (key->nb_ctx != NULL && key->nb_ctx != ctx) {
XMEMSET(key->nb_ctx, 0, sizeof(ecc_nb_ctx_t));
}
if (ctx != NULL) {
XMEMSET(ctx, 0, sizeof(ecc_nb_ctx_t));
}
key->nb_ctx = ctx;
return 0;
}
#endif /* WC_ECC_NONBLOCK */
+250
View File
@@ -179,6 +179,256 @@ int curve25519(byte *result, const byte *n, const byte *p)
fe_normalize(result);
return 0;
}
#ifdef WC_X25519_NONBLOCK
int fe_inv__distinct_nb(byte *r, const byte *x, fe_inv__distinct_nb_ctx_t* ctx)
{
int ret = FP_WOULDBLOCK;
switch (ctx->state) {
case 0:
fe_mul__distinct(ctx->s, x, x);
fe_mul__distinct(r, ctx->s, x);
ctx->i = 0;
ctx->subState = 0;
ctx->state = 1;
break;
case 1:
if (ctx->i < 248) {
if (ctx->subState == 0) {
fe_mul__distinct(ctx->s, r, r);
ctx->subState = 1;
}
else {
fe_mul__distinct(r, ctx->s, x);
ctx->subState = 0;
++(ctx->i);
}
}
else {
ctx->state = 2;
ctx->subState = 0;
}
break;
case 2:
switch (ctx->subState) {
case 0:
fe_mul__distinct(ctx->s, r, r);
ctx->subState = 1;
break;
case 1:
fe_mul__distinct(r, ctx->s, ctx->s);
ctx->subState = 2;
break;
case 2:
fe_mul__distinct(ctx->s, r, x);
ctx->subState = 3;
break;
case 3:
fe_mul__distinct(r, ctx->s, ctx->s);
ctx->subState = 4;
break;
case 4:
fe_mul__distinct(ctx->s, r, r);
ctx->subState = 5;
break;
case 5:
fe_mul__distinct(r, ctx->s, x);
ctx->subState = 6;
break;
case 6:
fe_mul__distinct(ctx->s, r, r);
ctx->subState = 7;
break;
case 7:
fe_mul__distinct(r, ctx->s, x);
ret = 0;
break;
default:
ctx->subState = 0;
break;
}
break;
}
if (ret == 0) {
XMEMSET(ctx, 0, sizeof(fe_inv__distinct_nb_ctx_t));
}
return ret;
}
int curve25519_nb(byte *result, const byte *n, const byte *p,
struct x25519_nb_ctx_t* ctx)
{
int ret = FP_WOULDBLOCK;
switch (ctx->state) {
case 0:
XMEMSET(ctx->zm, 0, sizeof(ctx->zm));
ctx->zm[0] = 1;
XMEMSET(ctx->xm1, 0, sizeof(ctx->xm1));
ctx->xm1[0] = 1;
XMEMSET(ctx->zm1, 0, sizeof(ctx->zm1));
lm_copy(ctx->xm, p);
ctx->i = 253;
ctx->subState = 0;
ctx->state = 1;
break;
case 1:
if (ctx->i >= 0) {
switch (ctx->subState) {
case 0:
ctx->bit = (n[ctx->i >> 3] >> (ctx->i & 7)) & 1;
/* Diffadd step 1 */
lm_add(ctx->a, ctx->xm, ctx->zm);
lm_sub(ctx->b, ctx->xm1, ctx->zm1);
fe_mul__distinct(ctx->da, ctx->a, ctx->b);
ctx->subState = 1;
break;
case 1:
/* Diffadd step 2 */
lm_sub(ctx->b, ctx->xm, ctx->zm);
lm_add(ctx->a, ctx->xm1, ctx->zm1);
fe_mul__distinct(ctx->cb, ctx->a, ctx->b);
ctx->subState = 2;
break;
case 2:
/* Diffadd step 3 */
lm_add(ctx->a, ctx->da, ctx->cb);
fe_mul__distinct(ctx->b, ctx->a, ctx->a);
ctx->subState = 3;
break;
case 3:
/* Diffadd step 4 */
fe_mul__distinct(ctx->xm1, f25519_one, ctx->b);
ctx->subState = 4;
break;
case 4:
/* Diffadd step 5 */
lm_sub(ctx->a, ctx->da, ctx->cb);
fe_mul__distinct(ctx->b, ctx->a, ctx->a);
ctx->subState = 5;
break;
case 5:
/* Diffadd step 6 */
fe_mul__distinct(ctx->zm1, p, ctx->b);
ctx->subState = 6;
break;
case 6:
/* Double step 1 */
fe_mul__distinct(ctx->x1sq, ctx->xm, ctx->xm);
ctx->subState = 7;
break;
case 7:
/* Double step 2 */
fe_mul__distinct(ctx->z1sq, ctx->zm, ctx->zm);
ctx->subState = 8;
break;
case 8:
/* Double step 3 */
fe_mul__distinct(ctx->x1z1, ctx->xm, ctx->zm);
ctx->subState = 9;
break;
case 9:
/* Double step 4 */
lm_sub(ctx->a, ctx->x1sq, ctx->z1sq);
fe_mul__distinct(ctx->xm, ctx->a, ctx->a);
ctx->subState = 10;
break;
case 10:
/* Double step 5 */
fe_mul_c(ctx->a, ctx->x1z1, 486662);
lm_add(ctx->a, ctx->x1sq, ctx->a);
lm_add(ctx->a, ctx->z1sq, ctx->a);
fe_mul__distinct(ctx->x1sq, ctx->x1z1, ctx->a);
ctx->subState = 11;
break;
case 11:
fe_mul_c(ctx->zm, ctx->x1sq, 4);
ctx->subState = 12;
break;
case 12:
/* Diffadd2 step 1 */
lm_add(ctx->a, ctx->xm, ctx->zm);
lm_sub(ctx->b, p, f25519_one);
fe_mul__distinct(ctx->da, ctx->a, ctx->b);
ctx->subState = 13;
break;
case 13:
/* Diffadd2 step 2 */
lm_sub(ctx->b, ctx->xm, ctx->zm);
lm_add(ctx->a, p, f25519_one);
fe_mul__distinct(ctx->cb, ctx->a, ctx->b);
ctx->subState = 14;
break;
case 14:
/* Diffadd2 step 3 */
lm_add(ctx->a, ctx->da, ctx->cb);
fe_mul__distinct(ctx->b, ctx->a, ctx->a);
ctx->subState = 15;
break;
case 15:
/* Diffadd2 step 4 */
fe_mul__distinct(ctx->xms, ctx->zm1, ctx->b);
ctx->subState = 16;
break;
case 16:
/* Diffadd2 step 5 */
lm_sub(ctx->a, ctx->da, ctx->cb);
fe_mul__distinct(ctx->b, ctx->a, ctx->a);
ctx->subState = 17;
break;
case 17:
/* Diffadd2 step 6 */
fe_mul__distinct(ctx->zms, ctx->xm1, ctx->b);
ctx->subState = 18;
break;
case 18:
/* Select:
* bit = 1 --> (P_(2m+1), P_(2m))
* bit = 0 --> (P_(2m), P_(2m-1))
*/
fe_select(ctx->xm1, ctx->xm1, ctx->xm, ctx->bit);
fe_select(ctx->zm1, ctx->zm1, ctx->zm, ctx->bit);
fe_select(ctx->xm, ctx->xm, ctx->xms, ctx->bit);
fe_select(ctx->zm, ctx->zm, ctx->zms, ctx->bit);
--(ctx->i);
ctx->subState = 0;
break;
default:
ctx->subState = 0;
break;
}
}
else {
ctx->state = 2;
}
break;
case 2:
/* Freeze out of projective coordinates */
if (fe_inv__distinct_nb(ctx->zm1, ctx->zm,
&ctx->inv_distinct_nb_ctx) == 0) {
ctx->state = 3;
}
break;
case 3:
fe_mul__distinct(result, ctx->zm1, ctx->xm);
fe_normalize(result);
ret = 0;
break;
}
if (ret == 0) {
XMEMSET(ctx, 0, sizeof(x25519_nb_ctx_t));
}
return ret;
}
#endif /* WC_X25519_NONBLOCK */
#endif /* !FREESCALE_LTC_ECC */
#endif /* CURVE25519_SMALL */
+12 -12
View File
@@ -74917,6 +74917,9 @@ static int sp_256_proj_point_add_8_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
int err = FP_WOULDBLOCK;
sp_256_proj_point_add_8_ctx* ctx = (sp_256_proj_point_add_8_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_8_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_256* a = p;
@@ -74924,9 +74927,6 @@ static int sp_256_proj_point_add_8_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_8_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -92908,6 +92908,9 @@ static int sp_384_proj_point_add_12_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
int err = FP_WOULDBLOCK;
sp_384_proj_point_add_12_ctx* ctx = (sp_384_proj_point_add_12_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_12_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_384* a = p;
@@ -92915,9 +92918,6 @@ static int sp_384_proj_point_add_12_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_12_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -119987,6 +119987,9 @@ static int sp_521_proj_point_add_17_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
int err = FP_WOULDBLOCK;
sp_521_proj_point_add_17_ctx* ctx = (sp_521_proj_point_add_17_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_17_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_521* a = p;
@@ -119994,9 +119997,6 @@ static int sp_521_proj_point_add_17_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_17_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -150008,6 +150008,9 @@ static int sp_1024_proj_point_add_32_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
int err = FP_WOULDBLOCK;
sp_1024_proj_point_add_32_ctx* ctx = (sp_1024_proj_point_add_32_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_32_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_1024* a = p;
@@ -150015,9 +150018,6 @@ static int sp_1024_proj_point_add_32_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_32_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
+12 -12
View File
@@ -23532,6 +23532,9 @@ static int sp_256_proj_point_add_4_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
int err = FP_WOULDBLOCK;
sp_256_proj_point_add_4_ctx* ctx = (sp_256_proj_point_add_4_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_4_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_256* a = p;
@@ -23539,9 +23542,6 @@ static int sp_256_proj_point_add_4_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_4_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -44108,6 +44108,9 @@ static int sp_384_proj_point_add_6_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
int err = FP_WOULDBLOCK;
sp_384_proj_point_add_6_ctx* ctx = (sp_384_proj_point_add_6_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_6_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_384* a = p;
@@ -44115,9 +44118,6 @@ static int sp_384_proj_point_add_6_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_6_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -72055,6 +72055,9 @@ static int sp_521_proj_point_add_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
int err = FP_WOULDBLOCK;
sp_521_proj_point_add_9_ctx* ctx = (sp_521_proj_point_add_9_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_521* a = p;
@@ -72062,9 +72065,6 @@ static int sp_521_proj_point_add_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -115721,6 +115721,9 @@ static int sp_1024_proj_point_add_16_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
int err = FP_WOULDBLOCK;
sp_1024_proj_point_add_16_ctx* ctx = (sp_1024_proj_point_add_16_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_16_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_1024* a = p;
@@ -115728,9 +115731,6 @@ static int sp_1024_proj_point_add_16_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_16_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
+12 -12
View File
@@ -100369,6 +100369,9 @@ static int sp_256_proj_point_add_8_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
int err = FP_WOULDBLOCK;
sp_256_proj_point_add_8_ctx* ctx = (sp_256_proj_point_add_8_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_8_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_256* a = p;
@@ -100376,9 +100379,6 @@ static int sp_256_proj_point_add_8_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_8_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -110760,6 +110760,9 @@ static int sp_384_proj_point_add_12_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
int err = FP_WOULDBLOCK;
sp_384_proj_point_add_12_ctx* ctx = (sp_384_proj_point_add_12_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_12_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_384* a = p;
@@ -110767,9 +110770,6 @@ static int sp_384_proj_point_add_12_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_12_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -123926,6 +123926,9 @@ static int sp_521_proj_point_add_17_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
int err = FP_WOULDBLOCK;
sp_521_proj_point_add_17_ctx* ctx = (sp_521_proj_point_add_17_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_17_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_521* a = p;
@@ -123933,9 +123936,6 @@ static int sp_521_proj_point_add_17_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_17_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -208389,6 +208389,9 @@ static int sp_1024_proj_point_add_32_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
int err = FP_WOULDBLOCK;
sp_1024_proj_point_add_32_ctx* ctx = (sp_1024_proj_point_add_32_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_32_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_1024* a = p;
@@ -208396,9 +208399,6 @@ static int sp_1024_proj_point_add_32_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_32_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
+12 -12
View File
@@ -19982,6 +19982,9 @@ static int sp_256_proj_point_add_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
int err = FP_WOULDBLOCK;
sp_256_proj_point_add_9_ctx* ctx = (sp_256_proj_point_add_9_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_256* a = p;
@@ -19989,9 +19992,6 @@ static int sp_256_proj_point_add_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -26983,6 +26983,9 @@ static int sp_384_proj_point_add_15_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
int err = FP_WOULDBLOCK;
sp_384_proj_point_add_15_ctx* ctx = (sp_384_proj_point_add_15_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_15_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_384* a = p;
@@ -26990,9 +26993,6 @@ static int sp_384_proj_point_add_15_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_15_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -34228,6 +34228,9 @@ static int sp_521_proj_point_add_21_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
int err = FP_WOULDBLOCK;
sp_521_proj_point_add_21_ctx* ctx = (sp_521_proj_point_add_21_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_21_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_521* a = p;
@@ -34235,9 +34238,6 @@ static int sp_521_proj_point_add_21_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_21_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -42594,6 +42594,9 @@ static int sp_1024_proj_point_add_42_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
int err = FP_WOULDBLOCK;
sp_1024_proj_point_add_42_ctx* ctx = (sp_1024_proj_point_add_42_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_42_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_1024* a = p;
@@ -42601,9 +42604,6 @@ static int sp_1024_proj_point_add_42_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_42_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
+12 -12
View File
@@ -20599,6 +20599,9 @@ static int sp_256_proj_point_add_5_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
int err = FP_WOULDBLOCK;
sp_256_proj_point_add_5_ctx* ctx = (sp_256_proj_point_add_5_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_5_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_256* a = p;
@@ -20606,9 +20609,6 @@ static int sp_256_proj_point_add_5_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_5_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -27087,6 +27087,9 @@ static int sp_384_proj_point_add_7_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
int err = FP_WOULDBLOCK;
sp_384_proj_point_add_7_ctx* ctx = (sp_384_proj_point_add_7_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_7_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_384* a = p;
@@ -27094,9 +27097,6 @@ static int sp_384_proj_point_add_7_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_7_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -34191,6 +34191,9 @@ static int sp_521_proj_point_add_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
int err = FP_WOULDBLOCK;
sp_521_proj_point_add_9_ctx* ctx = (sp_521_proj_point_add_9_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_521* a = p;
@@ -34198,9 +34201,6 @@ static int sp_521_proj_point_add_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -41643,6 +41643,9 @@ static int sp_1024_proj_point_add_18_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
int err = FP_WOULDBLOCK;
sp_1024_proj_point_add_18_ctx* ctx = (sp_1024_proj_point_add_18_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_18_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_1024* a = p;
@@ -41650,9 +41653,6 @@ static int sp_1024_proj_point_add_18_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_18_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
+12 -12
View File
@@ -36307,6 +36307,9 @@ static int sp_256_proj_point_add_8_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
int err = FP_WOULDBLOCK;
sp_256_proj_point_add_8_ctx* ctx = (sp_256_proj_point_add_8_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_8_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_256* a = p;
@@ -36314,9 +36317,6 @@ static int sp_256_proj_point_add_8_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_8_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -46218,6 +46218,9 @@ static int sp_384_proj_point_add_12_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
int err = FP_WOULDBLOCK;
sp_384_proj_point_add_12_ctx* ctx = (sp_384_proj_point_add_12_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_12_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_384* a = p;
@@ -46225,9 +46228,6 @@ static int sp_384_proj_point_add_12_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_12_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -58009,6 +58009,9 @@ static int sp_521_proj_point_add_17_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
int err = FP_WOULDBLOCK;
sp_521_proj_point_add_17_ctx* ctx = (sp_521_proj_point_add_17_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_17_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_521* a = p;
@@ -58016,9 +58019,6 @@ static int sp_521_proj_point_add_17_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_17_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -72548,6 +72548,9 @@ static int sp_1024_proj_point_add_32_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
int err = FP_WOULDBLOCK;
sp_1024_proj_point_add_32_ctx* ctx = (sp_1024_proj_point_add_32_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_32_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_1024* a = p;
@@ -72555,9 +72558,6 @@ static int sp_1024_proj_point_add_32_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_32_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
+24 -24
View File
@@ -8505,6 +8505,9 @@ static int sp_256_proj_point_add_4_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
int err = FP_WOULDBLOCK;
sp_256_proj_point_add_4_ctx* ctx = (sp_256_proj_point_add_4_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_4_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_256* a = p;
@@ -8512,9 +8515,6 @@ static int sp_256_proj_point_add_4_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_4_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -9606,6 +9606,9 @@ static int sp_256_proj_point_add_avx2_4_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r
int err = FP_WOULDBLOCK;
sp_256_proj_point_add_avx2_4_ctx* ctx = (sp_256_proj_point_add_avx2_4_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_avx2_4_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_256* a = p;
@@ -9613,9 +9616,6 @@ static int sp_256_proj_point_add_avx2_4_nb(sp_ecc_ctx_t* sp_ctx, sp_point_256* r
q = a;
}
typedef char ctx_size_test[sizeof(sp_256_proj_point_add_avx2_4_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -27196,6 +27196,9 @@ static int sp_384_proj_point_add_6_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
int err = FP_WOULDBLOCK;
sp_384_proj_point_add_6_ctx* ctx = (sp_384_proj_point_add_6_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_6_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_384* a = p;
@@ -27203,9 +27206,6 @@ static int sp_384_proj_point_add_6_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_6_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -28350,6 +28350,9 @@ static int sp_384_proj_point_add_avx2_6_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r
int err = FP_WOULDBLOCK;
sp_384_proj_point_add_avx2_6_ctx* ctx = (sp_384_proj_point_add_avx2_6_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_avx2_6_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_384* a = p;
@@ -28357,9 +28360,6 @@ static int sp_384_proj_point_add_avx2_6_nb(sp_ecc_ctx_t* sp_ctx, sp_point_384* r
q = a;
}
typedef char ctx_size_test[sizeof(sp_384_proj_point_add_avx2_6_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -51673,6 +51673,9 @@ static int sp_521_proj_point_add_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
int err = FP_WOULDBLOCK;
sp_521_proj_point_add_9_ctx* ctx = (sp_521_proj_point_add_9_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_521* a = p;
@@ -51680,9 +51683,6 @@ static int sp_521_proj_point_add_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -52804,6 +52804,9 @@ static int sp_521_proj_point_add_avx2_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r
int err = FP_WOULDBLOCK;
sp_521_proj_point_add_avx2_9_ctx* ctx = (sp_521_proj_point_add_avx2_9_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_avx2_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_521* a = p;
@@ -52811,9 +52814,6 @@ static int sp_521_proj_point_add_avx2_9_nb(sp_ecc_ctx_t* sp_ctx, sp_point_521* r
q = a;
}
typedef char ctx_size_test[sizeof(sp_521_proj_point_add_avx2_9_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -92503,6 +92503,9 @@ static int sp_1024_proj_point_add_16_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
int err = FP_WOULDBLOCK;
sp_1024_proj_point_add_16_ctx* ctx = (sp_1024_proj_point_add_16_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_16_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_1024* a = p;
@@ -92510,9 +92513,6 @@ static int sp_1024_proj_point_add_16_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024* r,
q = a;
}
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_16_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
@@ -93604,6 +93604,9 @@ static int sp_1024_proj_point_add_avx2_16_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024
int err = FP_WOULDBLOCK;
sp_1024_proj_point_add_avx2_16_ctx* ctx = (sp_1024_proj_point_add_avx2_16_ctx*)sp_ctx->data;
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_avx2_16_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
/* Ensure only the first point is the same as the result. */
if (q == r) {
const sp_point_1024* a = p;
@@ -93611,9 +93614,6 @@ static int sp_1024_proj_point_add_avx2_16_nb(sp_ecc_ctx_t* sp_ctx, sp_point_1024
q = a;
}
typedef char ctx_size_test[sizeof(sp_1024_proj_point_add_avx2_16_ctx) >= sizeof(*sp_ctx) ? -1 : 1];
(void)sizeof(ctx_size_test);
switch (ctx->state) {
case 0: /* INIT */
ctx->t6 = t;
+184 -4
View File
@@ -38247,7 +38247,12 @@ static wc_test_ret_t curve25519_overflow_test(WC_RNG* rng)
/* test against known test vector */
XMEMSET(shared, 0, sizeof(shared));
y = sizeof(shared);
if (wc_curve25519_shared_secret(&userA, &userA, shared, &y) != 0) {
ret = wc_curve25519_shared_secret(&userA, &userA, shared, &y);
#if defined(WOLFSSL_ASYNC_CRYPT)
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
ret = wc_AsyncWait(ret, &userA.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0) {
ret = WC_TEST_RET_ENC_I(i); break;
}
@@ -38625,6 +38630,131 @@ static wc_test_ret_t curve255519_der_test(void)
}
#endif /* !NO_ASN && HAVE_CURVE25519_KEY_EXPORT && HAVE_CURVE25519_KEY_IMPORT */
#ifdef WC_X25519_NONBLOCK
/* build and test with:
* ./configure --enable-curve25519=nonblock CFLAGS="-DWOLFSSL_DEBUG_NONBLOCK"
* make
* ./wolfcrypt/test/testwolfcrypt
*/
static int x25519_nonblock_test(WC_RNG* rng)
{
int ret = 0;
x25519_nb_ctx_t nb_ctx;
curve25519_key userA;
curve25519_key userB;
#ifdef HAVE_CURVE25519_SHARED_SECRET
byte sharedA[32];
byte sharedB[32];
word32 x;
word32 y;
#endif
int count;
XMEMSET(&nb_ctx, 0, sizeof(nb_ctx));
ret = wc_curve25519_init(&userA);
if (ret != 0) {
printf("wc_curve25519_init 1 %d\n", ret);
return -10722;
}
ret = wc_curve25519_set_nonblock(&userA, &nb_ctx);
if (ret != 0) {
printf("wc_curve25519_set_nonblock 1 %d\n", ret);
wc_curve25519_free(&userA);
return -10723;
}
count = 0;
do {
ret = wc_curve25519_make_key(rng, 32, &userA);
count++;
} while (ret == FP_WOULDBLOCK);
if (ret != 0) {
printf("wc_curve25519_make_key_nb 1 %d\n", ret);
wc_curve25519_free(&userA);
return -10724;
}
#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_DEBUG_NONBLOCK)
/* CURVE25519 non-block key gen: 5335 times */
printf("CURVE25519 non-block key gen: %d times\n", count);
#endif
ret = wc_curve25519_init(&userB);
if (ret != 0) {
printf("wc_curve25519_init 2 %d\n", ret);
wc_curve25519_free(&userA);
return -10724;
}
ret = wc_curve25519_set_nonblock(&userB, &nb_ctx);
if (ret != 0) {
printf("wc_curve25519_set_nonblock 2 %d\n", ret);
wc_curve25519_free(&userA);
wc_curve25519_free(&userB);
return -10725;
}
count = 0;
do {
ret = wc_curve25519_make_key(rng, 32, &userB);
count++;
} while (ret == FP_WOULDBLOCK);
if (ret != 0) {
printf("wc_curve25519_make_key_nb 2 %d\n", ret);
wc_curve25519_free(&userA);
wc_curve25519_free(&userB);
return -10726;
}
#ifdef HAVE_CURVE25519_SHARED_SECRET
x = sizeof(sharedA);
do {
ret = wc_curve25519_shared_secret(&userA, &userB, sharedA, &x);
} while (ret == FP_WOULDBLOCK);
if (ret != 0) {
printf("wc_curve25519_shared_secret_nb 1 %d\n", ret);
wc_curve25519_free(&userA);
wc_curve25519_free(&userB);
return -10727;
}
y = sizeof(sharedB);
count = 0;
do {
ret = wc_curve25519_shared_secret(&userB, &userA, sharedB, &y);
count++;
}
while (ret == FP_WOULDBLOCK);
if (ret != 0) {
printf("wc_curve25519_shared_secret_nb 2 %d\n", ret);
wc_curve25519_free(&userA);
wc_curve25519_free(&userB);
return -10728;
}
#if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_DEBUG_NONBLOCK)
/* CURVE25519 non-block shared secret: 5337 times */
printf("CURVE25519 non-block shared secret: %d times\n", count);
#endif
/* compare shared secret keys to test they are the same */
if (y != x) {
wc_curve25519_free(&userA);
wc_curve25519_free(&userB);
return -10729;
}
if (XMEMCMP(sharedA, sharedB, x) != 0) {
wc_curve25519_free(&userA);
wc_curve25519_free(&userB);
return -10730;
}
#endif /* HAVE_CURVE25519_SHARED_SECRET */
wc_curve25519_free(&userA);
wc_curve25519_free(&userB);
return 0;
}
#endif /* WC_X25519_NONBLOCK */
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t curve25519_test(void)
{
WC_RNG rng;
@@ -38726,23 +38856,41 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t curve25519_test(void)
/* make curve25519 keys */
ret = wc_curve25519_make_key(&rng, 32, userA);
#if defined(WOLFSSL_ASYNC_CRYPT)
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
ret = wc_AsyncWait(ret, &userA->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), cleanup);
ret = wc_curve25519_make_key(&rng, 32, userB);
#if defined(WOLFSSL_ASYNC_CRYPT)
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), cleanup);
#ifdef HAVE_CURVE25519_SHARED_SECRET
/* find shared secret key */
x = sizeof(sharedA);
if ((ret = wc_curve25519_shared_secret(userA, userB, sharedA, &x)) != 0) {
ret = wc_curve25519_shared_secret(userA, userB, sharedA, &x);
#if defined(WOLFSSL_ASYNC_CRYPT)
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
ret = wc_AsyncWait(ret, &userA->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0) {
printf("wc_curve25519_shared_secret 1 failed\n");
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), cleanup);
}
y = sizeof(sharedB);
if ((ret = wc_curve25519_shared_secret(userB, userA, sharedB, &y)) != 0) {
ret = wc_curve25519_shared_secret(userB, userA, sharedB, &y);
#if defined(WOLFSSL_ASYNC_CRYPT)
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0) {
printf("wc_curve25519_shared_secret 2 failed\n");
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), cleanup);
}
@@ -38774,7 +38922,12 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t curve25519_test(void)
/* test shared key after importing a public key */
XMEMSET(sharedB, 0, sizeof(sharedB));
y = sizeof(sharedB);
if (wc_curve25519_shared_secret(userB, pubKey, sharedB, &y) != 0) {
ret = wc_curve25519_shared_secret(userB, pubKey, sharedB, &y);
#if defined(WOLFSSL_ASYNC_CRYPT)
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0) {
ERROR_OUT(WC_TEST_RET_ENC_NC, cleanup);
}
@@ -38796,6 +38949,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t curve25519_test(void)
XMEMSET(sharedB, 0, sizeof(sharedB));
y = sizeof(sharedB);
ret = wc_curve25519_shared_secret(userA, userB, sharedB, &y);
#if defined(WOLFSSL_ASYNC_CRYPT)
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
ret = wc_AsyncWait(ret, &userA->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), cleanup);
@@ -38806,6 +38963,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t curve25519_test(void)
XMEMSET(sharedB, 0, sizeof(sharedB));
y = sizeof(sharedB);
ret = wc_curve25519_shared_secret(userB, userA, sharedB, &y);
#if defined(WOLFSSL_ASYNC_CRYPT)
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), cleanup);
@@ -38825,16 +38986,28 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t curve25519_test(void)
#endif
ret = wc_curve25519_make_key(&rng, 32, userB);
#if defined(WOLFSSL_ASYNC_CRYPT)
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), cleanup);
x = sizeof(sharedA);
ret = wc_curve25519_shared_secret(userA, userB, sharedA, &x);
#if defined(WOLFSSL_ASYNC_CRYPT)
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
ret = wc_AsyncWait(ret, &userA->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), cleanup);
y = sizeof(sharedB);
ret = wc_curve25519_shared_secret(userB, userA, sharedB, &y);
#if defined(WOLFSSL_ASYNC_CRYPT)
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
ret = wc_AsyncWait(ret, &userB->asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (ret != 0)
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), cleanup);
@@ -38860,6 +39033,13 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t curve25519_test(void)
goto cleanup;
#endif
#ifdef WC_X25519_NONBLOCK
ret = x25519_nonblock_test(&rng);
if (ret != 0) {
goto cleanup;
}
#endif /* WC_X25519_NONBLOCK */
cleanup:
/* clean up keys when done */
+12 -12
View File
@@ -6851,14 +6851,14 @@ static const unsigned char server_ed25519_cert[] =
};
#define sizeof_server_ed25519_cert (sizeof(server_ed25519_cert))
/* ./certs/ed25519/server-ed25519-key.der, ED25519 */
/* ./certs/ed25519/server-ed25519-priv.der, ED25519 */
static const unsigned char server_ed25519_key[] =
{
0x30, 0x2A, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x03,
0x21, 0x00, 0x23, 0xAA, 0x4D, 0x60, 0x50, 0xE0, 0x13, 0xD3,
0x3A, 0xED, 0xAB, 0xF6, 0xA9, 0xCC, 0x4A, 0xFE, 0xD7, 0x4D,
0x2F, 0xD2, 0x5B, 0x1A, 0x10, 0x05, 0xEF, 0x5A, 0x41, 0x25,
0xCE, 0x1B, 0x53, 0x78
0x30, 0x2E, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2B,
0x65, 0x70, 0x04, 0x22, 0x04, 0x20, 0x8E, 0x98, 0x44, 0xB0,
0x54, 0x81, 0xC6, 0x3A, 0x47, 0xD8, 0xFB, 0xC3, 0x36, 0xBF,
0x19, 0x70, 0x61, 0x09, 0x23, 0x76, 0xE3, 0x1C, 0x6F, 0x83,
0x38, 0xAE, 0x49, 0x55, 0xC5, 0x9E, 0x87, 0x22
};
#define sizeof_server_ed25519_key (sizeof(server_ed25519_key))
@@ -7030,14 +7030,14 @@ static const unsigned char client_ed25519_cert[] =
};
#define sizeof_client_ed25519_cert (sizeof(client_ed25519_cert))
/* ./certs/ed25519/client-ed25519-key.der, ED25519 */
/* ./certs/ed25519/client-ed25519-priv.der, ED25519 */
static const unsigned char client_ed25519_key[] =
{
0x30, 0x2A, 0x30, 0x05, 0x06, 0x03, 0x2B, 0x65, 0x70, 0x03,
0x21, 0x00, 0xE6, 0x57, 0x5B, 0x13, 0x1B, 0xC7, 0x51, 0x14,
0x6B, 0xED, 0x3B, 0xF5, 0xD1, 0xFA, 0xAB, 0x9E, 0x6C, 0xB6,
0xEB, 0x02, 0x09, 0xA3, 0x99, 0xF5, 0x6E, 0xBF, 0x9D, 0x3C,
0xFE, 0x54, 0x39, 0xE6
0x30, 0x2E, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2B,
0x65, 0x70, 0x04, 0x22, 0x04, 0x20, 0x92, 0xB5, 0x4C, 0xEC,
0xAF, 0x81, 0xC6, 0xBB, 0x01, 0xD6, 0xD5, 0xDE, 0xBD, 0x37,
0x97, 0x5A, 0xD2, 0xC6, 0xF6, 0xC3, 0x85, 0xB5, 0x3B, 0xE6,
0xE4, 0xEC, 0x32, 0xE9, 0xC7, 0xCA, 0x52, 0xEB
};
#define sizeof_client_ed25519_key (sizeof(client_ed25519_key))
+27
View File
@@ -81,6 +81,10 @@ struct WC_ASYNC_DEV;
ASYNC_SW_DES3_CBC_ENCRYPT = 13,
ASYNC_SW_DES3_CBC_DECRYPT = 14,
#endif /* !NO_DES3 */
#ifdef HAVE_CURVE25519
ASYNC_SW_X25519_MAKE = 15,
ASYNC_SW_X25519_SHARED_SEC = 16,
#endif /* HAVE_CURVE25519 */
};
#ifdef HAVE_ECC
@@ -179,6 +183,21 @@ struct WC_ASYNC_DEV;
};
#endif /* !NO_DES3 */
#ifdef HAVE_CURVE25519
struct AsyncCryptX25519Make {
void* rng; /* WC_RNG */
void* key; /* curve25519_key */
int size;
};
struct AsyncCryptX25519SharedSec {
void* priv; /* curve25519_key */
void* pub; /* curve25519_key */
byte* out;
word32* outLen;
int endian;
};
#endif /* HAVE_CURVE25519 */
#ifdef __CC_ARM
#pragma push
#pragma anon_unions
@@ -211,6 +230,10 @@ struct WC_ASYNC_DEV;
#ifndef NO_DES3
struct AsyncCryptSwDes des;
#endif /* !NO_DES3 */
#ifdef HAVE_CURVE25519
struct AsyncCryptX25519Make x25519Make;
struct AsyncCryptX25519SharedSec x25519SharedSec;
#endif /* HAVE_CURVE25519 */
#ifdef HAVE_ANONYMOUS_INLINE_AGGREGATES
}; /* union */
#endif
@@ -288,6 +311,9 @@ struct WC_ASYNC_DEV;
#ifndef WC_ASYNC_NO_DH
#define WC_ASYNC_ENABLE_DH
#endif
#ifndef WC_ASYNC_NO_X25519
#define WC_ASYNC_ENABLE_X25519
#endif
#endif /* WC_ASYNC_NO_PKI */
#ifndef WC_ASYNC_NO_HASH
#ifndef WC_ASYNC_NO_SHA512
@@ -337,6 +363,7 @@ struct WC_ASYNC_DEV;
#define WOLFSSL_ASYNC_MARKER_MD5 0xBEEF000D
#define WOLFSSL_ASYNC_MARKER_DH 0xBEEF000E
#define WOLFSSL_ASYNC_MARKER_SHA3 0xBEEF000F
#define WOLFSSL_ASYNC_MARKER_X25519 0xBEEF0010
/* event flags (bit mask) */
+64
View File
@@ -74,6 +74,46 @@ typedef struct ECPoint {
#define WC_CURVE25519KEY_TYPE_DEFINED
#endif
#ifdef WC_X25519_NONBLOCK
typedef struct fe_inv__distinct_nb_ctx_t {
int state;
int subState;
byte s[F25519_SIZE];
int i;
} fe_inv__distinct_nb_ctx_t;
typedef struct x25519_nb_ctx_t {
/* state for curve25519 operation */
int state;
int subState;
/* state for shared secret */
int ssState;
int i;
int bit;
/* Current point: P_m */
byte xm[F25519_SIZE];
byte zm[F25519_SIZE];
/* Predecessor: P_(m-1) */
byte xm1[F25519_SIZE];
byte zm1[F25519_SIZE];
/* Temporary P_(2m+1) */
byte xms[F25519_SIZE];
byte zms[F25519_SIZE];
/* Temporary buffers for non-blocking diffadd/double */
byte a[F25519_SIZE];
byte b[F25519_SIZE];
byte da[F25519_SIZE];
byte cb[F25519_SIZE];
byte x1sq[F25519_SIZE];
byte z1sq[F25519_SIZE];
byte x1z1[F25519_SIZE];
fe_inv__distinct_nb_ctx_t inv_distinct_nb_ctx;
ECPoint o; /* point for shared secret */
} x25519_nb_ctx_t;
#endif /* WC_X25519_NONBLOCK */
/* A CURVE25519 Key */
struct curve25519_key {
int idx; /* Index into the ecc_sets[] for the parameters of
@@ -100,6 +140,10 @@ struct curve25519_key {
byte keyIdSet;
#endif
#ifdef WC_X25519_NONBLOCK
x25519_nb_ctx_t* nb_ctx;
#endif /* WC_X25519_NONBLOCK */
/* bit fields */
WC_BITFIELD pubSet:1;
WC_BITFIELD privSet:1;
@@ -137,6 +181,26 @@ int wc_curve25519_make_priv(WC_RNG* rng, int keysize, byte* priv);
WOLFSSL_API
int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key);
#ifdef WC_X25519_NONBLOCK
/*!
\brief Enable non-blocking support for X25519 operations on a key.
When enabled, wc_curve25519_make_key() and
wc_curve25519_shared_secret() will return FP_WOULDBLOCK during
operation, allowing the caller to
yield and resume. Requires WC_X25519_NONBLOCK and CURVE25519_SMALL.
\param key Pointer to curve25519_key structure to configure
\param ctx Pointer to x25519_nb_ctx_t context for state tracking,
or NULL to disable non-blocking mode
\return 0 on success, BAD_FUNC_ARG if key is NULL
*/
WOLFSSL_API
int wc_curve25519_set_nonblock(curve25519_key* key, x25519_nb_ctx_t* ctx);
#endif /* WC_X25519_NONBLOCK */
WOLFSSL_API
int wc_curve25519_shared_secret(curve25519_key* private_key,
curve25519_key* public_key,
+38 -11
View File
@@ -68,25 +68,52 @@ Bounds on each t[i] vary depending on context.
#endif
#if defined(CURVE25519_SMALL) || defined(ED25519_SMALL)
#define F25519_SIZE 32
WOLFSSL_LOCAL void lm_copy(byte* x, const byte* a);
WOLFSSL_LOCAL void lm_add(byte* r, const byte* a, const byte* b);
WOLFSSL_LOCAL void lm_sub(byte* r, const byte* a, const byte* b);
WOLFSSL_LOCAL void lm_neg(byte* r,const byte* a);
WOLFSSL_LOCAL void lm_invert(byte* r, const byte* x);
WOLFSSL_LOCAL void lm_mul(byte* r,const byte* a, const byte* b);
#define F25519_SIZE 32
#include <wolfssl/wolfcrypt/curve25519.h>
WOLFSSL_LOCAL void lm_copy(byte*, const byte*);
WOLFSSL_LOCAL void lm_add(byte*, const byte*, const byte*);
WOLFSSL_LOCAL void lm_sub(byte*, const byte*, const byte*);
WOLFSSL_LOCAL void lm_neg(byte*,const byte*);
WOLFSSL_LOCAL void lm_invert(byte*, const byte*);
WOLFSSL_LOCAL void lm_mul(byte*,const byte*,const byte*);
#ifdef WC_X25519_NONBLOCK
/* Use standard wolfSSL non-blocking error code */
#ifndef FP_WOULDBLOCK
#include <wolfssl/wolfcrypt/error-crypt.h>
#define FP_WOULDBLOCK MP_WOULDBLOCK
#endif
struct fe_inv__distinct_nb_ctx_t;
struct x25519_nb_ctx_t;
WOLFSSL_LOCAL int fe_inv__distinct_nb(byte *r, const byte *x,
struct fe_inv__distinct_nb_ctx_t* ctx);
WOLFSSL_LOCAL int curve25519_nb(byte * q, const byte * n, const byte * p,
struct x25519_nb_ctx_t* ctx);
#endif /* WC_X25519_NONBLOCK */
#else
#ifdef WC_X25519_NONBLOCK
#error The X25519 non-blocking requires CURVE25519_SMALL \
(--enable-curve25519=small)
#endif
#endif /* CURVE25519_SMALL || ED25519_SMALL */
#if !defined(FREESCALE_LTC_ECC)
WOLFSSL_LOCAL void fe_init(void);
WOLFSSL_LOCAL int curve25519_base(byte * q, const byte * n);
WOLFSSL_LOCAL int curve25519(byte * q, const byte * n, const byte * p);
WOLFSSL_LOCAL int curve25519(byte * q, const byte * n, const byte * p);
#ifdef WOLFSSL_CURVE25519_BLINDING
WOLFSSL_LOCAL int curve25519_blind(byte * q, const byte * n, const byte* mask,
const byte * p, const byte* rz);
WOLFSSL_LOCAL int curve25519_blind(byte* q, const byte* n, const byte* mask,
const byte* p, const byte* rz);
#endif
#endif