Update Arduino examples; add wolfcrypt breadcrumbs.

pull/7304/head
gojimmypi 2024-03-06 15:13:37 -08:00
parent 39ad67607e
commit e40eb3c774
16 changed files with 1971 additions and 366 deletions

13
.gitignore vendored
View File

@ -82,16 +82,19 @@ snifftest
output
mcapi/test
testsuite/testsuite
tests/unit
testsuite/testsuite.test
testsuite/*.der
testsuite/*.pem
testsuite/*.raw
testsuite/*.obj
testsuite/*.pdb
testsuite/*.idb
tests/unit
tests/unit.test
tests/bio_write_test.txt
tests/test-log-dump-to-file.txt
tests/cert_cache.tmp
test-write-dhparams.pem
testsuite/*.der
testsuite/*.pem
testsuite/*.raw
cert.der
cert.pem
certecc.der
@ -402,7 +405,7 @@ XXX-fips-test
# Generated user_settings_asm.h.
user_settings_asm.h
# VisualGD
# VisualGDB
**/.visualgdb
# Espressif sdk config default should be saved in sdkconfig.defaults

View File

@ -1,4 +1,13 @@
# Arduino wolfSSL Library
The library is modified from wolfSSL Release ${WOLFSSL_VERSION} for the Arduino platform.
This library is restructured from [wolfSSL](https://github.com/wolfSSL/wolfssl/) Release ${WOLFSSL_VERSION} for the Arduino platform.
The Official wolfSSL Arduino Library is found in [The Library Manager index](http://downloads.arduino.cc/libraries/library_index.json).
See the [Arduino-wolfSSL logs](https://downloads.arduino.cc/libraries/logs/github.com/wolfSSL/Arduino-wolfSSL/).
## Arduino Releases
The first Official wolfSSL Arduino Library is `5.6.6-Arduino.1`: a slightly modified, post [release 5.6.6](https://github.com/wolfSSL/wolfssl/releases/tag/v5.6.6-stable) version update.
See other [wolfSSL releases versions](https://github.com/wolfSSL/wolfssl/releases). The `./wolfssl-arduino.sh INSTALL` [script](https://github.com/wolfSSL/wolfssl/tree/master/IDE/ARDUINO) can be used to install specific GitHub versions as needed.

View File

@ -1,5 +1,14 @@
# wolfSSL with Arduino
See the [example sketches](./sketches/README.md):
- [sketches/wolfssl_server](./sketches/wolfssl_server/README.md)
- [sketches/wolfssl_client](./sketches/wolfssl_client/README.md)
When publishing a new version to the Arduino Registry, be sure to edit `WOLFSSL_VERSION_ARUINO_SUFFIX` in the `wolfssl-arduino.sh` script.
## Boards
Many of the supported boards are natively built-in to the [Arduino IDE Board Manager](https://docs.arduino.cc/software/ide-v2/tutorials/ide-v2-board-manager/)
and by adding [additional cores](https://docs.arduino.cc/learn/starting-guide/cores/) as needed.
@ -12,7 +21,7 @@ https://github.com/stm32duino/BoardManagerFiles/raw/main/package_stmicroelectron
## Using wolfSSL from the Arduino IDE
Coming soon! https://github.com/wolfSSL/arduino-wolfSSL See [PR #1](https://github.com/wolfSSL/Arduino-wolfSSL/pull/1).
The Official wolfSSL: https://github.com/wolfSSL/arduino-wolfSSL See [PR #1](https://github.com/wolfSSL/Arduino-wolfSSL/pull/1).
This option will allow wolfSSL to be installed directly using the native Arduino tools.
@ -28,7 +37,7 @@ directory and creates a stub header file called `wolfssl.h` inside that director
### Step 1:
To configure wolfSSL with Arduino, enter one of the following commands
To configure wolfSSL with Arduino, enter ONE of the following 4 commands
from within the `wolfssl/IDE/ARDUINO` directory:
1. `./wolfssl-arduino.sh`
@ -93,9 +102,25 @@ Open an example Arduino sketch for wolfSSL:
#### Script Examples
Publish wolfSSL from WSL to a repository.
Refresh the local Windows Arduino wolfSSL library from GitHub repository directory using WSL:
Don't forget to edit `WOLFSSL_VERSION_ARUINO_SUFFIX`!
```bash
# Change to the wolfSSL Arduino IDE directory
cd /mnt/c/workspace/wolfssl-$USER/IDE/ARDUINO
# remove current Arduino wolfSSL library
rm -rf /mnt/c/Users/$USER/Documents/Arduino/libraries/wolfssl
# Install wolfSSL as an Arduino library
./wolfssl-arduino.sh INSTALL
```
Publish wolfSSL from WSL to a `Arduino-wolfSSL-$USER` repository.
```bash
cd /mnt/c/workspace/wolfssl-$USER/IDE/ARDUINO
rm -rf /mnt/c/Users/$USER/Documents/Arduino/libraries/wolfSSL
rm -rf /mnt/c/workspace/wolfssl-$USER/IDE/ARDUINO/wolfSSL
./wolfssl-arduino.sh INSTALL /mnt/c/workspace/Arduino-wolfSSL-$USER/

View File

@ -11,4 +11,5 @@ EXTRA_DIST+= IDE/ARDUINO/sketches/wolfssl_client/README.md
EXTRA_DIST+= IDE/ARDUINO/sketches/wolfssl_client/wolfssl_client.ino
EXTRA_DIST+= IDE/ARDUINO/sketches/wolfssl_server/README.md
EXTRA_DIST+= IDE/ARDUINO/sketches/wolfssl_server/wolfssl_server.ino
EXTRA_DIST+= IDE/ARDUINO/wolfssl.h
EXTRA_DIST+= IDE/ARDUINO/wolfssl-arduino.sh

View File

@ -1,6 +1,6 @@
name=wolfSSL
name=wolfssl
version=${WOLFSSL_VERSION}${WOLFSSL_VERSION_ARUINO_SUFFIX}
author=wolfSSL inc
author=wolfSSL Inc.
maintainer=wolfSSL inc <support@wolfssl.com>
sentence=A lightweight SSL/TLS library written in ANSI C and targeted for embedded, RTOS, and resource-constrained environments.
paragraph=Manual: https://www.wolfssl.com/documentation/manuals/wolfssl/index.html.

View File

@ -20,157 +20,870 @@
*/
/*
This was original tested with Intel Galileo acting as the Client, with a
laptop acting as a server using the server example provided in examples/server.
Legacy Ardunio v1.86 was used to compile and program the Galileo
Tested with:
1) Intel Galileo acting as the Client, with a laptop acting as a server using
the server example provided in examples/server.
Legacy Arduino v1.86 was used to compile and program the Galileo
2) Espressif ESP32 WiFi
3) Arduino Due, Nano33 IoT, Nano RP-2040
*/
#define USE_CERT_BUFFERS_2048
/*
* Note to code editors: the Arduino client and server examples are edited in
* parallel for side-by-side comparison between examples.
*/
/* If you have a private include, define it here, otherwise edit WiFi params */
#define MY_PRIVATE_CONFIG "/workspace/my_private_config.h"
/* set REPEAT_CONNECTION to a non-zero value to continually run the example. */
#define REPEAT_CONNECTION 0
/* Edit this with your other TLS host server address to connect to: */
#define WOLFSSL_TLS_SERVER_HOST "192.168.1.34"
/* wolfssl TLS examples communicate on port 11111 */
#define WOLFSSL_PORT 11111
/* Choose a monitor serial baud rate: 9600, 14400, 19200, 57600, 74880, etc. */
#define SERIAL_BAUD 115200
/* We'll wait up to 2000 milliseconds to properly shut down connection */
#define SHUTDOWN_DELAY_MS 2000
/* Number of times to retry connection. */
#define RECONNECT_ATTEMPTS 20
/* Optional stress test. Define to consume memory until exhausted: */
#define MEMORY_STRESS_TEST
/* Choose client or server example, not both. */
#define WOLFSSL_CLIENT_EXAMPLE
/* #define WOLFSSL_SERVER_EXAMPLE */
#if defined(MY_PRIVATE_CONFIG)
/* the /workspace directory may contain a private config
* excluded from GitHub with items such as WiFi passwords */
#include MY_PRIVATE_CONFIG
const char* ssid PROGMEM = CONFIG_ESP_WIFI_SSID;
const char* password PROGMEM = CONFIG_ESP_WIFI_PASSWORD;
#else
/* when using WiFi capable boards: */
const char* ssid PROGMEM = "your_SSID";
const char* password PROGMEM = "your_PASSWORD";
#endif
#define BROADCAST_ADDRESS "255.255.255.255"
/* There's an optional 3rd party NTPClient library by Fabrice Weinberg.
* If it is installed, uncomment define USE_NTP_LIB here: */
/* #define USE_NTP_LIB */
#ifdef USE_NTP_LIB
#include <NTPClient.h>
#endif
#include <wolfssl.h>
/* Important: make sure settings.h appears before any other wolfSSL headers */
#include <wolfssl/wolfcrypt/settings.h>
/* Reminder: settings.h includes user_settings.h
* For ALL project wolfSSL settings, see:
* [your path]/Arduino\libraries\wolfSSL\src\user_settings.h */
#include <wolfssl/ssl.h>
#include <Ethernet.h>
#include <wolfssl/certs_test.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
/* Define DEBUG_WOLFSSL in user_settings.h for more verbose logging. */
#if defined(DEBUG_WOLFSSL)
#define PROGRESS_DOT F("")
#else
#define PROGRESS_DOT F(".")
#endif
const char host[] = "192.168.1.148"; /* server to connect to */
const int port = 11111; /* port on server to connect to */
/* Convert a macro to a string */
#define xstr(x) str(x)
#define str(x) #x
int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx);
int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx);
int reconnect = 10;
/* optional board-specific networking includes */
#if defined(ESP32)
#define USING_WIFI
#include <WiFi.h>
#include <WiFiUdp.h>
#ifdef USE_NTP_LIB
WiFiUDP ntpUDP;
#endif
/* Ensure the F() flash macro is defined */
#ifndef F
#define F
#endif
WiFiClient client;
EthernetClient client;
#elif defined(ESP8266)
#define USING_WIFI
#include <ESP8266WiFi.h>
WiFiClient client;
#elif defined(ARDUINO_SAM_DUE)
#include <SPI.h>
/* There's no WiFi/Ethernet on the Due. Requires Ethernet Shield.
/* Needs "Ethernet by Various" library to be installed. Tested with V2.0.2 */
#include <Ethernet.h>
EthernetClient client;
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
#define USING_WIFI
#include <SPI.h>
#include <WiFiNINA.h>
WiFiClient client;
#elif defined(ARDUINO_ARCH_RP2040)
#define USING_WIFI
#include <SPI.h>
#include <WiFiNINA.h>
WiFiClient client;
#elif defined(USING_WIFI)
#define USING_WIFI
#include <WiFi.h>
#include <WiFiUdp.h>
#ifdef USE_NTP_LIB
WiFiUDP ntpUDP;
#endif
WiFiClient client;
/* TODO
#elif defined(OTHER_BOARD)
*/
#else
#define USING_WIFI
WiFiClient client;
#endif
/* Only for syntax highlighters to show interesting options enabled: */
#if defined(HAVE_SNI) \
|| defined(HAVE_MAX_FRAGMENT) \
|| defined(HAVE_TRUSTED_CA) \
|| defined(HAVE_TRUNCATED_HMAC) \
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) \
|| defined(HAVE_SUPPORTED_CURVES) \
|| defined(HAVE_ALPN) \
|| defined(HAVE_SESSION_TICKET) \
|| defined(HAVE_SECURE_RENEGOTIATION) \
|| defined(HAVE_SERVER_RENEGOTIATION_INFO)
#endif
const char host[] PROGMEM = WOLFSSL_TLS_SERVER_HOST; /* server to connect to */
const int port PROGMEM = WOLFSSL_PORT; /* port on server to connect to */
const int serial_baud PROGMEM = SERIAL_BAUD; /* local serial port to monitor */
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
char* wc_error_message = (char*)malloc(80 + 1);
char errBuf[80];
void setup() {
WOLFSSL_METHOD* method;
/* Initialize Return Code */
int rc;
Serial.begin(9600);
/* Delay need to ensure connection to server */
delay(4000);
#if defined(MEMORY_STRESS_TEST)
#define MEMORY_STRESS_ITERATIONS 100
#define MEMORY_STRESS_BLOCK_SIZE 1024
#define MEMORY_STRESS_INITIAL (4*1024)
char* memory_stress[MEMORY_STRESS_ITERATIONS]; /* typically 1K per item */
int mem_ctr = 0;
#endif
method = wolfTLSv1_2_client_method();
if (method == NULL) {
Serial.println("unable to get method");
return;
static int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx);
static int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx);
static int reconnect = RECONNECT_ATTEMPTS;
static int lng_index PROGMEM = 0; /* 0 = English */
#if defined(__arm__)
#include <malloc.h>
extern char _end;
extern "C" char *sbrk(int i);
char *ramstart=(char *)0x20070000;
char *ramend=(char *)0x20088000;
#endif
/*****************************************************************************/
/* fail_wait - in case of unrecoverable error */
/*****************************************************************************/
int fail_wait(void) {
show_memory();
Serial.println(F("Failed. Halt."));
while (1) {
delay(1000);
}
ctx = wolfSSL_CTX_new(method);
if (ctx == NULL) {
Serial.println("unable to get ctx");
return;
}
/* initialize wolfSSL using callback functions */
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);
rc = wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_der_2048,\
sizeof_ca_cert_der_2048,\
WOLFSSL_FILETYPE_ASN1);
Serial.print("\n\n Return code of load_verify is:");
Serial.println(rc);
Serial.println("");
rc = wolfSSL_CTX_use_certificate_buffer(ctx, client_cert_der_2048,\
sizeof_client_cert_der_2048,\
WOLFSSL_FILETYPE_ASN1);
Serial.print("\n\n Return code of use_certificate_buffer is:");
Serial.println(rc);
Serial.println("");
rc = wolfSSL_CTX_use_PrivateKey_buffer(ctx, client_key_der_2048,\
sizeof_client_key_der_2048,\
WOLFSSL_FILETYPE_ASN1);
Serial.print("\n\n Return code of use_PrivateKey_buffer is:");
Serial.println(rc);
Serial.println("");
wolfSSL_SetIOSend(ctx, EthernetSend);
wolfSSL_SetIORecv(ctx, EthernetReceive);
return;
return 0;
}
int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx) {
/*****************************************************************************/
/* show_memory() to optionally view during debugging. */
/*****************************************************************************/
int show_memory(void)
{
#if defined(__arm__)
struct mallinfo mi = mallinfo();
char *heapend=sbrk(0);
register char * stack_ptr asm("sp");
#if defined(DEBUG_WOLFSSL_VERBOSE)
Serial.print(" arena=");
Serial.println(mi.arena);
Serial.print(" ordblks=");
Serial.println(mi.ordblks);
Serial.print(" uordblks=");
Serial.println(mi.uordblks);
Serial.print(" fordblks=");
Serial.println(mi.fordblks);
Serial.print(" keepcost=");
Serial.println(mi.keepcost);
#endif
#if defined(DEBUG_WOLFSSL) || defined(MEMORY_STRESS_TEST)
Serial.print("Estimated free memory: ");
Serial.print(stack_ptr - heapend + mi.fordblks);
Serial.println(F(" bytes"));
#endif
#if (0)
/* Experimental: not supported on all devices: */
Serial.print("RAM Start %lx\n", (unsigned long)ramstart);
Serial.print("Data/Bss end %lx\n", (unsigned long)&_end);
Serial.print("Heap End %lx\n", (unsigned long)heapend);
Serial.print("Stack Ptr %lx\n",(unsigned long)stack_ptr);
Serial.print("RAM End %lx\n", (unsigned long)ramend);
Serial.print("Heap RAM Used: ",mi.uordblks);
Serial.print("Program RAM Used ",&_end - ramstart);
Serial.print("Stack RAM Used ",ramend - stack_ptr);
Serial.print("Estimated Free RAM: %d\n\n",stack_ptr - heapend + mi.fordblks);
#endif
#else
Serial.println(F("show_memory() not implemented for this platform"));
#endif
return 0;
}
/*****************************************************************************/
/* EthernetSend() to send a message string. */
/*****************************************************************************/
int EthernetSend(WOLFSSL* ssl, char* message, int sz, void* ctx) {
int sent = 0;
sent = client.write((byte*)msg, sz);
(void)ssl;
(void)ctx;
sent = client.write((byte*)message, sz);
return sent;
}
/*****************************************************************************/
/* EthernetReceive() to receive a reply string. */
/*****************************************************************************/
int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx) {
int ret = 0;
(void)ssl;
(void)ctx;
while (client.available() > 0 && ret < sz) {
reply[ret++] = client.read();
}
return ret;
}
void loop() {
int err = 0;
int input = 0;
int total_input = 0;
char msg[32] = "hello wolfssl!";
int msgSz = (int)strlen(msg);
char errBuf[80];
char reply[80];
const char* cipherName;
if (reconnect) {
reconnect--;
if (client.connect(host, port)) {
Serial.print("Connected to ");
Serial.println(host);
ssl = wolfSSL_new(ctx);
if (ssl == NULL) {
Serial.println("Unable to allocate SSL object");
return;
/*****************************************************************************/
/* Arduino setup_hardware() */
/*****************************************************************************/
int setup_hardware(void) {
int ret = 0;
#if defined(ARDUINO_SAMD_NANO_33_IOT)
Serial.println(F("Detected known tested and working Arduino Nano 33 IoT"));
#elif defined(ARDUINO_ARCH_RP2040)
Serial.println(F("Detected known tested and working Arduino RP-2040"));
#elif defined(__arm__) && defined(ID_TRNG) && defined(TRNG)
/* need to manually turn on random number generator on Arduino Due, etc. */
pmc_enable_periph_clk(ID_TRNG);
trng_enable(TRNG);
Serial.println(F("Enabled ARM TRNG"));
#endif
show_memory();
randomSeed(analogRead(0));
return ret;
}
/*****************************************************************************/
/* Arduino setup_datetime() */
/* The device needs to have a valid date within the valid range of certs. */
/*****************************************************************************/
int setup_datetime(void) {
int ret = 0;
int ntp_tries = 20;
/* we need a date in the range of cert expiration */
#ifdef USE_NTP_LIB
#if defined(ESP32)
NTPClient timeClient(ntpUDP, "pool.ntp.org");
timeClient.begin();
timeClient.update();
delay(1000);
while (!timeClient.isTimeSet() && (ntp_tries > 0)) {
timeClient.forceUpdate();
Serial.println(F("Waiting for NTP update"));
delay(2000);
ntp_tries--;
}
if (ntp_tries <= 0) {
Serial.println(F("Warning: gave up waiting on NTP"));
}
Serial.println(timeClient.getFormattedTime());
Serial.println(timeClient.getEpochTime());
#endif
#endif
#if defined(ESP32)
/* see esp32-hal-time.c */
ntp_tries = 5;
/* Replace "pool.ntp.org" with your preferred NTP server */
configTime(0, 0, "pool.ntp.org");
/* Wait for time to be set */
while ((time(nullptr) <= 100000) && ntp_tries > 0) {
Serial.println(F("Waiting for time to be set..."));
delay(2000);
ntp_tries--;
}
#endif
return ret;
} /* setup_datetime */
/*****************************************************************************/
/* Arduino setup_network() */
/*****************************************************************************/
int setup_network(void) {
int ret = 0;
#if defined(USING_WIFI)
int status = WL_IDLE_STATUS;
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
/* don't continue if no network */
while (true) ;
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
/* The ESP8266 & ESP32 support both AP and STA. We'll use STA: */
#if defined(ESP8266) || defined(ESP32)
WiFi.mode(WIFI_STA);
#endif
Serial.print(F("Connecting to WiFi "));
Serial.print(ssid);
while (status != WL_CONNECTED) {
status = WiFi.begin(ssid, password);
delay(5000);
Serial.print(F("."));
}
Serial.println(F(" Connected!"));
#else
/* Newer Ethernet shields have a
* MAC address printed on a sticker on the shield */
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 42);
IPAddress myDns(192, 168, 1, 1);
Ethernet.init(10); /* Most Arduino shields */
/* Ethernet.init(5); * MKR ETH Shield */
/* Ethernet.init(0); * Teensy 2.0 */
/* Ethernet.init(20); * Teensy++ 2.0 */
/* Ethernet.init(15); * ESP8266 with Adafruit FeatherWing Ethernet */
/* Ethernet.init(33); * ESP32 with Adafruit FeatherWing Ethernet */
Serial.println(F("Initialize Ethernet with DHCP:"));
if (Ethernet.begin(mac) == 0) {
Serial.println(F("Failed to configure Ethernet using DHCP"));
/* Check for Ethernet hardware present */
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println(F("Ethernet shield was not found."));
while (true) {
delay(1); /* do nothing */
}
err = wolfSSL_connect(ssl);
if (err != WOLFSSL_SUCCESS) {
err = wolfSSL_get_error(ssl, 0);
wolfSSL_ERR_error_string(err, errBuf);
Serial.print("TLS Connect Error: ");
Serial.println(errBuf);
}
Serial.print("SSL version is ");
Serial.println(wolfSSL_get_version(ssl));
cipherName = wolfSSL_get_cipher(ssl);
Serial.print("SSL cipher suite is ");
Serial.println(cipherName);
if ((wolfSSL_write(ssl, msg, msgSz)) == msgSz) {
Serial.print("Server response: ");
/* wait for data */
while (!client.available()) {}
/* read data */
while (wolfSSL_pending(ssl)) {
input = wolfSSL_read(ssl, reply, sizeof(reply) - 1);
total_input += input;
if (input < 0) {
err = wolfSSL_get_error(ssl, 0);
wolfSSL_ERR_error_string(err, errBuf);
Serial.print("TLS Read Error: ");
Serial.println(errBuf);
break;
}
else if (input > 0) {
reply[input] = '\0';
Serial.print(reply);
}
else {
Serial.println();
}
}
}
else {
err = wolfSSL_get_error(ssl, 0);
wolfSSL_ERR_error_string(err, errBuf);
Serial.print("TLS Write Error: ");
Serial.println(errBuf);
}
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl);
client.stop();
Serial.println("Connection complete.");
reconnect = 0;
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println(F("Ethernet cable is not connected."));
}
/* try to configure using IP address instead of DHCP : */
Ethernet.begin(mac, ip, myDns);
}
else {
Serial.print(F(" DHCP assigned IP "));
Serial.println(Ethernet.localIP());
}
/* We'll assume the Ethernet connection is ready to go. */
#endif
Serial.println(F("********************************************************"));
Serial.print(F(" wolfSSL Example Client IP = "));
#if defined(USING_WIFI)
Serial.println(WiFi.localIP());
#else
Serial.println(Ethernet.localIP());
#endif
Serial.print(F(" Configured Server Host to connect to: "));
Serial.println(host);
Serial.println(F("********************************************************"));
Serial.println(F("Setup network complete."));
return ret;
}
/*****************************************************************************/
/* Arduino setup_wolfssl() */
/*****************************************************************************/
int setup_wolfssl(void) {
int ret = 0;
WOLFSSL_METHOD* method;
/* Show a revision of wolfssl user_settings.h file in use when available: */
#if defined(WOLFSSL_USER_SETTINGS_ID)
Serial.print(F("WOLFSSL_USER_SETTINGS_ID: "));
Serial.println(F(WOLFSSL_USER_SETTINGS_ID));
#else
Serial.println(F("No WOLFSSL_USER_SETTINGS_ID found."));
#endif
#if defined(NO_WOLFSSL_SERVER)
Serial.println(F("wolfSSL server code disabled to save space."));
#endif
#if defined(NO_WOLFSSL_CLIENT)
Serial.println(F("wolfSSL client code disabled to save space."));
#endif
#if defined(DEBUG_WOLFSSL)
wolfSSL_Debugging_ON();
Serial.println(F("wolfSSL Debugging is On!"));
#else
Serial.println(F("wolfSSL Debugging is Off! (enable with DEBUG_WOLFSSL)"));
#endif
/* See ssl.c for TLS cache settings. Larger cache = use more RAM. */
#if defined(NO_SESSION_CACHE)
Serial.println(F("wolfSSL TLS NO_SESSION_CACHE"));
#elif defined(MICRO_SESSION_CACHEx)
Serial.println(F("wolfSSL TLS MICRO_SESSION_CACHE"));
#elif defined(SMALL_SESSION_CACHE)
Serial.println(F("wolfSSL TLS SMALL_SESSION_CACHE"));
#elif defined(MEDIUM_SESSION_CACHE)
Serial.println(F("wolfSSL TLS MEDIUM_SESSION_CACHE"));
#elif defined(BIG_SESSION_CACHE)
Serial.println(F("wolfSSL TLS BIG_SESSION_CACHE"));
#elif defined(HUGE_SESSION_CACHE)
Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE"));
#elif defined(HUGE_SESSION_CACHE)
Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE"));
#else
Serial.println(F("WARNING: Unknown or no TLS session cache setting."));
/* See wolfssl/src/ssl.c for amount of memory used.
* It is best on embedded devices to choose a TLS session cache size. */
#endif
ret = wolfSSL_Init();
if (ret == WOLFSSL_SUCCESS) {
Serial.println("Successfully called wolfSSL_Init");
}
else {
Serial.println("ERROR: wolfSSL_Init failed");
}
/* See companion server example with wolfSSLv23_server_method here.
* method = wolfSSLv23_client_method()); SSL 3.0 - TLS 1.3.
* method = wolfTLSv1_2_client_method(); only TLS 1.2
* method = wolfTLSv1_3_client_method(); only TLS 1.3
*
* see Arduino\libraries\wolfssl\src\user_settings.h */
Serial.println("Here we go!");
method = wolfSSLv23_client_method();
if (method == NULL) {
Serial.println(F("unable to get wolfssl client method"));
fail_wait();
}
ctx = wolfSSL_CTX_new(method);
if (ctx == NULL) {
Serial.println(F("unable to get ctx"));
fail_wait();
}
return ret;
}
/*****************************************************************************/
/* Arduino setup_certificates() */
/*****************************************************************************/
int setup_certificates(void) {
int ret = 0;
Serial.println(F("Initializing certificates..."));
show_memory();
/* Use built-in validation, No verification callback function: */
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0);
/* Certificate */
Serial.println("Initializing certificates...");
ret = wolfSSL_CTX_use_certificate_buffer(ctx,
CTX_CLIENT_CERT,
CTX_CLIENT_CERT_SIZE,
CTX_CLIENT_CERT_TYPE);
if (ret == WOLFSSL_SUCCESS) {
Serial.print("Success: use certificate: ");
Serial.println(xstr(CTX_SERVER_CERT));
}
else {
Serial.println(F("Error: wolfSSL_CTX_use_certificate_buffer failed: "));
wc_ErrorString(ret, wc_error_message);
Serial.println(wc_error_message);
fail_wait();
}
/* Setup private client key */
ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx,
CTX_CLIENT_KEY,
CTX_CLIENT_KEY_SIZE,
CTX_CLIENT_KEY_TYPE);
if (ret == WOLFSSL_SUCCESS) {
Serial.print("Success: use private key buffer: ");
Serial.println(xstr(CTX_SERVER_KEY));
}
else {
Serial.println(F("Error: wolfSSL_CTX_use_PrivateKey_buffer failed: "));
wc_ErrorString(ret, wc_error_message);
Serial.println(wc_error_message);
fail_wait();
}
ret = wolfSSL_CTX_load_verify_buffer(ctx,
CTX_CA_CERT,
CTX_CA_CERT_SIZE,
CTX_CA_CERT_TYPE);
if (ret == WOLFSSL_SUCCESS) {
Serial.println(F("Success: load_verify CTX_CA_CERT"));
}
else {
Serial.println(F("Error: wolfSSL_CTX_load_verify_buffer failed: "));
wc_ErrorString(ret, wc_error_message);
Serial.println(wc_error_message);
fail_wait();
}
return ret;
} /* Arduino setup */
/*****************************************************************************/
/*****************************************************************************/
/* Arduino setup() */
/*****************************************************************************/
/*****************************************************************************/
void setup(void) {
Serial.begin(serial_baud);
while (!Serial) {
/* wait for serial port to connect. Needed for native USB port only */
}
Serial.println(F(""));
Serial.println(F(""));
Serial.println(F("wolfSSL TLS Client Example Startup."));
/* define DEBUG_WOLFSSL in wolfSSL user_settings.h for diagnostics */
#if defined(DEBUG_WOLFSSL)
wolfSSL_Debugging_ON();
#endif
/* Optionally pre-allocate a large block of memory for testing */
#if defined(MEMORY_STRESS_TEST)
Serial.println(F("WARNING: Memory Stress Test Active!"));
Serial.print(F("Allocating extra memory: "));
Serial.print(MEMORY_STRESS_INITIAL);
Serial.println(F(" bytes..."));
memory_stress[mem_ctr] = (char*)malloc(MEMORY_STRESS_INITIAL);
show_memory();
#endif
setup_hardware();
setup_datetime();
setup_network();
setup_wolfssl();
setup_certificates();
/* Initialize wolfSSL using callback functions. */
wolfSSL_SetIOSend(ctx, EthernetSend);
wolfSSL_SetIORecv(ctx, EthernetReceive);
Serial.println(F("Completed Arduino setup!"));
/* See companion wolfssl_server.ino code; server begins listening here
* https://github.com/wolfSSL/wolfssl/tree/master/IDE/ARDUINO/sketches/wolfssl_server
* Any other server will work. See also:
* https://github.com/wolfSSL/wolfssl/tree/master/examples/client
*/
/* See companion wolfssl_server.ino code */
return;
} /* Arduino setup */
/*****************************************************************************/
/* wolfSSL error_check() */
/*****************************************************************************/
int error_check(int this_ret, bool halt_on_error,
const __FlashStringHelper* message) {
int ret = 0;
if (this_ret == WOLFSSL_SUCCESS) {
Serial.print(F("Success: "));
Serial.println(message);
}
else {
Serial.print(F("ERROR: return = "));
Serial.print(this_ret);
Serial.print(F(": "));
Serial.println(message);
Serial.println(wc_GetErrorString(this_ret));
if (halt_on_error) {
fail_wait();
}
}
show_memory();
return ret;
} /* error_check */
/*****************************************************************************/
/* wolfSSL error_check_ssl */
/* Parameters: */
/* ssl is the current WOLFSSL object pointer */
/* halt_on_error set to true to suspend operations for critical error */
/* message is expected to be a memory-efficient F("") macro string */
/*****************************************************************************/
int error_check_ssl(WOLFSSL* ssl, int this_ret, bool halt_on_error,
const __FlashStringHelper* message) {
int err = 0;
if (ssl == NULL) {
Serial.println(F("ssl is Null; Unable to allocate SSL object?"));
#ifndef DEBUG_WOLFSSL
Serial.println(F("Define DEBUG_WOLFSSL in user_settings.h for more."));
#else
Serial.println(F("See wolfssl/wolfcrypt/error-crypt.h for codes."));
#endif
Serial.print(F("ERROR: "));
Serial.println(message);
show_memory();
if (halt_on_error) {
fail_wait();
}
}
else {
err = wolfSSL_get_error(ssl, this_ret);
if (err == WOLFSSL_SUCCESS) {
Serial.print(F("Success m: "));
Serial.println(message);
}
else {
Serial.println("Trying to reconnect...");
if (err < 0) {
wolfSSL_ERR_error_string(err, errBuf);
Serial.print(F("WOLFSSL Error: "));
Serial.print(err);
Serial.print(F("; "));
Serial.println(errBuf);
}
else {
Serial.println(F("Success: ssl object."));
}
}
}
return err;
}
/*****************************************************************************/
/*****************************************************************************/
/* Arduino loop() */
/*****************************************************************************/
/*****************************************************************************/
void loop() {
char reply[80];
char msg[32] = "hello wolfssl!";
const char* cipherName;
int retry_shutdown = SHUTDOWN_DELAY_MS; /* max try, once per millisecond */
int total_input = 0;
int msgSz = 0;
int input = 0;
int ret = 0;
int err = 0;
msgSz = (int)strlen(msg);
Serial.println(F(""));
Serial.println(F("Starting Arduino loop() ..."));
if (reconnect) {
reconnect--;
/* WiFi client returns true if connection succeeds, false if not. */
/* Wired client returns int (1,-1,-2,-3,-4) for connection status. */
Serial.print(F("Connecting to "));
Serial.print(host);
Serial.print(F(":"));
Serial.println(port);
/* can also use: IPAddress server(192,168,1,37); */
Serial.println(F("Here we go..."));
ret = client.connect(host, port);
Serial.println(F("Ok, checking..."));
if (ret > 0) {
Serial.println(F("Connected!"));
/* initialize wolfSSL */
ret = wolfSSL_Init();
error_check(ret, false, F("calling wolfSSL_Init") );
/* create secure connection object. see setup for ctx certs. */
Serial.println(F("Calling ssl = wolfSSL_new(ctx)"));
ssl = wolfSSL_new(ctx);
error_check_ssl(ssl, 0, true, F("Create WOLFSSL object from ctx"));
Serial.print(F("Connecting to wolfSSL TLS Secure Server..."));
do {
err = 0; /* reset error */
Serial.println(F("wolfSSL_connect ..."));
ret = wolfSSL_connect(ssl);
Serial.print("wolfSSL_connect return result =");
Serial.println(ret);
if ((ret != WOLFSSL_SUCCESS) && (ret != WC_PENDING_E)) {
Serial.println(F("Failed connection, checking error."));
err = error_check_ssl(ssl, ret, true,
F("Create WOLFSSL object from ctx"));
Serial.print("err =");
Serial.println(err);
}
else {
Serial.print(PROGRESS_DOT);
}
} while (err == WC_PENDING_E);
Serial.println();
Serial.println(F("Connected!"));
Serial.print(F("SSL version is "));
Serial.println(wolfSSL_get_version(ssl));
cipherName = wolfSSL_get_cipher(ssl);
Serial.print(F("SSL cipher suite is "));
Serial.println(cipherName);
/* see test.h
* TODO: test.h needs a little bit of Arduino work for these:
showPeerEx(ssl, lng_index);
showPeerPEM(ssl);
*/
Serial.print(F("Sending secure message to server: "));
Serial.println(msg);
ret = wolfSSL_write(ssl, msg, msgSz);
if (ret == msgSz) {
Serial.print(F("Waiting for Server response..."));
while (!client.available()) {
/* wait for data */
delay(1); /* 1 ms delay */
}
Serial.print(F("Reading response.."));
/* read data */
do {
ret = wolfSSL_read(ssl, reply, sizeof(reply) - 1);
if (ret < 0) {
error_check_ssl(ssl, ret, false,
F("during TLS Read"));
}
else {
Serial.print(PROGRESS_DOT);
}
} while (err == WC_PENDING_E);
Serial.println();
Serial.println();
Serial.println(reply); /* typically: I hear you fa shizzle! */
Serial.println();
} /* wolfSSL_write message size matched */
else {
error_check_ssl(ssl, ret, false,
F("during TLS Write"));
} /* any wolfSSL_write message size mismatch is an error */
Serial.print(F("Shutting down.."));
do {
delay(1);
Serial.print(PROGRESS_DOT);
retry_shutdown--;
ret = wolfSSL_shutdown(ssl);
} while ( (ret == WOLFSSL_SHUTDOWN_NOT_DONE)
&& (retry_shutdown > 0)
); /* There may be pending data, so wait until done. */
Serial.println();
if (retry_shutdown <= 0) {
/* if wolfSSL_free is called before properly shutting down the
* ssl object, undesired results may occur. */
Serial.println(F("Warning! Shutdown did not properly complete."));
}
wolfSSL_free(ssl);
client.stop();
Serial.println(F("Connection complete."));
if (REPEAT_CONNECTION) {
reconnect = RECONNECT_ATTEMPTS;
}
else {
reconnect = 0;
}
} /* client.connect(host, port) */
else {
Serial.println(F("Problem sending message. Trying to reconnect..."));
}
}
delay(1000);
}
if ((reconnect > 0) && (REPEAT_CONNECTION)) {
Serial.println(F("Arduino loop repeating..."));
Serial.println();
}
else {
printf("wow");
Serial.println(F("Done!"));
while(1) {
/* wait forever */
}
}
#if defined(MEMORY_STRESS_TEST)
if (mem_ctr < MEMORY_STRESS_ITERATIONS) {
/* reminder: mem_ctr == 0 is MEMORY_STRESS_INITIAL allocation */
mem_ctr++;
Serial.print(F("Memory stress increment: "));
Serial.print(mem_ctr);
Serial.print(F(". Allocating addition memory (bytes): "));
Serial.println(MEMORY_STRESS_BLOCK_SIZE);
memory_stress[mem_ctr] = (char*)malloc(MEMORY_STRESS_BLOCK_SIZE);
show_memory();
}
#endif
} /* Arduino loop repeats */

View File

@ -19,161 +19,815 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/*
Tested with:
#include <wolfssl.h>
#include <wolfssl/ssl.h>
#include <Ethernet.h>
1) Intel Galileo acting as the Client, with a laptop acting as a server using
the server example provided in examples/server.
Legacy Arduino v1.86 was used to compile and program the Galileo
#define USE_CERT_BUFFERS_256
#include <wolfssl/certs_test.h>
2) Espressif ESP32 WiFi
#ifdef NO_WOLFSSL_SERVER
#error Please undefine NO_WOLFSSL_SERVER for this example
3) Arduino Due, Nano33 IoT, Nano RP-2040
*/
/*
* Note to code editors: the Arduino client and server examples are edited in
* parallel for side-by-side comparison between examples.
*/
/* If you have a private include, define it here, otherwise edit WiFi params */
#define MY_PRIVATE_CONFIG "/workspace/my_private_config.h"
/* set REPEAT_CONNECTION to a non-zero value to continually run the example. */
#define REPEAT_CONNECTION 1
/* Edit this with your other TLS host server address to connect to: */
/* #define WOLFSSL_TLS_SERVER_HOST "192.168.1.34" */
/* wolfssl TLS examples communicate on port 11111 */
#define WOLFSSL_PORT 11111
/* Choose a monitor serial baud rate: 9600, 14400, 19200, 57600, 74880, etc. */
#define SERIAL_BAUD 115200
/* We'll wait up to 2000 milliseconds to properly shut down connection */
#define SHUTDOWN_DELAY_MS 2000
/* Number of times to retry connection. */
#define RECONNECT_ATTEMPTS 20
/* Optional stress test. Define to consume memory until exhausted: */
/* #define MEMORY_STRESS_TEST */
/* Choose client or server example, not both. */
/* #define WOLFSSL_CLIENT_EXAMPLE */
#define WOLFSSL_SERVER_EXAMPLE
#if defined(MY_PRIVATE_CONFIG)
/* the /workspace directory may contain a private config
* excluded from GitHub with items such as WiFi passwords */
#include MY_PRIVATE_CONFIG
const char* ssid PROGMEM = CONFIG_ESP_WIFI_SSID;
const char* password PROGMEM = CONFIG_ESP_WIFI_PASSWORD;
#else
/* when using WiFi capable boards: */
const char* ssid PROGMEM = "your_SSID";
const char* password PROGMEM = "your_PASSWORD";
#endif
const int port = 11111; /* port to listen on */
#define BROADCAST_ADDRESS "255.255.255.255"
int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx);
int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx);
/* There's an optional 3rd party NTPClient library by Fabrice Weinberg.
* If it is installed, uncomment define USE_NTP_LIB here: */
/* #define USE_NTP_LIB */
#ifdef USE_NTP_LIB
#include <NTPClient.h>
#endif
EthernetServer server(port);
EthernetClient client;
#include <wolfssl.h>
/* Important: make sure settings.h appears before any other wolfSSL headers */
#include <wolfssl/wolfcrypt/settings.h>
/* Reminder: settings.h includes user_settings.h
* For ALL project wolfSSL settings, see:
* [your path]/Arduino\libraries\wolfSSL\src\user_settings.h */
#include <wolfssl/ssl.h>
#include <wolfssl/certs_test.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
/* Define DEBUG_WOLFSSL in user_settings.h for more verbose logging. */
#if defined(DEBUG_WOLFSSL)
#define PROGRESS_DOT F("")
#else
#define PROGRESS_DOT F(".")
#endif
/* Convert a macro to a string */
#define xstr(x) str(x)
#define str(x) #x
/* optional board-specific networking includes */
#if defined(ESP32)
#define USING_WIFI
#include <WiFi.h>
#include <WiFiUdp.h>
#ifdef USE_NTP_LIB
WiFiUDP ntpUDP;
#endif
/* Ensure the F() flash macro is defined */
#ifndef F
#define F
#endif
WiFiClient client;
WiFiServer server(WOLFSSL_PORT);
#elif defined(ESP8266)
#define USING_WIFI
#include <ESP8266WiFi.h>
WiFiClient client;
WiFiServer server(WOLFSSL_PORT);
#elif defined(ARDUINO_SAM_DUE)
#include <SPI.h>
/* There's no WiFi/Ethernet on the Due. Requires Ethernet Shield.
/* Needs "Ethernet by Various" library to be installed. Tested with V2.0.2 */
#include <Ethernet.h>
EthernetClient client;
EthernetClient server(WOLFSSL_PORT);
#elif defined(ARDUINO_SAMD_NANO_33_IOT)
#define USING_WIFI
#include <SPI.h>
#include <WiFiNINA.h>
WiFiClient client;
WiFiServer server(WOLFSSL_PORT);
#elif defined(ARDUINO_ARCH_RP2040)
#define USING_WIFI
#include <SPI.h>
#include <WiFiNINA.h>
WiFiClient client;
WiFiServer server(WOLFSSL_PORT);
#elif defined(USING_WIFI)
#define USING_WIFI
#include <WiFi.h>
#include <WiFiUdp.h>
#ifdef USE_NTP_LIB
WiFiUDP ntpUDP;
#endif
WiFiClient client;
WiFiServer server(WOLFSSL_PORT);
/* TODO
#elif defined(OTHER_BOARD)
*/
#else
#define USING_WIFI
WiFiClient client;
WiFiServer server(WOLFSSL_PORT);
#endif
/* Only for syntax highlighters to show interesting options enabled: */
#if defined(HAVE_SNI) \
|| defined(HAVE_MAX_FRAGMENT) \
|| defined(HAVE_TRUSTED_CA) \
|| defined(HAVE_TRUNCATED_HMAC) \
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
|| defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) \
|| defined(HAVE_SUPPORTED_CURVES) \
|| defined(HAVE_ALPN) \
|| defined(HAVE_SESSION_TICKET) \
|| defined(HAVE_SECURE_RENEGOTIATION) \
|| defined(HAVE_SERVER_RENEGOTIATION_INFO)
#endif
/* we expect our IP address from DHCP */
const int serial_baud = SERIAL_BAUD; /* local serial port to monitor */
WOLFSSL_CTX* ctx = NULL;
WOLFSSL* ssl = NULL;
char* wc_error_message = (char*)malloc(80 + 1);
char errBuf[80];
void setup() {
int err;
WOLFSSL_METHOD* method;
#if defined(MEMORY_STRESS_TEST)
#define MEMORY_STRESS_ITERATIONS 100
#define MEMORY_STRESS_BLOCK_SIZE 1024
#define MEMORY_STRESS_INITIAL (4*1024)
char* memory_stress[MEMORY_STRESS_ITERATIONS]; /* typically 1K per item */
int mem_ctr = 0;
#endif
Serial.begin(9600);
static int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx);
static int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx);
static int reconnect = RECONNECT_ATTEMPTS;
static int lng_index PROGMEM = 0; /* 0 = English */
method = wolfTLSv1_2_server_method();
if (method == NULL) {
Serial.println("unable to get method");
return;
}
ctx = wolfSSL_CTX_new(method);
if (ctx == NULL) {
Serial.println("unable to get ctx");
return;
}
#if defined(__arm__)
#include <malloc.h>
extern char _end;
extern "C" char *sbrk(int i);
char *ramstart=(char *)0x20070000;
char *ramend=(char *)0x20088000;
#endif
/* initialize wolfSSL using callback functions */
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
wolfSSL_SetIOSend(ctx, EthernetSend);
wolfSSL_SetIORecv(ctx, EthernetReceive);
/*****************************************************************************/
/* fail_wait - in case of unrecoverable error */
/*****************************************************************************/
int fail_wait(void) {
show_memory();
/* setup the private key and certificate */
err = wolfSSL_CTX_use_PrivateKey_buffer(ctx, ecc_key_der_256,
sizeof_ecc_key_der_256, WOLFSSL_FILETYPE_ASN1);
if (err != WOLFSSL_SUCCESS) {
Serial.println("error setting key");
return;
}
err = wolfSSL_CTX_use_certificate_buffer(ctx, serv_ecc_der_256,
sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1);
if (err != WOLFSSL_SUCCESS) {
Serial.println("error setting certificate");
return;
}
/* Start the server */
server.begin();
return;
Serial.println(F("Failed. Halt."));
while (1) {
delay(1000);
}
return 0;
}
int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx) {
int sent = 0;
/*****************************************************************************/
/* show_memory() to optionally view during debugging. */
/*****************************************************************************/
int show_memory(void)
{
#if defined(__arm__)
struct mallinfo mi = mallinfo();
sent = client.write((byte*)msg, sz);
char *heapend=sbrk(0);
register char * stack_ptr asm("sp");
#if defined(DEBUG_WOLFSSL_VERBOSE)
Serial.print(" arena=");
Serial.println(mi.arena);
Serial.print(" ordblks=");
Serial.println(mi.ordblks);
Serial.print(" uordblks=");
Serial.println(mi.uordblks);
Serial.print(" fordblks=");
Serial.println(mi.fordblks);
Serial.print(" keepcost=");
Serial.println(mi.keepcost);
#endif
return sent;
#if defined(DEBUG_WOLFSSL) || defined(MEMORY_STRESS_TEST)
Serial.print("Estimated free memory: ");
Serial.print(stack_ptr - heapend + mi.fordblks);
Serial.println(F(" bytes"));
#endif
#if (0)
/* Experimental: not supported on all devices: */
Serial.print("RAM Start %lx\n", (unsigned long)ramstart);
Serial.print("Data/Bss end %lx\n", (unsigned long)&_end);
Serial.print("Heap End %lx\n", (unsigned long)heapend);
Serial.print("Stack Ptr %lx\n",(unsigned long)stack_ptr);
Serial.print("RAM End %lx\n", (unsigned long)ramend);
Serial.print("Heap RAM Used: ",mi.uordblks);
Serial.print("Program RAM Used ",&_end - ramstart);
Serial.print("Stack RAM Used ",ramend - stack_ptr);
Serial.print("Estimated Free RAM: %d\n\n",stack_ptr - heapend + mi.fordblks);
#endif
#else
Serial.println(F("show_memory() not implemented for this platform"));
#endif
return 0;
}
/*****************************************************************************/
/* EthernetSend() to send a message string. */
/*****************************************************************************/
int EthernetSend(WOLFSSL* ssl, char* message, int sz, void* ctx) {
int sent = 0;
(void)ssl;
(void)ctx;
sent = client.write((byte*)message, sz);
return sent;
}
/*****************************************************************************/
/* EthernetReceive() to receive a reply string. */
/*****************************************************************************/
int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx) {
int ret = 0;
int ret = 0;
(void)ssl;
(void)ctx;
while (client.available() > 0 && ret < sz) {
reply[ret++] = client.read();
}
return ret;
while (client.available() > 0 && ret < sz) {
reply[ret++] = client.read();
}
return ret;
}
void loop() {
int err = 0;
int input = 0;
char errBuf[80];
char reply[80];
int replySz = 0;
const char* cipherName;
/*****************************************************************************/
/* Arduino setup_hardware() */
/*****************************************************************************/
int setup_hardware(void) {
int ret = 0;
/* Listen for incoming client requests. */
client = server.available();
if (!client) {
#if defined(ARDUINO_SAMD_NANO_33_IOT)
Serial.println(F("Detected known tested and working Arduino Nano 33 IoT"));
#elif defined(ARDUINO_ARCH_RP2040)
Serial.println(F("Detected known tested and working Arduino RP-2040"));
#elif defined(__arm__) && defined(ID_TRNG) && defined(TRNG)
/* need to manually turn on random number generator on Arduino Due, etc. */
pmc_enable_periph_clk(ID_TRNG);
trng_enable(TRNG);
Serial.println(F("Enabled ARM TRNG"));
#endif
show_memory();
randomSeed(analogRead(0));
return ret;
}
/*****************************************************************************/
/* Arduino setup_datetime() */
/* The device needs to have a valid date within the valid range of certs. */
/*****************************************************************************/
int setup_datetime(void) {
int ret = 0;
int ntp_tries = 20;
/* we need a date in the range of cert expiration */
#ifdef USE_NTP_LIB
#if defined(ESP32)
NTPClient timeClient(ntpUDP, "pool.ntp.org");
timeClient.begin();
timeClient.update();
delay(1000);
while (!timeClient.isTimeSet() && (ntp_tries > 0)) {
timeClient.forceUpdate();
Serial.println(F("Waiting for NTP update"));
delay(2000);
ntp_tries--;
}
if (ntp_tries <= 0) {
Serial.println(F("Warning: gave up waiting on NTP"));
}
Serial.println(timeClient.getFormattedTime());
Serial.println(timeClient.getEpochTime());
#endif
#endif
#if defined(ESP32)
/* see esp32-hal-time.c */
ntp_tries = 5;
/* Replace "pool.ntp.org" with your preferred NTP server */
configTime(0, 0, "pool.ntp.org");
/* Wait for time to be set */
while ((time(nullptr) <= 100000) && ntp_tries > 0) {
Serial.println(F("Waiting for time to be set..."));
delay(2000);
ntp_tries--;
}
#endif
return ret;
} /* setup_datetime */
/*****************************************************************************/
/* Arduino setup_network() */
/*****************************************************************************/
int setup_network(void) {
int ret = 0;
#if defined(USING_WIFI)
int status = WL_IDLE_STATUS;
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
/* don't continue if no network */
while (true) ;
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
/* The ESP8266 & ESP32 support both AP and STA. We'll use STA: */
#if defined(ESP8266) || defined(ESP32)
WiFi.mode(WIFI_STA);
#endif
Serial.print(F("Connecting to WiFi "));
Serial.print(ssid);
while (status != WL_CONNECTED) {
status = WiFi.begin(ssid, password);
delay(5000);
Serial.print(F("."));
}
Serial.println(F(" Connected!"));
#else
/* Newer Ethernet shields have a
* MAC address printed on a sticker on the shield */
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 1, 42);
IPAddress myDns(192, 168, 1, 1);
Ethernet.init(10); /* Most Arduino shields */
/* Ethernet.init(5); * MKR ETH Shield */
/* Ethernet.init(0); * Teensy 2.0 */
/* Ethernet.init(20); * Teensy++ 2.0 */
/* Ethernet.init(15); * ESP8266 with Adafruit FeatherWing Ethernet */
/* Ethernet.init(33); * ESP32 with Adafruit FeatherWing Ethernet */
Serial.println(F("Initialize Ethernet with DHCP:"));
if (Ethernet.begin(mac) == 0) {
Serial.println(F("Failed to configure Ethernet using DHCP"));
/* Check for Ethernet hardware present */
if (Ethernet.hardwareStatus() == EthernetNoHardware) {
Serial.println(F("Ethernet shield was not found."));
while (true) {
delay(1); /* do nothing */
}
}
if (Ethernet.linkStatus() == LinkOFF) {
Serial.println(F("Ethernet cable is not connected."));
}
/* try to configure using IP address instead of DHCP : */
Ethernet.begin(mac, ip, myDns);
}
else {
Serial.print(F(" DHCP assigned IP "));
Serial.println(Ethernet.localIP());
}
/* We'll assume the Ethernet connection is ready to go. */
#endif
Serial.println(F("********************************************************"));
Serial.print(F(" wolfSSL Example Server IP = "));
#if defined(USING_WIFI)
Serial.println(WiFi.localIP());
#else
Serial.println(Ethernet.localIP());
#endif
/* In server mode, there's no host definition. */
/* See companion example: wolfssl_client.ino */
Serial.println(F("********************************************************"));
Serial.println(F("Setup network complete."));
return ret;
}
/*****************************************************************************/
/* Arduino setup_wolfssl() */
/*****************************************************************************/
int setup_wolfssl(void) {
int ret = 0;
WOLFSSL_METHOD* method;
/* Show a revision of wolfssl user_settings.h file in use when available: */
#if defined(WOLFSSL_USER_SETTINGS_ID)
Serial.print(F("WOLFSSL_USER_SETTINGS_ID: "));
Serial.println(F(WOLFSSL_USER_SETTINGS_ID));
#else
Serial.println(F("No WOLFSSL_USER_SETTINGS_ID found."));
#endif
#if defined(NO_WOLFSSL_SERVER)
Serial.println(F("wolfSSL server code disabled to save space."));
#endif
#if defined(NO_WOLFSSL_CLIENT)
Serial.println(F("wolfSSL client code disabled to save space."));
#endif
#if defined(DEBUG_WOLFSSL)
wolfSSL_Debugging_ON();
Serial.println(F("wolfSSL Debugging is On!"));
#else
Serial.println(F("wolfSSL Debugging is Off! (enable with DEBUG_WOLFSSL)"));
#endif
/* See ssl.c for TLS cache settings. Larger cache = use more RAM. */
#if defined(NO_SESSION_CACHE)
Serial.println(F("wolfSSL TLS NO_SESSION_CACHE"));
#elif defined(MICRO_SESSION_CACHEx)
Serial.println(F("wolfSSL TLS MICRO_SESSION_CACHE"));
#elif defined(SMALL_SESSION_CACHE)
Serial.println(F("wolfSSL TLS SMALL_SESSION_CACHE"));
#elif defined(MEDIUM_SESSION_CACHE)
Serial.println(F("wolfSSL TLS MEDIUM_SESSION_CACHE"));
#elif defined(BIG_SESSION_CACHE)
Serial.println(F("wolfSSL TLS BIG_SESSION_CACHE"));
#elif defined(HUGE_SESSION_CACHE)
Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE"));
#elif defined(HUGE_SESSION_CACHE)
Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE"));
#else
Serial.println(F("WARNING: Unknown or no TLS session cache setting."));
/* See wolfssl/src/ssl.c for amount of memory used.
* It is best on embedded devices to choose a TLS session cache size. */
#endif
ret = wolfSSL_Init();
if (ret == WOLFSSL_SUCCESS) {
Serial.println("Successfully called wolfSSL_Init");
}
else {
Serial.println("ERROR: wolfSSL_Init failed");
}
/* See companion server example with wolfSSLv23_server_method here.
* method = wolfSSLv23_client_method()); SSL 3.0 - TLS 1.3.
* method = wolfTLSv1_2_client_method(); only TLS 1.2
* method = wolfTLSv1_3_client_method(); only TLS 1.3
*
* see Arduino\libraries\wolfssl\src\user_settings.h */
Serial.println("Here we go!");
method = wolfSSLv23_server_method();
if (method == NULL) {
Serial.println(F("unable to get wolfssl server method"));
fail_wait();
}
ctx = wolfSSL_CTX_new(method);
if (ctx == NULL) {
Serial.println(F("unable to get ctx"));
fail_wait();
}
return ret;
}
/*****************************************************************************/
/* Arduino setup_certificates() */
/*****************************************************************************/
int setup_certificates(void) {
int ret = 0;
Serial.println(F("Initializing certificates..."));
show_memory();
/* Use built-in validation, No verification callback function: */
wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0);
/* Certificate */
Serial.println("Initializing certificates...");
ret = wolfSSL_CTX_use_certificate_buffer(ctx,
CTX_SERVER_CERT,
CTX_SERVER_CERT_SIZE,
CTX_CA_CERT_TYPE);
if (ret == WOLFSSL_SUCCESS) {
Serial.print("Success: use certificate: ");
Serial.println(xstr(CTX_SERVER_CERT));
}
else {
Serial.print("Error: wolfSSL_CTX_use_certificate_buffer failed: ");
wc_ErrorString(ret, wc_error_message);
Serial.println(wc_error_message);
fail_wait();
}
/* Setup private server key */
ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx,
CTX_SERVER_KEY,
CTX_SERVER_KEY_SIZE,
CTX_SERVER_KEY_TYPE);
if (ret == WOLFSSL_SUCCESS) {
Serial.print("Success: use private key buffer: ");
Serial.println(xstr(CTX_SERVER_KEY));
}
else {
Serial.print("Error: wolfSSL_CTX_use_PrivateKey_buffer failed: ");
wc_ErrorString(ret, wc_error_message);
Serial.println(wc_error_message);
fail_wait();
}
return ret;
} /* Arduino setup */
/*****************************************************************************/
/*****************************************************************************/
/* Arduino setup() */
/*****************************************************************************/
/*****************************************************************************/
void setup(void) {
Serial.begin(SERIAL_BAUD);
while (!Serial) {
/* wait for serial port to connect. Needed for native USB port only */
}
Serial.println(F(""));
Serial.println(F(""));
Serial.println(F("wolfSSL TLS Server Example Startup."));
/* define DEBUG_WOLFSSL in wolfSSL user_settings.h for diagnostics */
#if defined(DEBUG_WOLFSSL)
wolfSSL_Debugging_ON();
#endif
/* Optionally pre-allocate a large block of memory for testing */
#if defined(MEMORY_STRESS_TEST)
Serial.println(F("WARNING: Memory Stress Test Active!"));
Serial.print(F("Allocating extra memory: "));
Serial.print(MEMORY_STRESS_INITIAL);
Serial.println(F(" bytes..."));
memory_stress[mem_ctr] = (char*)malloc(MEMORY_STRESS_INITIAL);
show_memory();
#endif
setup_hardware();
setup_datetime();
setup_network();
setup_wolfssl();
setup_certificates();
/* Initialize wolfSSL using callback functions. */
wolfSSL_SetIOSend(ctx, EthernetSend);
wolfSSL_SetIORecv(ctx, EthernetReceive);
#if defined THIS_USER_SETTINGS_VERSION
Serial.print(F("This user_settings.h version:"))
Serial.println(THIS_USER_SETTINGS_VERSION)
#endif
/* Start the server
* See https://www.arduino.cc/reference/en/libraries/ethernet/server.begin/
*/
Serial.println(F("Completed Arduino setup()"));
server.begin();
Serial.println("Begin Server... (waiting for remote client to connect)");
/* See companion wolfssl_client.ino code */
return;
}
} /* Arduino setup */
if (client.connected()) {
/*****************************************************************************/
/* wolfSSL error_check() */
/*****************************************************************************/
int error_check(int this_ret, bool halt_on_error,
const __FlashStringHelper* message) {
int ret = 0;
if (this_ret == WOLFSSL_SUCCESS) {
Serial.print(F("Success: "));
Serial.println(message);
}
else {
Serial.print(F("ERROR: return = "));
Serial.print(this_ret);
Serial.print(F(": "));
Serial.println(message);
Serial.println(wc_GetErrorString(this_ret));
if (halt_on_error) {
fail_wait();
}
}
show_memory();
Serial.println("Client connected");
return ret;
} /* error_check */
/*****************************************************************************/
/* wolfSSL error_check_ssl */
/* Parameters: */
/* ssl is the current WOLFSSL object pointer */
/* halt_on_error set to true to suspend operations for critical error */
/* message is expected to be a memory-efficient F("") macro string */
/*****************************************************************************/
int error_check_ssl(WOLFSSL* ssl, int this_ret, bool halt_on_error,
const __FlashStringHelper* message) {
int err = 0;
ssl = wolfSSL_new(ctx);
if (ssl == NULL) {
Serial.println("Unable to allocate SSL object");
return;
Serial.println(F("ssl is Null; Unable to allocate SSL object?"));
#ifndef DEBUG_WOLFSSL
Serial.println(F("Define DEBUG_WOLFSSL in user_settings.h for more."));
#else
Serial.println(F("See wolfssl/wolfcrypt/error-crypt.h for codes."));
#endif
Serial.print(F("ERROR: "));
Serial.println(message);
show_memory();
if (halt_on_error) {
fail_wait();
}
}
else {
err = wolfSSL_get_error(ssl, this_ret);
if (err == WOLFSSL_SUCCESS) {
Serial.print(F("Success m: "));
Serial.println(message);
}
else {
if (err < 0) {
wolfSSL_ERR_error_string(err, errBuf);
Serial.print(F("WOLFSSL Error: "));
Serial.print(err);
Serial.print(F("; "));
Serial.println(errBuf);
}
else {
Serial.println(F("Success: ssl object."));
}
}
}
err = wolfSSL_accept(ssl);
if (err != WOLFSSL_SUCCESS) {
err = wolfSSL_get_error(ssl, 0);
wolfSSL_ERR_error_string(err, errBuf);
Serial.print("TLS Accept Error: ");
Serial.println(errBuf);
}
Serial.print("SSL version is ");
Serial.println(wolfSSL_get_version(ssl));
cipherName = wolfSSL_get_cipher(ssl);
Serial.print("SSL cipher suite is ");
Serial.println(cipherName);
Serial.print("Server Read: ");
/* wait for data */
while (!client.available()) {}
/* read data */
while (wolfSSL_pending(ssl)) {
input = wolfSSL_read(ssl, reply, sizeof(reply) - 1);
if (input < 0) {
err = wolfSSL_get_error(ssl, 0);
wolfSSL_ERR_error_string(err, errBuf);
Serial.print("TLS Read Error: ");
Serial.println(errBuf);
break;
} else if (input > 0) {
replySz = input;
reply[input] = '\0';
Serial.print(reply);
} else {
Serial.println();
}
}
/* echo data */
if ((wolfSSL_write(ssl, reply, replySz)) != replySz) {
err = wolfSSL_get_error(ssl, 0);
wolfSSL_ERR_error_string(err, errBuf);
Serial.print("TLS Write Error: ");
Serial.println(errBuf);
}
wolfSSL_shutdown(ssl);
wolfSSL_free(ssl);
}
client.stop();
Serial.println("Connection complete");
return err;
}
/*****************************************************************************/
/*****************************************************************************/
/* Arduino loop() */
/*****************************************************************************/
/*****************************************************************************/
void loop() {
char errBuf[80] = "(no error";
char reply[80] = "(no reply)";
const char msg[] = "I hear you fa shizzle!";
const char* cipherName;
int input = 0;
int replySz = 0;
int retry_shutdown = SHUTDOWN_DELAY_MS; /* max try, once per millisecond */
int ret = 0;
IPAddress broadcast_address(255, 255, 255, 255);
/* Listen for incoming client requests. */
client = server.available();
if (client) {
Serial.println("Have Client");
while (!client.connected()) {
/* wait for the client to actually connect */
delay(10);
}
Serial.print("Client connected from remote IP: ");
Serial.println(client.remoteIP());
ssl = wolfSSL_new(ctx);
if (ssl == NULL) {
Serial.println("Unable to allocate SSL object");
fail_wait();
}
ret = wolfSSL_accept(ssl);
if (ret != WOLFSSL_SUCCESS) {
ret = wolfSSL_get_error(ssl, 0);
wolfSSL_ERR_error_string(ret, errBuf);
Serial.print("TLS Accept Error: ");
Serial.println(errBuf);
}
cipherName = wolfSSL_get_cipher(ssl);
Serial.print("SSL cipher suite is ");
Serial.println(cipherName);
Serial.print("Server Read: ");
while (!client.available()) {
/* wait for data */
}
/* read data */
while (wolfSSL_pending(ssl)) {
input = wolfSSL_read(ssl, reply, sizeof(reply) - 1);
if (input < 0) {
ret = wolfSSL_get_error(ssl, 0);
wolfSSL_ERR_error_string(ret, errBuf);
Serial.print("TLS Read Error: ");
Serial.println(errBuf);
break;
}
else if (input > 0) {
replySz = input;
reply[input] = '\0';
Serial.print(reply);
}
else {
Serial.println("<end of reply, input == 0>");
}
}
/* Write our message into reply buffer to send */
memset(reply, 0, sizeof(reply));
memcpy(reply, msg, sizeof(msg));
replySz = strnlen(reply, sizeof(reply));
Serial.println("Sending reply...");
if ((wolfSSL_write(ssl, reply, replySz)) != replySz) {
ret = wolfSSL_get_error(ssl, 0);
wolfSSL_ERR_error_string(ret, errBuf);
Serial.print("TLS Write Error: ");
Serial.println(errBuf);
}
else {
Serial.println("Reply sent!");
}
Serial.println("Shutdown!");
do {
delay(1);
retry_shutdown--;
ret = wolfSSL_shutdown(ssl);
} while ((ret == WOLFSSL_SHUTDOWN_NOT_DONE) && (retry_shutdown > 0));
if (retry_shutdown <= 0) {
/* if wolfSSL_free is called before properly shutting down the
* ssl object, undesired results may occur. */
Serial.println("Warning! Shutdown did not properly complete.");
}
wolfSSL_free(ssl);
Serial.println("Connection complete.");
if (REPEAT_CONNECTION) {
Serial.println();
Serial.println("Waiting for next connection.");
}
else {
client.stop();
Serial.println("Done!");
while (1) {
/* wait forever if not repeating */
delay(100);
}
}
}
else {
/* Serial.println("Client not connected. Trying again..."); */
}
delay(100);
} /* Arduino loop repeats */

View File

@ -4,19 +4,32 @@
# an Arduino project
# run as bash ./wolfssl-arduino.sh [INSTALL] [path]
#
# ./wolfssl-arduino.sh
# The default is to install to a local wolfSSL directory (`ROOT_DIR`).
# If successfully built, and the INSTALL option is used, tis directory
# is then moved to the target.
#
# ./wolfssl-arduino.sh INSTALL
# Creates a local wolfSSL directory and then moves it to the ARDUINO_ROOT
#
# ./wolfssl-arduino.sh INSTALL /mnt/c/workspace/Arduino-wolfSSL-$USER
# Updates the Arduino-wolfSSL fork for $USER to refresh versions.
#
# To ensure a pristine build, the directory must not exist.
#
# Reminder there's typically no $USER for GitHub actions, but:
# ROOT_DIR="/mnt/c/Users/$USER/Documents/Arduino/libraries"
#
ROOT_DIR="/wolfSSL"
# The company name is "wolfSSL Inc."; Theres a space, no comma, and a period after "Inc."
# The Arduino library name is "wolfssl" (all lower case)
# The Arduino library directory name is "wolfssl" (all lower case)
# The Arduino library include file is "wolfssl.h" (all lower case)
# The Published wolfSSL Arduino Registry is at https://github.com/wolfSSL/Arduino-wolfSSL.git
# See https://downloads.arduino.cc/libraries/logs/github.com/wolfSSL/Arduino-wolfSSL/
ROOT_DIR="/wolfssl"
# The Arduino Version will initially have a suffix appended during fine tuning stage.
WOLFSSL_VERSION_ARUINO_SUFFIX="01"
WOLFSSL_VERSION_ARUINO_SUFFIX="-Arduino.2"
# For verbose copy, set CP_CMD="-v", otherwise clear it: CP_CMD="cp"
# Do not set to empty string, as copy will fail with this: CP_CMD=""
@ -32,7 +45,7 @@ MY_SHELLCHECK="shellcheck"
# Unlike a local Arduino library that requires a clean directory,
# we'll allow extra files, overwrites, etc.
#
# Note in all cases, the local IDE/ARDUINO/wolfSSL must be empty.
# Note in all cases, the local IDE/ARDUINO/wolfssl must be empty.
THIS_INSTALL_IS_GITHUB="false"
# Check if the executable is available in the PATH
@ -97,6 +110,7 @@ fi
ROOT_SRC_DIR="${ROOT_DIR}/src"
EXAMPLES_DIR="${ROOT_DIR}/examples"
WOLFSSL_SRC="${ROOT_SRC_DIR}/src"
WOLFSSL_HEADERS="${ROOT_SRC_DIR}/wolfssl"
WOLFCRYPT_ROOT="${ROOT_SRC_DIR}/wolfcrypt"
@ -121,100 +135,111 @@ if [ "$WOLFSSL_VERSION" = "" ]; then
exit 1
else
echo "Found wolfSSL version $WOLFSSL_VERSION"
echo "# WOLFSSL_VERSION_ARUINO_SUFFIX $WOLFSSL_VERSION_ARUINO_SUFFIX"
fi
echo ""
THIS_DIR=${PWD##*/}
if [ "$THIS_DIR" = "ARDUINO" ]; then
# mkdir ./wolfSSL
# mkdir ./wolfssl
if [ -d ".${ROOT_DIR}" ]; then
echo "ERROR: $(realpath ".${ROOT_DIR}") is not empty"
exit 1
else
echo "Step 01: mkdir .${ROOT_DIR}"
mkdir .${ROOT_DIR}
mkdir ."${ROOT_DIR}"
fi
# mkdir ./wolfSSL/src
# mkdir ./wolfssl/src
if [ ! -d ".${ROOT_SRC_DIR}" ]; then
echo "Step 02: mkdir .${ROOT_SRC_DIR}"
mkdir .${ROOT_SRC_DIR}
mkdir ."${ROOT_SRC_DIR}"
fi
# mkdir ./wolfSSL/src/wolfssl
# mkdir ./wolfssl/src/wolfssl
if [ ! -d ".${WOLFSSL_HEADERS}" ]; then
echo "Step 03: mkdir .${WOLFSSL_HEADERS}"
mkdir .${WOLFSSL_HEADERS}
mkdir ."${WOLFSSL_HEADERS}"
fi
# cp ../../wolfssl/*.h ./wolfSSL/src/wolfssl
echo "Step 04: cp ${WOLFSSL_HEADERS_TOP}/*.h .${WOLFSSL_HEADERS}"
$CP_CMD ${WOLFSSL_HEADERS_TOP}/*.h .${WOLFSSL_HEADERS}
# cp ../../wolfssl/*.h ./wolfssl/src/wolfssl
echo "Step 04: cp ${WOLFSSL_HEADERS_TOP}/*.h .${WOLFSSL_HEADERS}"
$CP_CMD "${WOLFSSL_HEADERS_TOP}"/*.h ."${WOLFSSL_HEADERS}"
if [ ! -d ".${WOLFCRYPT_HEADERS}" ]; then
# mkdir ./wolfSSL/src/wolfssl/wolfcrypt
# mkdir ./wolfssl/src/wolfssl/wolfcrypt
echo "Step 05: mkdir .${WOLFCRYPT_HEADERS}"
mkdir .${WOLFCRYPT_HEADERS}
mkdir .${WOLFCRYPT_HEADERS}/port
mkdir .${WOLFCRYPT_HEADERS}/port/atmel
mkdir .${WOLFCRYPT_HEADERS}/port/Espressif
mkdir ."${WOLFCRYPT_HEADERS}"
mkdir ."${WOLFCRYPT_HEADERS}/port"
mkdir ."${WOLFCRYPT_HEADERS}/port/atmel"
mkdir ."${WOLFCRYPT_HEADERS}/port/Espressif"
fi
# cp ../../wolfssl/wolfcrypt/*.h ./wolfSSL/src/wolfssl/wolfcrypt
echo "Step 06: cp ${WOLFCRYPT_HEADERS_TOP}/*.h .${WOLFCRYPT_HEADERS}"
$CP_CMD ${WOLFCRYPT_HEADERS_TOP}/*.h .${WOLFCRYPT_HEADERS} || exit 1
$CP_CMD ${WOLFCRYPT_HEADERS_TOP}/port/atmel/*.h .${WOLFCRYPT_HEADERS}/port/atmel || exit 1
$CP_CMD ${WOLFCRYPT_HEADERS_TOP}/port/Espressif/*.h .${WOLFCRYPT_HEADERS}/port/Espressif || exit 1
# cp ../../wolfssl/wolfcrypt/*.h ./wolfssl/src/wolfssl/wolfcrypt
echo "Step 06: cp ${WOLFCRYPT_HEADERS_TOP}/*.h .${WOLFCRYPT_HEADERS}"
$CP_CMD "${WOLFCRYPT_HEADERS_TOP}"/*.h ."${WOLFCRYPT_HEADERS}" || exit 1
$CP_CMD "${WOLFCRYPT_HEADERS_TOP}"/port/atmel/*.h ."${WOLFCRYPT_HEADERS}/port/atmel" || exit 1
$CP_CMD "${WOLFCRYPT_HEADERS_TOP}"/port/Espressif/*.h ."${WOLFCRYPT_HEADERS}/port/Espressif" || exit 1
# Add in source files to wolfcrypt/src
if [ ! -d ".${WOLFCRYPT_ROOT}" ]; then
# mkdir ./wolfSSL/src/wolfcrypt
# mkdir ./wolfssl/src/wolfcrypt
echo "Step 07: mkdir .${WOLFCRYPT_ROOT}"
mkdir .${WOLFCRYPT_ROOT}
mkdir ."${WOLFCRYPT_ROOT}"
fi
# mkdir ./wolfSSL/src/wolfcrypt/src
# mkdir ./wolfssl/src/wolfcrypt/src
if [ ! -d ".${WOLFCRYPT_SRC}" ]; then
echo "Step 08: mkdir .${WOLFCRYPT_SRC}"
mkdir .${WOLFCRYPT_SRC}
mkdir .${WOLFCRYPT_SRC}/port
mkdir .${WOLFCRYPT_SRC}/port/atmel
mkdir .${WOLFCRYPT_SRC}/port/Espressif
mkdir ."${WOLFCRYPT_SRC}"
mkdir ."${WOLFCRYPT_SRC}"/port
mkdir ."${WOLFCRYPT_SRC}"/port/atmel
mkdir ."${WOLFCRYPT_SRC}"/port/Espressif
fi
# cp ../../wolfcrypt/src/*.c ./wolfSSL/src/wolfcrypt/src
echo "Step 09: cp ${WOLFCRYPT_SRC_TOP}/*.c .${WOLFCRYPT_SRC}"
$CP_CMD -r ${WOLFCRYPT_SRC_TOP}/*.c .${WOLFCRYPT_SRC} || exit 1
$CP_CMD -r ${WOLFCRYPT_SRC_TOP}/port/atmel/*.c .${WOLFCRYPT_SRC}/port/atmel || exit 1
$CP_CMD -r ${WOLFCRYPT_SRC_TOP}/port/Espressif/*.c .${WOLFCRYPT_SRC}/port/Espressif || exit 1
# cp ../../wolfcrypt/src/*.c ./wolfssl/src/wolfcrypt/src
echo "Step 09: cp ${WOLFCRYPT_SRC_TOP}/*.c .${WOLFCRYPT_SRC}"
$CP_CMD -r "${WOLFCRYPT_SRC_TOP}"/*.c ."${WOLFCRYPT_SRC}" || exit 1
$CP_CMD -r "${WOLFCRYPT_SRC_TOP}"/port/atmel/*.c ."${WOLFCRYPT_SRC}"/port/atmel || exit 1
$CP_CMD -r "${WOLFCRYPT_SRC_TOP}"/port/Espressif/*.c ."${WOLFCRYPT_SRC}"/port/Espressif || exit 1
# Add in source files to top level src folders
if [ ! -d ".${WOLFSSL_SRC}" ]; then
# mkdir ./wolfSSL/src/src
# mkdir ./wolfssl/src/src
echo "Step 10: mkdir .${WOLFSSL_SRC}"
mkdir .${WOLFSSL_SRC}
mkdir ."${WOLFSSL_SRC}"
fi
$CP_CMD ${WOLFSSL_SRC_TOP}/*.c .${WOLFSSL_SRC} || exit 1
$CP_CMD "${WOLFSSL_SRC_TOP}"/*.c ."${WOLFSSL_SRC}" || exit 1
# put bio and evp as includes
$CP_CMD .${WOLFSSL_SRC}/bio.c .${WOLFSSL_HEADERS} || exit 1
$CP_CMD .${WOLFCRYPT_SRC}/evp.c .${WOLFSSL_HEADERS} || exit 1
$CP_CMD ."${WOLFSSL_SRC}"/bio.c ."${WOLFSSL_HEADERS}" || exit 1
$CP_CMD ."${WOLFCRYPT_SRC}"/evp.c ."${WOLFSSL_HEADERS}" || exit 1
# make a copy of evp.c and bio.c for ssl.c to include inline
$CP_CMD .${WOLFSSL_HEADERS}/evp.c .${WOLFCRYPT_SRC}/evp.c || exit 1
$CP_CMD .${WOLFSSL_HEADERS}/bio.c .${WOLFCRYPT_SRC}/bio.c || exit 1
$CP_CMD ."${WOLFSSL_HEADERS}"/evp.c ."${WOLFCRYPT_SRC}"/evp.c || exit 1
$CP_CMD ."${WOLFSSL_HEADERS}"/bio.c ."${WOLFCRYPT_SRC}"/bio.c || exit 1
# copy openssl compatibility headers to their appropriate location
if [ ! -d ".${OPENSSL_DIR}" ]; then
mkdir .${OPENSSL_DIR}
mkdir ."${OPENSSL_DIR}"
fi
$CP_CMD ${OPENSSL_DIR_TOP}/* .${OPENSSL_DIR} || exit 1
$CP_CMD "${OPENSSL_DIR_TOP}"/* ."${OPENSSL_DIR}" || exit 1
# Finally, copy the Arduino-specific wolfssl library files into place: [lib]/src
$CP_CMD ./wolfssl.h ".${ROOT_SRC_DIR}"/wolfssl.h
cat > .${ROOT_SRC_DIR}/wolfssl.h <<EOF
/* Generated wolfSSL header file for Arduino */
#include <user_settings.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/ssl.h>
EOF
echo "Copy examples...."
# Copy examples
mkdir -p ".${ROOT_SRC_DIR}"/examples
echo "Copy wolfssl_client example...."
mkdir -p ".${EXAMPLES_DIR}"/wolfssl_client
$CP_CMD ./sketches/wolfssl_client/wolfssl_client.ino ".${EXAMPLES_DIR}"/wolfssl_client/wolfssl_client.ino || exit 1
$CP_CMD ./sketches/wolfssl_client/README.md ".${EXAMPLES_DIR}"/wolfssl_client/README.md || exit 1
echo "Copy wolfssl_server example...."
mkdir -p .${EXAMPLES_DIR}/wolfssl_server
$CP_CMD ./sketches/wolfssl_server/wolfssl_server.ino ".${EXAMPLES_DIR}"/wolfssl_server/wolfssl_server.ino || exit 1
$CP_CMD ./sketches/wolfssl_server/README.md ".${EXAMPLES_DIR}"/wolfssl_server/README.md || exit 1
else
echo "ERROR: You must be in the IDE/ARDUINO directory to run this script"
@ -248,23 +273,23 @@ sed -i.backup s/"$ARDUINO_VERSION_SUFFIX_PLACEHOLDER"/"$WOLFSSL_VERSION_ARUINO_
# echo "${WOLFSSL_VERSION_ARUINO_SUFFIX}"
echo "Step 11: Final root file copy"
$CP_CMD PREPENDED_README.md .${ROOT_DIR}/README.md || exit 1
$CP_CMD library.properties.tmp .${ROOT_DIR}/library.properties || exit 1
$CP_CMD ${TOP_DIR}/"LICENSING" .${ROOT_DIR}/ || exit 1
$CP_CMD ${TOP_DIR}/"README" .${ROOT_DIR}/ || exit 1
$CP_CMD ${TOP_DIR}/"COPYING" .${ROOT_DIR}/ || exit 1
$CP_CMD ${TOP_DIR}/"ChangeLog.md" .${ROOT_DIR}/ || exit 1
$CP_CMD ${TOP_DIR}/".editorconfig" .${ROOT_DIR}/ || exit 1
$CP_CMD ${TOP_DIR}/".gitignore" .${ROOT_DIR}/ || exit 1
$CP_CMD PREPENDED_README.md ."${ROOT_DIR}"/README.md || exit 1
$CP_CMD library.properties.tmp ."${ROOT_DIR}"/library.properties || exit 1
$CP_CMD "${TOP_DIR}"/"LICENSING" ."${ROOT_DIR}"/ || exit 1
$CP_CMD "${TOP_DIR}"/"README" ."${ROOT_DIR}"/ || exit 1
$CP_CMD "${TOP_DIR}"/"COPYING" ."${ROOT_DIR}"/ || exit 1
$CP_CMD "${TOP_DIR}"/"ChangeLog.md" ."${ROOT_DIR}"/ || exit 1
$CP_CMD "${TOP_DIR}"/".editorconfig" ."${ROOT_DIR}"/ || exit 1
$CP_CMD "${TOP_DIR}"/".gitignore" ."${ROOT_DIR}"/ || exit 1
$CP_CMD "keywords.txt" .${ROOT_DIR}/ || exit 1
$CP_CMD "keywords.txt" ."${ROOT_DIR}"/ || exit 1
echo "Step 12: workspace to publish:"
echo "Step 12: Workspace to publish:"
echo ""
head -n 3 PREPENDED_README.md
echo ""
ls ./wolfSSL -al
ls ./wolfssl -al
echo ""
# Optionally install to a separate directory.
@ -273,14 +298,22 @@ echo ""
if [ "$THIS_OPERATION" = "INSTALL" ]; then
if [ "$THIS_INSTALL_IS_GITHUB" = "true" ]; then
echo "Installing to GitHub directory: $THIS_INSTALL_DIR"
cp -r ".$ROOT_DIR"/* "$THIS_INSTALL_DIR" || exit 1
cp -r ."$ROOT_DIR"/* "$THIS_INSTALL_DIR" || exit 1
else
echo "Install:"
echo "cp ../../examples/configs/user_settings_arduino.h .${ROOT_SRC_DIR}/user_settings.h"
cp ../../examples/configs/user_settings_arduino.h ".${ROOT_SRC_DIR}/user_settings.h" || exit 1
echo "Config:"
echo "cp ../../examples/configs/user_settings_arduino.h ".${ROOT_SRC_DIR}"/user_settings.h"
# Nearly an ordinary copy, but we remove any lines with ">>" (typically edit with caution warning in comments)
grep -v '>>' ../../examples/configs/user_settings_arduino.h > ".${ROOT_SRC_DIR}"/user_settings.h || exit 1
echo "mv $ROOT_DIR $ARDUINO_ROOT"
mv ".$ROOT_DIR" "$ARDUINO_ROOT" || exit 1
# Show the user_settings.h revision string:
grep "WOLFSSL_USER_SETTINGS_ID" ."${ROOT_SRC_DIR}/user_settings.h"
echo ""
echo "Install:"
echo "mv .$ROOT_DIR $ARDUINO_ROOT"
mv ."$ROOT_DIR" "$ARDUINO_ROOT" || exit 1
echo "Arduino wolfSSL Version: $WOLFSSL_VERSION$WOLFSSL_VERSION_ARUINO_SUFFIX"
fi
fi

View File

@ -0,0 +1,39 @@
/* wolfssl.h
*
* Copyright (C) 2006-2024 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 2 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
*/
/* Edit with caution. This is an Arduino-library specific header for wolfSSL */
#ifndef WOLFSSL_USER_SETTINGS
#define WOLFSSL_USER_SETTINGS
#endif
#include <Arduino.h>
/* wolfSSL user_settings.h must be included from settings.h */
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/ssl.h>
int wolfSSL_Arduino_Serial_Print(const char *const s)
{
/* See wolfssl/wolfcrypt/logging.c */
Serial.println(F(s));
return 0;
};

View File

@ -19,7 +19,13 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* This is a sample Arduino user_settings.h for wolfSSL */
/* This is a sample Arduino user_settings.h for wolfSSL
>> Edit with caution. This is the file copied to wolfSSL Arduino library.
>> at publish time. (lines with ">>" are removed)
*/
/* Define a macro to display user settings version in example code: */
#define WOLFSSL_USER_SETTINGS_ID "Arduino user_settings.h v5.6.6 Rev 5"
#define NO_FILESYSTEM
#define USE_CERT_BUFFERS_2048
@ -29,15 +35,26 @@
#define HAVE_ECC
#define WOLFSSL_SMALL_STACK
/* #define WOLFSSL_SMALL_STACK_EXTRA */
/* #define WOLFSSL_SMALL_STACK_CIPHERS */
/* #define NO_DH */
/* #define WOLFSSL_SMALL_STACK_EXTRA */
/* #define WOLFSSL_SMALL_STACK_CIPHERS */
/* #define NO_DH */
#define MICRO_SESSION_CACHE
/* RSA must be enabled for examples, but can be disabled like this: */
/* #define NO_RSA */
#define RSA_LOW_MEM
/* #define NO_OLD_TLS */
#define NO_OLD_TLS
/* TLS 1.3 */
/* #define WOLFSSL_TLS13 */
#if defined(WOLFSSL_TLS13)
#define HAVE_TLS_EXTENSIONS
#define WC_RSA_PSS
#define HAVE_HKDF
#define HAVE_AEAD
#endif
/* #define HAVE_SUPPORTED_CURVES */
/* Cannot use WOLFSSL_NO_MALLOC with small stack */
/* #define WOLFSSL_NO_MALLOC */
@ -45,6 +62,35 @@
#define HAVE_TLS_EXTENSIONS
#define HAVE_SUPPORTED_CURVES
/* To further reduce size, client or server functionality can be disabled.
* Here, we check if the example code gave us a hint.
*
* The calling application can define either one of these macros before
* including the Arduino wolfssl.h library file:
*
* WOLFSSL_CLIENT_EXAMPLE
* WOLFSSL_SERVER_EXAMPLE
*/
#if defined(WOLFSSL_CLIENT_EXAMPLE)
#define NO_WOLFSSL_SERVER
#elif defined(WOLFSSL_SERVER_EXAMPLE)
#define NO_WOLFSSL_CLIENT
#else
/* Provide a hint to application that neither WOLFSSL_CLIENT_EXAMPLE
* or WOLFSSL_SERVER_EXAMPLE macro hint was desired but not found. */
#define NO_WOLFSSL_SERVER_CLIENT_MISSING
#warning "Define WOLFSSL_CLIENT_EXAMPLE or WOLFSSL_SERVER_EXAMPLE to" \
" optimize memory for small embedded devices."
/* Both can be disabled in wolfssl test & benchmark */
#endif
#define NO_DH
#define NO_DSA
#define USE_FAST_MATH
#define WOLFSSL_SMALL_STACK
#define SINGLE_THREADED
#define WOLFSSL_LOW_MEMORY
#define HAVE_AESGCM
/* optionally turn off SHA512/224 SHA512/256 */
@ -241,13 +287,14 @@
#define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
/***** END CONFIG_IDF_TARGET_ESP266 *****/
#else
/* Anything else encountered, disable HW accleration */
/* Anything else encountered, disable HW acceleration */
#define NO_ESP32_CRYPT
#define NO_WOLFSSL_ESP32_CRYPT_HASH
#define NO_WOLFSSL_ESP32_CRYPT_AES
#define NO_WOLFSSL_ESP32_CRYPT_RSA_PRI
#endif /* CONFIG_IDF_TARGET Check */
#define DEBUG_WOLFSSL
/* Debug options:
#define ESP_VERIFY_MEMBLOCK
@ -266,10 +313,10 @@
#define WOLFSSL_ESPIDF_ERROR_PAUSE /* Pause in a loop rather than exit. */
#define WOLFSSL_HW_METRICS
#define ALT_ECC_SIZE
/* #define HASH_SIZE_LIMIT */ /* for test.c */
/* #define NO_HW_MATH_TEST */ /* Optionall turn off HW math checks */
/* #define NO_HW_MATH_TEST */ /* Optionally turn off HW math checks */
/* Optionally include alternate HW test library: alt_hw_test.h */
/* When enabling, the ./components/wolfssl/CMakeLists.txt file
@ -301,6 +348,7 @@
#define ATCA_WOLFSSL
*/
/* optional SM4 Ciphers. See https://github.com/wolfSSL/wolfsm
/* The section below defines macros used in typically all of the wolfSSL
* examples such as the client and server for certs stored in header files.
*
@ -384,6 +432,9 @@
#define WOLFSSL_BASE16
#else
#if defined(USE_CERT_BUFFERS_2048)
#ifdef USE_CERT_BUFFERS_1024
#error "USE_CERT_BUFFERS_1024 is already defined. Pick one."
#endif
#include <wolfssl/certs_test.h>
#define CTX_CA_CERT ca_cert_der_2048
#define CTX_CA_CERT_SIZE sizeof_ca_cert_der_2048
@ -402,8 +453,10 @@
#define CTX_CLIENT_KEY client_key_der_2048
#define CTX_CLIENT_KEY_SIZE sizeof_client_key_der_2048
#define CTX_CLIENT_KEY_TYPE WOLFSSL_FILETYPE_ASN1
#elif defined(USE_CERT_BUFFERS_1024)
#ifdef USE_CERT_BUFFERS_2048
#error "USE_CERT_BUFFERS_2048 is already defined. Pick one."
#endif
#include <wolfssl/certs_test.h>
#define CTX_CA_CERT ca_cert_der_1024
#define CTX_CA_CERT_SIZE sizeof_ca_cert_der_1024
@ -423,7 +476,6 @@
#define CTX_SERVER_KEY_SIZE sizeof_server_key_der_1024
#define CTX_SERVER_KEY_TYPE WOLFSSL_FILETYPE_ASN1
#else
/* Optionally define custom cert arrays, sizes, and types here */
#error "Must define USE_CERT_BUFFERS_2048 or USE_CERT_BUFFERS_1024"
#endif
#endif /* Conditional key and cert constant names */
#endif

View File

@ -5428,7 +5428,9 @@ int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer)
keySz = ssl->eccTempKeySz;
/* get curve type */
if (ssl->ecdhCurveOID > 0) {
WOLFSSL_MSG("calling ecc_cuve"); /* TODO; review */
ecc_curve = wc_ecc_get_oid(ssl->ecdhCurveOID, NULL, NULL);
WOLFSSL_MSG("ecc_curve done");
}
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) && \
(defined(WOLFSSL_SM4_CBC) || defined(WOLFSSL_SM4_GCM) || \
@ -5462,7 +5464,9 @@ int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer)
else
#endif
{
WOLFSSL_MSG("make key"); /* TODO review */
ret = wc_ecc_make_key_ex(ssl->rng, keySz, key, ecc_curve);
WOLFSSL_MSG("make key done");
}
/* make sure the curve is set for TLS */

View File

@ -136,6 +136,15 @@
#define FALSE 0
#endif
#ifndef HAVE_AEAD
#ifndef _MSC_VER
#error "The build option HAVE_AEAD is required for TLS 1.3"
#else
#pragma \
message("error: The build option HAVE_AEAD is required for TLS 1.3")
#endif
#endif
#ifndef HAVE_HKDF
#ifndef _MSC_VER
#error "The build option HAVE_HKDF is required for TLS 1.3"

View File

@ -1650,7 +1650,7 @@ static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
#ifdef ECC_CACHE_CURVE
int x;
#endif
WOLFSSL_ENTER("wc_ecc_curve_load");
if (dp == NULL || pCurve == NULL)
return BAD_FUNC_ARG;
@ -1751,6 +1751,8 @@ static int wc_ecc_curve_load(const ecc_set_type* dp, ecc_curve_spec** pCurve,
wc_UnLockMutex(&ecc_curve_cache_mutex);
#endif
WOLFSSL_LEAVE("wc_ecc_curve_load", ret);
return ret;
}
@ -2629,7 +2631,7 @@ int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
int err;
(void)ct;
WOLFSSL_ENTER("ecc_map_ex");
if (P == NULL || modulus == NULL)
return ECC_BAD_ARG_E;
@ -2658,6 +2660,7 @@ int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
#endif /* WOLFSSL_SMALL_STACK_CACHE */
#endif
{
WOLFSSL_MSG("ecc new mp");
NEW_MP_INT_SIZE(t1, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
NEW_MP_INT_SIZE(t2, mp_bitsused(modulus), NULL, DYNAMIC_TYPE_ECC);
#ifdef MP_INT_SIZE_CHECK_NULL
@ -2683,7 +2686,7 @@ int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct)
#endif
#endif
}
WOLFSSL_MSG("ecc init");
err = INIT_MP_INT_SIZE(t1, mp_bitsused(modulus));
if (err == MP_OKAY) {
err = INIT_MP_INT_SIZE(t2, mp_bitsused(modulus));
@ -2814,7 +2817,10 @@ done:
}
return err;
/* end !defined(WOLFSSL_SP_MATH) */
#else
/* begin defined(WOLFSSL_SP_MATH) */
if (P == NULL || modulus == NULL)
return ECC_BAD_ARG_E;
@ -2823,26 +2829,27 @@ done:
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
if ((mp_count_bits(modulus) == 256) && (!mp_is_bit_set(modulus, 224))) {
return sp_ecc_map_sm2_256(P->x, P->y, P->z);
err = sp_ecc_map_sm2_256(P->x, P->y, P->z);
}
#endif
#ifndef WOLFSSL_SP_NO_256
#elif defined(WOLFSSL_SP_NO_256)
if (mp_count_bits(modulus) == 256) {
return sp_ecc_map_256(P->x, P->y, P->z);
err = sp_ecc_map_256(P->x, P->y, P->z);
}
#endif
#ifdef WOLFSSL_SP_384
#elif defined(WOLFSSL_SP_384)
if (mp_count_bits(modulus) == 384) {
return sp_ecc_map_384(P->x, P->y, P->z);
err = sp_ecc_map_384(P->x, P->y, P->z);
}
#endif
#ifdef WOLFSSL_SP_521
#elif defined(WOLFSSL_SP_521)
if (mp_count_bits(modulus) == 521) {
return sp_ecc_map_521(P->x, P->y, P->z);
err = sp_ecc_map_521(P->x, P->y, P->z);
}
#else
err = ECC_BAD_ARG_E;
#endif
return ECC_BAD_ARG_E;
#endif
WOLFSSL_LEAVE("ecc_map_ex (SP Math)");
return err;
#endif /* WOLFSSL_SP_MATH */
}
#endif /* !FREESCALE_LTC_ECC && !WOLFSSL_STM32_PKA */
@ -3831,7 +3838,7 @@ int wc_ecc_mulmod_ex2(const mp_int* k, ecc_point* G, ecc_point* R, mp_int* a,
ecc_key key;
#endif
mp_digit mp;
WOLFSSL_ENTER("wc_ecc_mulmod_ex2");
if (k == NULL || G == NULL || R == NULL || modulus == NULL) {
return ECC_BAD_ARG_E;
}
@ -3993,6 +4000,7 @@ static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
int err = MP_OKAY;
ecc_point* p;
WOLFSSL_ENTER("wc_ecc_new_point_ex");
if (point == NULL) {
return BAD_FUNC_ARG;
}
@ -4000,23 +4008,32 @@ static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
p = *point;
#ifndef WOLFSSL_NO_MALLOC
if (p == NULL) {
p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
WOLFSSL_MSG_EX("XMALLOC ecc_point %d bytes.", sizeof(ecc_point));
p = (ecc_point*)XMALLOC(sizeof(ecc_point), heap, DYNAMIC_TYPE_ECC);
WOLFSSL_MSG("XMALLOC ecc_point complete.");
}
else {
WOLFSSL_MSG("XMALLOC ecc_point skipped! (p == NULL)");
}
#endif
if (p == NULL) {
WOLFSSL_MSG("failed to XMALLOC ecc_point");
return MEMORY_E;
}
XMEMSET(p, 0, sizeof(ecc_point));
#ifndef ALT_ECC_SIZE
WOLFSSL_MSG("mp_init_multi for ecc x,y,z (!ALT_ECC_SIZE)");
err = mp_init_multi(p->x, p->y, p->z, NULL, NULL, NULL);
if (err != MP_OKAY) {
WOLFSSL_MSG("mp_init_multi failed.");
#ifndef WOLFSSL_NO_MALLOC
XFREE(p, heap, DYNAMIC_TYPE_ECC);
#endif
return err;
}
#else
WOLFSSL_MSG("alt_fp_init ecc x,y,z (ALT_ECC_SIZE)");
p->x = (mp_int*)&p->xyz[0];
p->y = (mp_int*)&p->xyz[1];
p->z = (mp_int*)&p->xyz[2];
@ -4027,14 +4044,18 @@ static int wc_ecc_new_point_ex(ecc_point** point, void* heap)
*point = p;
(void)heap;
WOLFSSL_LEAVE("wc_ecc_new_point_ex", err);
return err;
}
} /* wc_ecc_new_point_ex */
ecc_point* wc_ecc_new_point_h(void* heap)
{
ecc_point* p = NULL;
(void)wc_ecc_new_point_ex(&p, heap);
return p;
}
ecc_point* wc_ecc_new_point(void)
{
ecc_point* p = NULL;
@ -5171,6 +5192,7 @@ int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
#ifndef WOLFSSL_ECC_GEN_REJECT_SAMPLING
int err;
byte buf[ECC_MAXSIZE_GEN];
WOLFSSL_ENTER("wc_ecc_gen_k");
if (rng == NULL || size < 0 || size + 8 > ECC_MAXSIZE_GEN || k == NULL ||
order == NULL) {
@ -5256,6 +5278,7 @@ int wc_ecc_gen_k(WC_RNG* rng, int size, mp_int* k, mp_int* order)
wc_MemZero_Check(buf, ECC_MAXSIZE_GEN);
#endif
WOLFSSL_LEAVE("wc_ecc_gen_k", err);
return err;
#endif
#else
@ -5295,9 +5318,9 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
#ifdef HAVE_ECC_MAKE_PUB
ecc_point* pub;
#endif /* HAVE_ECC_MAKE_PUB */
(void)rng;
WOLFSSL_ENTER("ecc_make_pub_ex");
if (key == NULL) {
return BAD_FUNC_ARG;
}
@ -5394,6 +5417,7 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
ecc_point lcl_base;
base = &lcl_base;
#endif
err = wc_ecc_new_point_ex(&base, key->heap);
/* read in the x/y for this key */
@ -5450,7 +5474,7 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
}
RESTORE_VECTOR_REGISTERS();
WOLFSSL_LEAVE("ecc_make_pub_ex", err);
return err;
}
@ -5511,6 +5535,8 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
int curve_id, int flags)
{
int err = 0;
WOLFSSL_ENTER("_ecc_make_key_ex");
#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) && \
!defined(WOLFSSL_ATECC608A)
const CRYS_ECPKI_Domain_t* pDomain;
@ -5809,7 +5835,6 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
err = WC_KEY_SIZE_E;
#else
DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT);
/* setup the key variables */
#ifndef ALT_ECC_SIZE
err = mp_init(key->k);
@ -5821,6 +5846,7 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
/* load curve info */
if (err == MP_OKAY) {
WOLFSSL_MSG("load curve specs");
ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err);
if (err != MP_OKAY) {
WOLFSSL_MSG("ALLOC_CURVE_SPECS failed");
@ -5828,6 +5854,7 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
}
if (err == MP_OKAY) {
err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL);
if (err != MP_OKAY) {
WOLFSSL_MSG("wc_ecc_curve_load failed");
@ -5880,6 +5907,7 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
#endif
#endif /* HAVE_ECC_MAKE_PUB */
WOLFSSL_LEAVE("_ecc_make_key_ex", err);
return err;
#endif /* !WOLF_CRYPTO_CB_ONLY_ECC */
@ -5890,9 +5918,9 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
int flags)
{
int err;
WOLFSSL_ENTER("wc_ecc_make_key_ex2");
SAVE_VECTOR_REGISTERS(return _svr_ret;);
err = _ecc_make_key_ex(rng, keysize, key, curve_id, flags);
#if (FIPS_VERSION_GE(5,0) || defined(WOLFSSL_VALIDATE_ECC_KEYGEN)) && \
@ -5918,6 +5946,7 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
WOLFSSL_ABI
int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
{
WOLFSSL_ENTER("wc_ecc_make_key_ex");
return wc_ecc_make_key_ex2(rng, keysize, key, curve_id, WC_ECC_FLAG_NONE);
}

View File

@ -234,7 +234,9 @@ void WOLFSSL_TIME(int count)
#ifdef DEBUG_WOLFSSL
#if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
#if defined(ARDUINO)
/* see Arduino wolfssl.h for wolfSSL_Arduino_Serial_Print */
#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
/* see wc_port.h for fio.h and nio.h includes */
#elif defined(WOLFSSL_SGX)
/* Declare sprintf for ocall */
@ -281,9 +283,10 @@ static void wolfssl_log(const int logLevel, const char *const logMessage)
else {
#if defined(WOLFSSL_USER_LOG)
WOLFSSL_USER_LOG(logMessage);
#elif defined(ARDUINO)
wolfSSL_Arduino_Serial_Print(logMessage);
#elif defined(WOLFSSL_LOG_PRINTF)
printf("%s\n", logMessage);
#elif defined(THREADX) && !defined(THREADX_NO_DC_PRINTF)
dc_log_printf("%s\n", logMessage);
#elif defined(WOLFSSL_DEOS)

View File

@ -1648,7 +1648,14 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,
seedSz = MAX_SEED_SZ;
}
if (wc_RNG_HealthTestLocal(0, rng->heap, devId) == 0) {
ret = wc_RNG_HealthTestLocal(0, rng->heap, devId);
if (ret != 0) {
#if defined(DEBUG_WOLFSSL)
WOLFSSL_MSG_EX("wc_RNG_HealthTestLocal failed err = %d", ret);
#endif
ret = DRBG_CONT_FAILURE;
}
else {
#ifndef WOLFSSL_SMALL_STACK
byte seed[MAX_SEED_SZ];
#else
@ -1720,10 +1727,7 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz,
#ifdef WOLFSSL_SMALL_STACK
XFREE(seed, rng->heap, DYNAMIC_TYPE_SEED);
#endif
}
else {
ret = DRBG_CONT_FAILURE;
}
} /* else swc_RNG_HealthTestLocal was successful */
if (ret == DRBG_SUCCESS) {
#ifdef WOLFSSL_CHECK_MEM_ZERO
@ -2226,16 +2230,32 @@ static int wc_RNG_HealthTestLocal(int reseed, void* heap, int devId)
#else
const byte* seedB = seedB_data;
const byte* outputB = outputB_data;
#endif
#if defined(DEBUG_WOLFSSL)
WOLFSSL_MSG_EX("RNG_HEALTH_TEST_CHECK_SIZE = %d",
RNG_HEALTH_TEST_CHECK_SIZE);
WOLFSSL_MSG_EX("sizeof(seedB_data) = %d",
(int)sizeof(outputB_data));
#endif
ret = wc_RNG_HealthTest_ex(0, NULL, 0,
seedB, sizeof(seedB_data),
NULL, 0,
check, RNG_HEALTH_TEST_CHECK_SIZE,
heap, devId);
if (ret == 0) {
if (ConstantCompare(check, outputB,
RNG_HEALTH_TEST_CHECK_SIZE) != 0)
if (ret != 0) {
#if defined(DEBUG_WOLFSSL)
WOLFSSL_MSG_EX("RNG_HealthTest failed: err = %d", ret);
#endif
}
else {
ret = ConstantCompare(check, outputB,
RNG_HEALTH_TEST_CHECK_SIZE);
if (ret != 0) {
#if defined(DEBUG_WOLFSSL)
WOLFSSL_MSG_EX("Random ConstantCompare failed: err = %d", ret);
#endif
ret = -1;
}
}
/* The previous test cases use a large seed instead of a seed and nonce.
@ -3490,7 +3510,11 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
if (sz < len)
len = sz;
/* Get an Arduino framework random number */
#if defined(__arm__)
#if defined(ARDUINO_SAMD_NANO_33_IOT) || \
defined(ARDUINO_ARCH_RP2040)
/* Known, tested boards working with random() */
rand = random();
#elif defined(ARDUINO_SAM_DUE)
/* See: https://github.com/avrxml/asf/tree/master/sam/utils/cmsis/sam3x/include */
#if defined(__SAM3A4C__)
#ifndef TRNG
@ -3534,10 +3558,12 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
#warning "Not yet tested on STM32 targets"
rand = random();
#else
/* TODO: Pull requests appreciated for new targets */
#warning "Not yet tested on this target"
/* TODO: Pull requests appreciated for new targets.
* Do *all* other Arduino boards support random()?
* Probably not 100%, but most will likely work: */
rand = random();
#endif
XMEMCPY(output, &rand, len);
output += len;
sz -= len;

View File

@ -89,6 +89,11 @@ enum wc_FuncNum {
};
#endif
#if defined(ARDUINO)
/* implemented in Arduino wolfssl.h */
extern WOLFSSL_API int wolfSSL_Arduino_Serial_Print(const char* const s);
#endif /* ARDUINO */
typedef void (*wolfSSL_Logging_cb)(const int logLevel,
const char *const logMessage);