mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-05 11:20:55 +02:00
Merge pull request #9721 from dgarske/x25519_nb
Add X25519 non-blocking support and async example improvements
This commit is contained in:
@@ -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
|
||||
@@ -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',
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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))
|
||||
|
||||
|
||||
@@ -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) */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user