From 71d6ebecfbdf6b87300302a34d41e909f3685a27 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 30 Nov 2023 10:13:20 +0100 Subject: [PATCH 01/33] OTAUpdate: do not use Error enum to return error codes --- libraries/OTAUpdate/examples/OTA/OTA.ino | 11 ++--- .../WiFiFirmwareOTA/WiFiFirmwareOTA.ino | 13 +++-- libraries/OTAUpdate/src/OTAUpdate.cpp | 48 +++++++++---------- libraries/OTAUpdate/src/OTAUpdate.h | 37 +++++--------- 4 files changed, 48 insertions(+), 61 deletions(-) diff --git a/libraries/OTAUpdate/examples/OTA/OTA.ino b/libraries/OTAUpdate/examples/OTA/OTA.ino index 758b0beb8..91cf4f100 100644 --- a/libraries/OTAUpdate/examples/OTA/OTA.ino +++ b/libraries/OTAUpdate/examples/OTA/OTA.ino @@ -54,15 +54,14 @@ void setup() { printWiFiStatus(); - OTAUpdate::Error ret = OTAUpdate::Error::None; - ret = ota.begin("/update.bin"); - if(ret != OTAUpdate::Error::None) { + int ret = ota.begin("/update.bin"); + if(ret != OTAUpdate::OTA_ERROR_NONE) { Serial.println("ota.begin() error: "); Serial.println((int)ret); return; } ret = ota.setCACert(root_ca); - if(ret != OTAUpdate::Error::None) { + if(ret != OTAUpdate::OTA_ERROR_NONE) { Serial.println("ota.setCACert() error: "); Serial.println((int)ret); return; @@ -74,14 +73,14 @@ void setup() { return; } ret = ota.verify(); - if(ret != OTAUpdate::Error::None) { + if(ret != OTAUpdate::OTA_ERROR_NONE) { Serial.println("ota.verify() error: "); Serial.println((int)ret); return; } ret = ota.update("/update.bin"); - if(ret != OTAUpdate::Error::None) { + if(ret != OTAUpdate::OTA_ERROR_NONE) { Serial.println("ota.update() error: "); Serial.println((int)ret); return; diff --git a/libraries/OTAUpdate/examples/WiFiFirmwareOTA/WiFiFirmwareOTA.ino b/libraries/OTAUpdate/examples/WiFiFirmwareOTA/WiFiFirmwareOTA.ino index 73a04fd91..4b84fa109 100644 --- a/libraries/OTAUpdate/examples/WiFiFirmwareOTA/WiFiFirmwareOTA.ino +++ b/libraries/OTAUpdate/examples/WiFiFirmwareOTA/WiFiFirmwareOTA.ino @@ -64,15 +64,14 @@ void setup() { printWiFiStatus(); - OTAUpdate::Error ret = OTAUpdate::Error::None; - ret = ota.begin(); - if(ret != OTAUpdate::Error::None) { + int ret = ota.begin(); + if(ret != OTAUpdate::OTA_ERROR_NONE) { Serial.println("ota.begin() error: "); Serial.println((int)ret); return; } ret = ota.setCACert(root_ca); - if(ret != OTAUpdate::Error::None) { + if(ret != OTAUpdate::OTA_ERROR_NONE) { Serial.println("ota.setCACert() error: "); Serial.println((int)ret); return; @@ -84,19 +83,19 @@ void setup() { return; } ret = ota.verify(); - if(ret != OTAUpdate::Error::None) { + if(ret != OTAUpdate::OTA_ERROR_NONE) { Serial.println("ota.verify() error: "); Serial.println((int)ret); return; } ret = ota.update(); - if(ret != OTAUpdate::Error::None) { + if(ret != OTAUpdate::OTA_ERROR_NONE) { Serial.println("ota.update() error: "); Serial.println((int)ret); return; } ret = ota.reset(); - if(ret != OTAUpdate::Error::None) { + if(ret != OTAUpdate::OTA_ERROR_NONE) { Serial.println("ota.reset() error: "); Serial.println((int)ret); return; diff --git a/libraries/OTAUpdate/src/OTAUpdate.cpp b/libraries/OTAUpdate/src/OTAUpdate.cpp index c98afda07..50ce57233 100644 --- a/libraries/OTAUpdate/src/OTAUpdate.cpp +++ b/libraries/OTAUpdate/src/OTAUpdate.cpp @@ -22,35 +22,35 @@ using namespace std; OTAUpdate::OTAUpdate() {} -OTAUpdate::Error OTAUpdate::setCACert(const char* root_ca) { +int OTAUpdate::setCACert(const char* root_ca) { string res = ""; if ( root_ca != nullptr && strlen(root_ca) > 0) { modem.write_nowait(string(PROMPT(_OTA_SETCAROOT)), res, "%s%d\r\n", CMD_WRITE(_OTA_SETCAROOT), strlen(root_ca)); if(modem.passthrough((uint8_t *)root_ca, strlen(root_ca))) { - return Error::None; + return static_cast(Error::None); } - return Error::Modem; + return static_cast(Error::Modem); } - return Error::Library; + return static_cast(Error::Library); } -OTAUpdate::Error OTAUpdate::begin() { +int OTAUpdate::begin() { string res = ""; if (modem.write(string(PROMPT(_OTA_BEGIN)), res, "%s", CMD(_OTA_BEGIN))) { - return static_cast(atoi(res.c_str())); + return atoi(res.c_str()); } - return Error::Modem; + return static_cast(Error::Modem); } -OTAUpdate::Error OTAUpdate::begin(const char* file_path) { +int OTAUpdate::begin(const char* file_path) { string res = ""; if ( file_path != nullptr && strlen(file_path) > 0) { if (modem.write(string(PROMPT(_OTA_BEGIN)), res, "%s%s\r\n", CMD_WRITE(_OTA_BEGIN), file_path)) { - return static_cast(atoi(res.c_str())); + return atoi(res.c_str()); } - return Error::Modem; + return static_cast(Error::Modem); } - return Error::Library; + return static_cast(Error::Library); } int OTAUpdate::download(const char* url) { @@ -87,37 +87,37 @@ int OTAUpdate::download(const char* url, const char* file_path) { return ret; } -OTAUpdate::Error OTAUpdate::verify() { +int OTAUpdate::verify() { string res = ""; if (modem.write(string(PROMPT(_OTA_VERIFY)), res, "%s", CMD(_OTA_VERIFY))) { - return static_cast(atoi(res.c_str())); + return atoi(res.c_str()); } - return Error::Modem; + return static_cast(Error::Modem); } -OTAUpdate::Error OTAUpdate::update() { +int OTAUpdate::update() { string res = ""; if (modem.write(string(PROMPT(_OTA_UPDATE)), res, "%s", CMD(_OTA_UPDATE))) { - return static_cast(atoi(res.c_str())); + return atoi(res.c_str()); } - return Error::Modem; + return static_cast(Error::Modem); } -OTAUpdate::Error OTAUpdate::update(const char* file_path) { +int OTAUpdate::update(const char* file_path) { string res = ""; if ( file_path != nullptr && strlen(file_path) > 0) { if (modem.write(string(PROMPT(_OTA_UPDATE)), res, "%s%s\r\n", CMD_WRITE(_OTA_UPDATE), file_path)) { - return Error::None; + return atoi(res.c_str()); } - return Error::Modem; + return static_cast(Error::Modem); } - return Error::Library; + return static_cast(Error::Library); } -OTAUpdate::Error OTAUpdate::reset() { +int OTAUpdate::reset() { string res = ""; if (modem.write(string(PROMPT(_OTA_RESET)), res, "%s", CMD(_OTA_RESET))) { - return Error::None; + return static_cast(Error::None); } - return Error::Modem; + return static_cast(Error::Modem); } diff --git a/libraries/OTAUpdate/src/OTAUpdate.h b/libraries/OTAUpdate/src/OTAUpdate.h index 4afeaf0e2..9b1b171c0 100644 --- a/libraries/OTAUpdate/src/OTAUpdate.h +++ b/libraries/OTAUpdate/src/OTAUpdate.h @@ -28,35 +28,24 @@ class OTAUpdate { public: - enum class Error: int { - None = 0, - StorageConfig = -1, - NoOtaStorage = -2, - OtaStorageInit = -3, - OtaStorageEnd = -4, - UrlParseError = -5, - ServerConnectError = -6, - HttpHeaderError = -7, - ParseHttpHeader = -8, - OtaHeaderLength = -9, - OtaHeaderCrc = -10, - OtaHeaderMagicNumber = -11, - OtaDownload = -12, - OtaFlash = -13, - Library = -14, - Modem = -15, + enum class Error: int { + None = 0, + Library = -25, + Modem = -26, }; + constexpr static const int OTA_ERROR_NONE = static_cast(Error::None); + OTAUpdate(); - OTAUpdate::Error setCACert(const char* root_ca); - OTAUpdate::Error begin(); - OTAUpdate::Error begin(const char* file_path); + int setCACert(const char* root_ca); + int begin(); + int begin(const char* file_path); int download(const char* url); int download(const char* url, const char* file_path); - OTAUpdate::Error verify(); - OTAUpdate::Error update(); - OTAUpdate::Error update(const char* file_path); - OTAUpdate::Error reset(); + int verify(); + int update(); + int update(const char* file_path); + int reset(); }; From 05248d5744d4598d8517faf028891a79c23ee643 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sat, 23 Dec 2023 19:31:52 +0100 Subject: [PATCH 02/33] WiFiS3 let WiFi.h include WiFiClient, WiFiUDP, WiFiServer --- libraries/WiFiS3/src/WiFi.h | 4 ++++ libraries/WiFiS3/src/WiFiS3.h | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/WiFiS3/src/WiFi.h b/libraries/WiFiS3/src/WiFi.h index 9958b7c17..13fee1f2b 100644 --- a/libraries/WiFiS3/src/WiFi.h +++ b/libraries/WiFiS3/src/WiFi.h @@ -8,6 +8,10 @@ #include "WiFiTypes.h" #include "Modem.h" +#include "WiFiClient.h" +#include "WiFiServer.h" +#include "WiFiUdp.h" +#include "WiFiSSLClient.h" #define DEFAULT_IP_AP_ADDRESS IPAddress(192,168,4,1) #define DEFAULT_GW_AP_ADDRESS IPAddress(192,168,1,1) diff --git a/libraries/WiFiS3/src/WiFiS3.h b/libraries/WiFiS3/src/WiFiS3.h index 4328ab595..eb42c08b0 100644 --- a/libraries/WiFiS3/src/WiFiS3.h +++ b/libraries/WiFiS3/src/WiFiS3.h @@ -21,9 +21,5 @@ #define WiFiS3_h #include "WiFi.h" -#include "WiFiClient.h" -#include "WiFiServer.h" -#include "WiFiUdp.h" -#include "WiFiSSLClient.h" #endif \ No newline at end of file From 1c193cf1ae5eab668ade9862e1a550e433eb32c4 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 21 Dec 2023 12:46:38 +0100 Subject: [PATCH 03/33] Add Preferences library --- .../examples/Prefs2Struct/Prefs2Struct.ino | 51 +++ .../examples/StartCounter/StartCounter.ino | 58 +++ libraries/Preferences/keywords.txt | 54 +++ libraries/Preferences/library.properties | 9 + libraries/Preferences/src/Preferences.cpp | 383 ++++++++++++++++++ libraries/Preferences/src/Preferences.h | 70 ++++ 6 files changed, 625 insertions(+) create mode 100644 libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino create mode 100644 libraries/Preferences/examples/StartCounter/StartCounter.ino create mode 100644 libraries/Preferences/keywords.txt create mode 100644 libraries/Preferences/library.properties create mode 100644 libraries/Preferences/src/Preferences.cpp create mode 100644 libraries/Preferences/src/Preferences.h diff --git a/libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino b/libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino new file mode 100644 index 000000000..4976ca936 --- /dev/null +++ b/libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino @@ -0,0 +1,51 @@ +/* +This example shows how to use Preferences (nvs) to store a +structure. Note that the maximum size of a putBytes is 496K +or 97% of the nvs partition size. nvs has signifcant overhead, +so should not be used for data that will change often. +*/ +#include +Preferences prefs; + +typedef struct { + uint8_t hour; + uint8_t minute; + uint8_t setting1; + uint8_t setting2; +} schedule_t; + +void setup() { + Serial.begin(115200); + + prefs.begin("schedule"); // use "schedule" namespace + uint8_t content[] = {9, 30, 235, 255, 20, 15, 0, 1}; // two entries + prefs.putBytes("schedule", content, sizeof(content)); + size_t schLen = prefs.getBytesLength("schedule"); + char buffer[schLen]; // prepare a buffer for the data + prefs.getBytes("schedule", buffer, schLen); + if (schLen % sizeof(schedule_t)) { // simple check that data fits + Serial.println("Data is not correct size!"); + return; + } + schedule_t *schedule = (schedule_t *) buffer; // cast the bytes into a struct ptr + Serial.print(schedule[1].hour); + Serial.print(":"); + Serial.print(schedule[1].minute); + Serial.print(" "); + Serial.print(schedule[1].setting1); + Serial.print("/"); + Serial.print(schedule[1].setting2); + + schedule[2] = {8, 30, 20, 21}; // add a third entry (unsafely) + + // force the struct array into a byte array + prefs.putBytes("schedule", schedule, 3*sizeof(schedule_t)); + schLen = prefs.getBytesLength("schedule"); + char buffer2[schLen]; + prefs.getBytes("schedule", buffer2, schLen); + for (int x=0; x + +Preferences preferences; + +void setup() { + Serial.begin(115200); + Serial.println(); + + // Open Preferences with my-app namespace. Each application module, library, etc + // has to use a namespace name to prevent key name collisions. We will open storage in + // RW-mode (second parameter has to be false). + // Note: Namespace name is limited to 15 chars. + int ret = preferences.begin("my-app", false); + Serial.println(ret); + + // Remove all preferences under the opened namespace + //preferences.clear(); + + // Or remove the counter key only + //preferences.remove("counter"); + + // Get the counter value, if the key does not exist, return a default value of 0 + // Note: Key name is limited to 15 chars. + unsigned int counter = preferences.getUInt("counter", 0); + + // Increase counter by 1 + counter++; + + // Print the counter to Serial Monitor + Serial.print("Current counter value: "); + Serial.println(counter); + + // Store the counter to the Preferences + preferences.putUInt("counter", counter); + + // Close the Preferences + preferences.end(); + + // Wait 10 seconds + Serial.println("Restarting in 10 seconds..."); + delay(10000); + + // Reset + NVIC_SystemReset(); +} + +void loop() {} diff --git a/libraries/Preferences/keywords.txt b/libraries/Preferences/keywords.txt new file mode 100644 index 000000000..fe2d4333e --- /dev/null +++ b/libraries/Preferences/keywords.txt @@ -0,0 +1,54 @@ +####################################### +# Syntax Coloring Map NVS +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +Preferences KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +end KEYWORD2 + +clear KEYWORD2 +remove KEYWORD2 + +putChar KEYWORD2 +putUChar KEYWORD2 +putShort KEYWORD2 +putUShort KEYWORD2 +putInt KEYWORD2 +putUInt KEYWORD2 +putLong KEYWORD2 +putULong KEYWORD2 +putLong64 KEYWORD2 +putULong64 KEYWORD2 +putFloat KEYWORD2 +putDouble KEYWORD2 +putBool KEYWORD2 +putString KEYWORD2 +putBytes KEYWORD2 + +getChar KEYWORD2 +getUChar KEYWORD2 +getShort KEYWORD2 +getUShort KEYWORD2 +getInt KEYWORD2 +getUInt KEYWORD2 +getLong KEYWORD2 +getULong KEYWORD2 +getLong64 KEYWORD2 +getULong64 KEYWORD2 +getFloat KEYWORD2 +getDouble KEYWORD2 +getBool KEYWORD2 +getString KEYWORD2 +getBytes KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/Preferences/library.properties b/libraries/Preferences/library.properties new file mode 100644 index 000000000..4c68c1339 --- /dev/null +++ b/libraries/Preferences/library.properties @@ -0,0 +1,9 @@ +name=Preferences +version=2.0.0 +author=Hristo Gochkov +maintainer=Hristo Gochkov +sentence=Provides friendly access to ESP32's Non-Volatile Storage +paragraph= +category=Data Storage +url= +architectures=renesas,renesas_uno diff --git a/libraries/Preferences/src/Preferences.cpp b/libraries/Preferences/src/Preferences.cpp new file mode 100644 index 000000000..e827a8db7 --- /dev/null +++ b/libraries/Preferences/src/Preferences.cpp @@ -0,0 +1,383 @@ +// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "Preferences.h" + + +using namespace std; + +Preferences::Preferences() { + +} + +Preferences::~Preferences() { + end(); +} + +bool Preferences::begin(const char * name, bool readOnly, const char* partition_label){ + string res = ""; + modem.begin(); + if (name != nullptr && strlen(name) > 0) { + if (modem.write(string(PROMPT(_PREF_BEGIN)), res, "%s%s,%d,%s\r\n", CMD_WRITE(_PREF_BEGIN), name, readOnly, partition_label != NULL ? partition_label : "")) { + return (atoi(res.c_str()) != 0) ? true : false; + } + } + return false; +} + +void Preferences::end() { + string res = ""; + modem.write(string(PROMPT(_PREF_END)), res, "%s\r\n", CMD(_PREF_END)); +} + +/* + * Clear all keys in opened preferences + * */ + +bool Preferences::clear() { + string res = ""; + if (modem.write(string(PROMPT(_PREF_CLEAR)), res, "%s\r\n", CMD(_PREF_CLEAR))) { + return (atoi(res.c_str()) != 0) ? true : false; + } + return false; +} + +/* + * Remove a key + * */ + +bool Preferences::remove(const char * key) { + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_REMOVE)), res, "%s%s\r\n", CMD_WRITE(_PREF_REMOVE), key)) { + return (atoi(res.c_str()) != 0) ? true : false; + } + } + return false; +} + +/* + * Put a key value + * */ + +size_t Preferences::putChar(const char* key, int8_t value) { + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%hhd\r\n", CMD_WRITE(_PREF_PUT), key, PT_I8, value)) { + return atoi(res.c_str()); + } + } + return 0; +} + +size_t Preferences::putUChar(const char* key, uint8_t value) { + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%hhu\r\n", CMD_WRITE(_PREF_PUT), key, PT_U8, value)) { + return atoi(res.c_str()); + } + } + return 0; +} + +size_t Preferences::putShort(const char* key, int16_t value) { + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%hd\r\n", CMD_WRITE(_PREF_PUT), key, PT_I16, value)) { + return atoi(res.c_str()); + } + } + return 0; +} + +size_t Preferences::putUShort(const char* key, uint16_t value) { + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%hu\r\n", CMD_WRITE(_PREF_PUT), key, PT_U16, value)) { + return atoi(res.c_str()); + } + } + return 0; +} + +size_t Preferences::putInt(const char* key, int32_t value) { + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%d\r\n", CMD_WRITE(_PREF_PUT), key, PT_I32, value)) { + return atoi(res.c_str()); + } + } + return 0; +} + +size_t Preferences::putUInt(const char* key, uint32_t value) { + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%u\r\n", CMD_WRITE(_PREF_PUT), key, PT_U32, value)) { + return atoi(res.c_str()); + } + } + return 0; +} + +size_t Preferences::putLong(const char* key, int32_t value) { + return putInt(key, value); +} + +size_t Preferences::putULong(const char* key, uint32_t value) { + return putUInt(key, value); +} + +size_t Preferences::putLong64(const char* key, int64_t value) { + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%lld\r\n", CMD_WRITE(_PREF_PUT), key, PT_I64, value)) { + return atoi(res.c_str()); + } + } + return 0; +} + +size_t Preferences::putULong64(const char* key, uint64_t value) { + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%llu\r\n", CMD_WRITE(_PREF_PUT), key, PT_U64, value)) { + return atoi(res.c_str()); + } + } + return 0; +} + +size_t Preferences::putFloat(const char* key, const float_t value) { + return putBytes(key, (void*)&value, sizeof(float_t)); +} + +size_t Preferences::putDouble(const char* key, const double_t value) { + return putBytes(key, (void*)&value, sizeof(double_t)); +} + +size_t Preferences::putBool(const char* key, const bool value) { + return putUChar(key, (uint8_t) (value ? 1 : 0)); +} + +size_t Preferences::putString(const char* key, const char* value) { + string res = ""; + if (key != nullptr && strlen(key) > 0 && value != nullptr && strlen(value) > 0) { + if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%s\r\n", CMD_WRITE(_PREF_PUT), key, PT_STR, value)) { + return atoi(res.c_str()); + } + } + return 0; +} + +size_t Preferences::putString(const char* key, const String value) { + return putString(key, value.c_str()); +} + +size_t Preferences::putBytes(const char* key, const void* value, size_t len) { + string res = ""; + if ( key != nullptr && strlen(key) > 0 && value != nullptr && len > 0) { + modem.write_nowait(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%d\r\n", CMD_WRITE(_PREF_PUT), key, PT_BLOB, len); + if(modem.passthrough((uint8_t *)value, len)) { + return len; + } + } + return 0; +} + +PreferenceType Preferences::getType(const char* key) { + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s\r\n", CMD_WRITE(_PREF_PUT), key)) { + return static_cast(atoi(res.c_str())); + } + } + return PT_INVALID; +} + +bool Preferences::isKey(const char* key) { + return getType(key) != PT_INVALID; +} + +/* + * Get a key value + * */ + +int8_t Preferences::getChar(const char* key, const int8_t defaultValue) { + int8_t value = defaultValue; + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%hhd\r\n", CMD_WRITE(_PREF_GET), key, PT_I8, defaultValue)) { + sscanf(res.c_str(), "%hhd", &value); + } + } + return value; +} + +uint8_t Preferences::getUChar(const char* key, const uint8_t defaultValue) { + uint8_t value = defaultValue; + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%hhu\r\n", CMD_WRITE(_PREF_GET), key, PT_U8, defaultValue)) { + sscanf(res.c_str(), "%hhu", &value); + } + } + return value; +} + +int16_t Preferences::getShort(const char* key, const int16_t defaultValue) { + int16_t value = defaultValue; + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%hd\r\n", CMD_WRITE(_PREF_GET), key, PT_I16, defaultValue)) { + sscanf(res.c_str(), "%hd", &value); + } + } + return value; +} + +uint16_t Preferences::getUShort(const char* key, const uint16_t defaultValue) { + uint16_t value = defaultValue; + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%hu\r\n", CMD_WRITE(_PREF_GET), key, PT_U16, defaultValue)) { + sscanf(res.c_str(), "%hu", &value); + } + } + return value; +} + +int32_t Preferences::getInt(const char* key, const int32_t defaultValue) { + int32_t value = defaultValue; + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%d\r\n", CMD_WRITE(_PREF_GET), key, PT_I32, defaultValue)) { + sscanf(res.c_str(), "%d", &value); + } + } + return value; +} + +uint32_t Preferences::getUInt(const char* key, const uint32_t defaultValue) { + uint32_t value = defaultValue; + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%u\r\n", CMD_WRITE(_PREF_GET), key, PT_U32, defaultValue)) { + sscanf(res.c_str(), "%u", &value); + } + } + return value; +} + +int32_t Preferences::getLong(const char* key, const int32_t defaultValue) { + return getInt(key, defaultValue); +} + +uint32_t Preferences::getULong(const char* key, const uint32_t defaultValue) { + return getUInt(key, defaultValue); +} + +int64_t Preferences::getLong64(const char* key, const int64_t defaultValue) { + int64_t value = defaultValue; + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%lld\r\n", CMD_WRITE(_PREF_GET), key, PT_I64, defaultValue)) { + sscanf(res.c_str(), "%lld", &value); + } + } + return value; +} + +uint64_t Preferences::getULong64(const char* key, const uint64_t defaultValue) { + uint64_t value = defaultValue; + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%llu\r\n", CMD_WRITE(_PREF_GET), key, PT_U64, defaultValue)) { + sscanf(res.c_str(), "%llu", &value); + } + } + return value; +} + +float_t Preferences::getFloat(const char* key, const float_t defaultValue) { + float_t value = defaultValue; + getBytes(key, (void*) &value, sizeof(float_t)); + return value; +} + +double_t Preferences::getDouble(const char* key, const double_t defaultValue) { + double_t value = defaultValue; + getBytes(key, (void*) &value, sizeof(double_t)); + return value; +} + +bool Preferences::getBool(const char* key, const bool defaultValue) { + return getUChar(key, defaultValue ? 1 : 0) == 1; +} + +size_t Preferences::getString(const char* key, char* value, const size_t maxLen) { + string res = ""; + if (key != nullptr && strlen(key) > 0 && value != nullptr) { + if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d\r\n", CMD_WRITE(_PREF_GET), key, PT_STR)) { + if (res.length() < maxLen) { + strncpy(value, res.c_str(), res.length()); + return res.length(); + } + } + } + return 0; +} + +String Preferences::getString(const char* key, const String defaultValue) { + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%s\r\n", CMD_WRITE(_PREF_GET), key, PT_STR, defaultValue.c_str())) { + return String(res.c_str()); + } + } + return defaultValue; +} + +size_t Preferences::getBytesLength(const char* key) { + string res = ""; + if (key != nullptr && strlen(key) > 0) { + if (modem.write(string(PROMPT(_PREF_LEN)), res, "%s%s\r\n", CMD_WRITE(_PREF_LEN), key)) { + return atoi(res.c_str()); + } + } + return 0; +} + +size_t Preferences::getBytes(const char* key, void * buf, size_t maxLen) { + size_t len = getBytesLength(key); + string res = ""; + if (key != nullptr && strlen(key) > 0 && buf != nullptr && len > 0) { + modem.avoid_trim_results(); + modem.read_using_size(); + if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d\r\n", CMD_WRITE(_PREF_GET), key, PT_BLOB)) { + if (res.size() >= len && len <= maxLen) { + memcpy(buf, (uint8_t*)&res[0], len); + } + } + } + return 0; +} + +size_t Preferences::freeEntries() { + string res = ""; + if (modem.write(string(PROMPT(_PREF_STAT)), res, "%s\r\n", CMD(_PREF_STAT))) { + return atoi(res.c_str()); + } + return 0; +} diff --git a/libraries/Preferences/src/Preferences.h b/libraries/Preferences/src/Preferences.h new file mode 100644 index 000000000..a4f762235 --- /dev/null +++ b/libraries/Preferences/src/Preferences.h @@ -0,0 +1,70 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _PREFERENCES_H_ +#define _PREFERENCES_H_ + +#include "Arduino.h" +#include "Modem.h" + +typedef enum { + PT_I8, PT_U8, PT_I16, PT_U16, PT_I32, PT_U32, PT_I64, PT_U64, PT_STR, PT_BLOB, PT_INVALID +} PreferenceType; + +class Preferences { +public: + Preferences(); + ~Preferences(); + bool begin(const char * name, bool readOnly=false, const char* partition_label=NULL); + void end(); + bool clear(); + bool remove(const char * key); + size_t putChar(const char* key, int8_t value); + size_t putUChar(const char* key, uint8_t value); + size_t putShort(const char* key, int16_t value); + size_t putUShort(const char* key, uint16_t value); + size_t putInt(const char* key, int32_t value); + size_t putUInt(const char* key, uint32_t value); + size_t putLong(const char* key, int32_t value); + size_t putULong(const char* key, uint32_t value); + size_t putLong64(const char* key, int64_t value); + size_t putULong64(const char* key, uint64_t value); + size_t putFloat(const char* key, float_t value); + size_t putDouble(const char* key, double_t value); + size_t putBool(const char* key, bool value); + size_t putString(const char* key, const char* value); + size_t putString(const char* key, String value); + size_t putBytes(const char* key, const void* value, size_t len); + bool isKey(const char* key); + PreferenceType getType(const char* key); + int8_t getChar(const char* key, int8_t defaultValue = 0); + uint8_t getUChar(const char* key, uint8_t defaultValue = 0); + int16_t getShort(const char* key, int16_t defaultValue = 0); + uint16_t getUShort(const char* key, uint16_t defaultValue = 0); + int32_t getInt(const char* key, int32_t defaultValue = 0); + uint32_t getUInt(const char* key, uint32_t defaultValue = 0); + int32_t getLong(const char* key, int32_t defaultValue = 0); + uint32_t getULong(const char* key, uint32_t defaultValue = 0); + int64_t getLong64(const char* key, int64_t defaultValue = 0); + uint64_t getULong64(const char* key, uint64_t defaultValue = 0); + float_t getFloat(const char* key, float_t defaultValue = NAN); + double_t getDouble(const char* key, double_t defaultValue = NAN); + bool getBool(const char* key, bool defaultValue = false); + size_t getString(const char* key, char* value, size_t maxLen); + String getString(const char* key, String defaultValue = String()); + size_t getBytesLength(const char* key); + size_t getBytes(const char* key, void * buf, size_t maxLen); + size_t freeEntries(); +}; + +#endif From 15827d698891467a6d5de89b2439c0617999711b Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 5 Jan 2024 10:31:51 +0100 Subject: [PATCH 04/33] Remove hhd and hhu format specifiers because they are not supported by newlib-nano --- libraries/Preferences/src/Preferences.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/libraries/Preferences/src/Preferences.cpp b/libraries/Preferences/src/Preferences.cpp index e827a8db7..067394ece 100644 --- a/libraries/Preferences/src/Preferences.cpp +++ b/libraries/Preferences/src/Preferences.cpp @@ -28,6 +28,7 @@ Preferences::~Preferences() { bool Preferences::begin(const char * name, bool readOnly, const char* partition_label){ string res = ""; modem.begin(); + modem.debug(Serial,2); if (name != nullptr && strlen(name) > 0) { if (modem.write(string(PROMPT(_PREF_BEGIN)), res, "%s%s,%d,%s\r\n", CMD_WRITE(_PREF_BEGIN), name, readOnly, partition_label != NULL ? partition_label : "")) { return (atoi(res.c_str()) != 0) ? true : false; @@ -74,7 +75,7 @@ bool Preferences::remove(const char * key) { size_t Preferences::putChar(const char* key, int8_t value) { string res = ""; if (key != nullptr && strlen(key) > 0) { - if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%hhd\r\n", CMD_WRITE(_PREF_PUT), key, PT_I8, value)) { + if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%hd\r\n", CMD_WRITE(_PREF_PUT), key, PT_I8, value)) { return atoi(res.c_str()); } } @@ -84,7 +85,7 @@ size_t Preferences::putChar(const char* key, int8_t value) { size_t Preferences::putUChar(const char* key, uint8_t value) { string res = ""; if (key != nullptr && strlen(key) > 0) { - if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%hhu\r\n", CMD_WRITE(_PREF_PUT), key, PT_U8, value)) { + if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%hu\r\n", CMD_WRITE(_PREF_PUT), key, PT_U8, value)) { return atoi(res.c_str()); } } @@ -215,22 +216,22 @@ bool Preferences::isKey(const char* key) { * */ int8_t Preferences::getChar(const char* key, const int8_t defaultValue) { - int8_t value = defaultValue; + int16_t value = defaultValue; string res = ""; if (key != nullptr && strlen(key) > 0) { - if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%hhd\r\n", CMD_WRITE(_PREF_GET), key, PT_I8, defaultValue)) { - sscanf(res.c_str(), "%hhd", &value); + if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%hd\r\n", CMD_WRITE(_PREF_GET), key, PT_I8, defaultValue)) { + sscanf(res.c_str(), "%hd", &value); } } return value; } uint8_t Preferences::getUChar(const char* key, const uint8_t defaultValue) { - uint8_t value = defaultValue; + uint16_t value = defaultValue; string res = ""; if (key != nullptr && strlen(key) > 0) { - if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%hhu\r\n", CMD_WRITE(_PREF_GET), key, PT_U8, defaultValue)) { - sscanf(res.c_str(), "%hhu", &value); + if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%hu\r\n", CMD_WRITE(_PREF_GET), key, PT_U8, defaultValue)) { + sscanf(res.c_str(), "%hu", &value); } } return value; From fbe81e275a74a00c9f03573e2d532705e481a305 Mon Sep 17 00:00:00 2001 From: pennam Date: Mon, 8 Jan 2024 17:31:31 +0100 Subject: [PATCH 05/33] Fix put/get Long64 ULong64 by using putBytes instead of printf format specifiers --- libraries/Preferences/src/Preferences.cpp | 30 +++-------------------- 1 file changed, 4 insertions(+), 26 deletions(-) diff --git a/libraries/Preferences/src/Preferences.cpp b/libraries/Preferences/src/Preferences.cpp index 067394ece..6d1c27d2c 100644 --- a/libraries/Preferences/src/Preferences.cpp +++ b/libraries/Preferences/src/Preferences.cpp @@ -141,23 +141,11 @@ size_t Preferences::putULong(const char* key, uint32_t value) { } size_t Preferences::putLong64(const char* key, int64_t value) { - string res = ""; - if (key != nullptr && strlen(key) > 0) { - if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%lld\r\n", CMD_WRITE(_PREF_PUT), key, PT_I64, value)) { - return atoi(res.c_str()); - } - } - return 0; + return putBytes(key, (void*)&value, sizeof(int64_t)); } size_t Preferences::putULong64(const char* key, uint64_t value) { - string res = ""; - if (key != nullptr && strlen(key) > 0) { - if (modem.write(string(PROMPT(_PREF_PUT)), res, "%s%s,%d,%llu\r\n", CMD_WRITE(_PREF_PUT), key, PT_U64, value)) { - return atoi(res.c_str()); - } - } - return 0; + return putBytes(key, (void*)&value, sizeof(uint64_t)); } size_t Preferences::putFloat(const char* key, const float_t value) { @@ -291,23 +279,13 @@ uint32_t Preferences::getULong(const char* key, const uint32_t defaultValue) { int64_t Preferences::getLong64(const char* key, const int64_t defaultValue) { int64_t value = defaultValue; - string res = ""; - if (key != nullptr && strlen(key) > 0) { - if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%lld\r\n", CMD_WRITE(_PREF_GET), key, PT_I64, defaultValue)) { - sscanf(res.c_str(), "%lld", &value); - } - } + getBytes(key, (void*) &value, sizeof(int64_t)); return value; } uint64_t Preferences::getULong64(const char* key, const uint64_t defaultValue) { uint64_t value = defaultValue; - string res = ""; - if (key != nullptr && strlen(key) > 0) { - if (modem.write(string(PROMPT(_PREF_GET)), res, "%s%s,%d,%llu\r\n", CMD_WRITE(_PREF_GET), key, PT_U64, defaultValue)) { - sscanf(res.c_str(), "%llu", &value); - } - } + getBytes(key, (void*) &value, sizeof(uint64_t)); return value; } From f8cfac12eefc37496aaefabd77fac51ec0210962 Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 12 Jan 2024 11:06:45 +0100 Subject: [PATCH 06/33] Preferences: remove modem debug --- libraries/Preferences/src/Preferences.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/Preferences/src/Preferences.cpp b/libraries/Preferences/src/Preferences.cpp index 6d1c27d2c..dd5a9f677 100644 --- a/libraries/Preferences/src/Preferences.cpp +++ b/libraries/Preferences/src/Preferences.cpp @@ -28,7 +28,6 @@ Preferences::~Preferences() { bool Preferences::begin(const char * name, bool readOnly, const char* partition_label){ string res = ""; modem.begin(); - modem.debug(Serial,2); if (name != nullptr && strlen(name) > 0) { if (modem.write(string(PROMPT(_PREF_BEGIN)), res, "%s%s,%d,%s\r\n", CMD_WRITE(_PREF_BEGIN), name, readOnly, partition_label != NULL ? partition_label : "")) { return (atoi(res.c_str()) != 0) ? true : false; From 83f6d7b6eeef819c045fdfffd591ec7161fdd5ef Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 12 Jan 2024 11:06:54 +0100 Subject: [PATCH 07/33] Preferences: fix RUN commands --- libraries/Preferences/src/Preferences.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/Preferences/src/Preferences.cpp b/libraries/Preferences/src/Preferences.cpp index dd5a9f677..9bdac4887 100644 --- a/libraries/Preferences/src/Preferences.cpp +++ b/libraries/Preferences/src/Preferences.cpp @@ -38,7 +38,7 @@ bool Preferences::begin(const char * name, bool readOnly, const char* partition_ void Preferences::end() { string res = ""; - modem.write(string(PROMPT(_PREF_END)), res, "%s\r\n", CMD(_PREF_END)); + modem.write(string(PROMPT(_PREF_END)), res, "%s", CMD(_PREF_END)); } /* @@ -47,7 +47,7 @@ void Preferences::end() { bool Preferences::clear() { string res = ""; - if (modem.write(string(PROMPT(_PREF_CLEAR)), res, "%s\r\n", CMD(_PREF_CLEAR))) { + if (modem.write(string(PROMPT(_PREF_CLEAR)), res, "%s", CMD(_PREF_CLEAR))) { return (atoi(res.c_str()) != 0) ? true : false; } return false; @@ -354,7 +354,7 @@ size_t Preferences::getBytes(const char* key, void * buf, size_t maxLen) { size_t Preferences::freeEntries() { string res = ""; - if (modem.write(string(PROMPT(_PREF_STAT)), res, "%s\r\n", CMD(_PREF_STAT))) { + if (modem.write(string(PROMPT(_PREF_STAT)), res, "%s", CMD(_PREF_STAT))) { return atoi(res.c_str()); } return 0; From b6508c32a82143c5a829c14e8a93f7955c283ac3 Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 12 Jan 2024 11:07:39 +0100 Subject: [PATCH 08/33] Preferences examples: add begin return value check - This library works only if WiFi firmware version is greater than 0.3.0 --- .../Preferences/examples/Prefs2Struct/Prefs2Struct.ino | 6 +++++- .../Preferences/examples/StartCounter/StartCounter.ino | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino b/libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino index 4976ca936..7ac44c9bc 100644 --- a/libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino +++ b/libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino @@ -17,7 +17,11 @@ typedef struct { void setup() { Serial.begin(115200); - prefs.begin("schedule"); // use "schedule" namespace + if (!prefs.begin("schedule")) { // use "schedule" namespace + Serial.println("Cannot initialize preferences"); + Serial.println("Make sure your WiFi firmware version is greater than 0.3.0"); + while(1) {}; + } uint8_t content[] = {9, 30, 235, 255, 20, 15, 0, 1}; // two entries prefs.putBytes("schedule", content, sizeof(content)); size_t schLen = prefs.getBytesLength("schedule"); diff --git a/libraries/Preferences/examples/StartCounter/StartCounter.ino b/libraries/Preferences/examples/StartCounter/StartCounter.ino index 85d47510d..77de2c8f5 100644 --- a/libraries/Preferences/examples/StartCounter/StartCounter.ino +++ b/libraries/Preferences/examples/StartCounter/StartCounter.ino @@ -21,8 +21,11 @@ void setup() { // has to use a namespace name to prevent key name collisions. We will open storage in // RW-mode (second parameter has to be false). // Note: Namespace name is limited to 15 chars. - int ret = preferences.begin("my-app", false); - Serial.println(ret); + if (!preferences.begin("my-app", false)) { + Serial.println("Cannot initialize preferences"); + Serial.println("Make sure your WiFi firmware version is greater than 0.3.0"); + while(1) {}; + } // Remove all preferences under the opened namespace //preferences.clear(); From db70d23072d3ab73391a41dc2ae0d64193d94db0 Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 12 Jan 2024 11:50:59 +0100 Subject: [PATCH 09/33] Preferences examples: add newline --- libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino b/libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino index 7ac44c9bc..b8cc4dab6 100644 --- a/libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino +++ b/libraries/Preferences/examples/Prefs2Struct/Prefs2Struct.ino @@ -39,6 +39,7 @@ void setup() { Serial.print(schedule[1].setting1); Serial.print("/"); Serial.print(schedule[1].setting2); + Serial.println(); schedule[2] = {8, 30, 20, 21}; // add a third entry (unsafely) From e85618159426c2f8cc5795a4ea142df9b7bb8766 Mon Sep 17 00:00:00 2001 From: Johannes Winkler Date: Tue, 9 Jan 2024 10:46:03 +0100 Subject: [PATCH 10/33] Add AES encrypt/decrypt support for SE05X on Arduino with two example sketches. --- .../SE05XAESEncryptandDecrypt.ino | 56 +++++++++++++++++++ .../SE05XAESWriteKey/SE05XAESWriteKey.ino | 33 +++++++++++ libraries/SE05X/src/SE05X.cpp | 51 +++++++++++++++++ libraries/SE05X/src/SE05X.h | 40 +++++++++++++ 4 files changed, 180 insertions(+) create mode 100644 libraries/SE05X/examples/SE05XAESEncryptandDecrypt/SE05XAESEncryptandDecrypt.ino create mode 100644 libraries/SE05X/examples/SE05XAESWriteKey/SE05XAESWriteKey.ino diff --git a/libraries/SE05X/examples/SE05XAESEncryptandDecrypt/SE05XAESEncryptandDecrypt.ino b/libraries/SE05X/examples/SE05XAESEncryptandDecrypt/SE05XAESEncryptandDecrypt.ino new file mode 100644 index 000000000..e163f7d85 --- /dev/null +++ b/libraries/SE05X/examples/SE05XAESEncryptandDecrypt/SE05XAESEncryptandDecrypt.ino @@ -0,0 +1,56 @@ +/* + SE05X AES Encrypt and Decrypt + + This sketch uses the SE05X to encrypt and decrypt given data + with an AES key, which was uploaded in the SE05XWriteAESKey + example. This sketch encrypts 32 bytes with AES ECB Mode + and then decrypt this data for comparing the results. + + Circuit: + - Portenta C33 +*/ + +#include + + +const int AES_KEY_ID = 666; +const byte data[32] = { + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f +}; + + +void print_hex(const byte in[], size_t len) { + for (size_t i = 0; i < len; i++) { + Serial.print(in[i] >> 4, HEX); + Serial.print(in[i] & 0x0f, HEX); + } + Serial.println(); +} + +void setup() { + Serial.begin(9600); + while (!Serial); + + + if (!SE05X.begin()) { + Serial.println("Error with secure element"); + while(1); + } + + + size_t encrypted_data_len = 32; + size_t decrypted_data_len = 32; + byte encrypted_data[32]; + byte decrypted_data[32]; + + int status1 = SE05X.AES_ECB_encrypt(AES_KEY_ID, data, sizeof(data), encrypted_data, &encrypted_data_len); + int status2 = SE05X.AES_ECB_decrypt(AES_KEY_ID, encrypted_data, sizeof(data), decrypted_data, &decrypted_data_len); + print_hex(data,32); + print_hex(encrypted_data,32); + print_hex(decrypted_data,32); +} + +void loop() { + +} \ No newline at end of file diff --git a/libraries/SE05X/examples/SE05XAESWriteKey/SE05XAESWriteKey.ino b/libraries/SE05X/examples/SE05XAESWriteKey/SE05XAESWriteKey.ino new file mode 100644 index 000000000..b17e8aaa1 --- /dev/null +++ b/libraries/SE05X/examples/SE05XAESWriteKey/SE05XAESWriteKey.ino @@ -0,0 +1,33 @@ +/* + SE05X WriteAESKey + + This sketch uses the SE05X to securely store an AES key. When the key is uploaded to + SE05X, the sketch on the Arduino should be overwritten. + + Circuit: + - Portenta C33 +*/ + +#include + +const int AES_KEY_ID = 666; +const byte aes_key[32] = { + 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0x33, 0x33, 0xFF, 0x33, + 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0xFF, 0x33, 0x33, 0x33, 0xFF, 0x44 +}; + +void setup() { + Serial.begin(9600); + + if (!SE05X.begin()) { + Serial.println("Error with secure element"); + while(1); + } + + SE05X.deleteBinaryObject(AES_KEY_ID); + SE05X.writeAESKey(AES_KEY_ID, aes_key, sizeof(aes_key)); +} + +void loop() { + +} diff --git a/libraries/SE05X/src/SE05X.cpp b/libraries/SE05X/src/SE05X.cpp index 30e82e93c..b70164637 100644 --- a/libraries/SE05X/src/SE05X.cpp +++ b/libraries/SE05X/src/SE05X.cpp @@ -595,6 +595,57 @@ int SE05XClass::readSlot(int slot, byte data[], int length) return readBinaryObject(slot, data, length, &size); } +int SE05XClass::AES_ECB_encrypt(int objectId, const byte data[], size_t data_length, byte output[], size_t *output_len) +{ + smStatus_t status; + status = Se05x_API_CipherOneShot(&_se05x_session, objectId, kSE05x_CipherMode_AES_ECB_NOPAD, data, data_length, 0, 0, output, output_len, kSE05x_Cipher_Oper_OneShot_Encrypt); + if (status != SM_OK) { + SMLOG_E("Error in Se05x_API_CipherOneShot \n"); + return 0; + } + return 1; +} + +int SE05XClass::AES_ECB_decrypt(int objectId, const byte data[], size_t data_length, byte output[], size_t *output_len) +{ + smStatus_t status; + status = Se05x_API_CipherOneShot(&_se05x_session, objectId, kSE05x_CipherMode_AES_ECB_NOPAD, data, data_length, 0, 0, output, output_len, kSE05x_Cipher_Oper_OneShot_Decrypt); + if (status != SM_OK) { + SMLOG_E("Error in Se05x_API_CipherOneShot \n"); + return 0; + } + return 1; +} + +int SE05XClass::writeAESKey(int objectId, const byte data[], size_t length) +{ + smStatus_t status; + SE05x_Result_t result; + uint16_t offset = 0; + uint16_t size; + + status = Se05x_API_CheckObjectExists(&_se05x_session, objectId, &result); + if (status != SM_OK) { + SMLOG_E("Error in Se05x_API_CheckObjectExists \n"); + return 0; + } + + if (result == kSE05x_Result_SUCCESS) { + SMLOG_E("Object exists \n"); + return 0; + } + + uint16_t left = length; + + status = Se05x_API_WriteSymmKey(&_se05x_session, NULL, 3, objectId, NULL, data, length, kSE05x_INS_NA, kSE05x_SymmKeyType_AES); + + if (status != SM_OK) { + SMLOG_E("Error in Se05x_API_WriteSymmKey \n"); + return 0; + } + return 1; +} + int SE05XClass::writeBinaryObject(int objectId, const byte data[], size_t length) { smStatus_t status; diff --git a/libraries/SE05X/src/SE05X.h b/libraries/SE05X/src/SE05X.h index 149414b0f..0754680e2 100644 --- a/libraries/SE05X/src/SE05X.h +++ b/libraries/SE05X/src/SE05X.h @@ -194,6 +194,46 @@ class SE05XClass */ int readBinaryObject(int ObjectId, byte data[], size_t dataMaxLen, size_t* length); + /** AES_ECB_encrypt + * + * Enrypts something with AES ECB + * + * @param[in] ObjectId SE050 object ID + * @param[in] data Input data buffer + * @param[in] length Input data buffer size (should be a multiple of 16 bytes) + * @param[out] output Output data buffer + * @param[out] output_length Output data buffer size (same as input) + * + * @return 0 on Failure 1 on Success + */ + int AES_ECB_encrypt(int objectId, const byte data[], size_t data_length, byte output[], size_t *output_len); + + /** AES_ECB_decrypt + * + * Enrypts something with AES ECB + * + * @param[in] ObjectId SE050 object ID + * @param[in] data Input data buffer + * @param[in] length Input data buffer size (should be a multiple of 16 bytes) + * @param[out] output Output data buffer + * @param[out] output_length Output data buffer size (same as input) + * + * @return 0 on Failure 1 on Success + */ + int AES_ECB_decrypt(int objectId, const byte data[], size_t data_length, byte output[], size_t *output_len); + + /** writeAESKey + * + * Writes symmetric key into SE050 object. + * + * @param[in] ObjectId SE050 object ID + * @param[in] data Input data buffer + * @param[in] length Input data buffer size + * + * @return 0 on Failure 1 on Success + */ + int writeAESKey(int ObjectId, const byte data[], size_t length); + /** writeBinaryObject * * Writes binary data into SE050 object. From 432b075f67303b9253b1106fa3aa51e3f3fb77ee Mon Sep 17 00:00:00 2001 From: Johannes Winkler Date: Tue, 16 Jan 2024 11:18:41 +0100 Subject: [PATCH 11/33] Add HMAC Generation with SE05X with Arduino --- .../SE05X/examples/SE05XHMAC/SE05XHMAC.ino | 54 +++++++++++++ libraries/SE05X/src/SE05X.cpp | 42 +++++++++- libraries/SE05X/src/SE05X.h | 28 +++++++ .../SE05X/src/lib/apdu/se05x_APDU_apis.h | 78 +++++++++++++++++++ .../SE05X/src/lib/apdu/se05x_APDU_impl.c | 56 +++++++++++++ libraries/SE05X/src/lib/apdu/se05x_types.h | 2 + 6 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 libraries/SE05X/examples/SE05XHMAC/SE05XHMAC.ino diff --git a/libraries/SE05X/examples/SE05XHMAC/SE05XHMAC.ino b/libraries/SE05X/examples/SE05XHMAC/SE05XHMAC.ino new file mode 100644 index 000000000..31dba3818 --- /dev/null +++ b/libraries/SE05X/examples/SE05XHMAC/SE05XHMAC.ino @@ -0,0 +1,54 @@ +/* + SE05X HMAC + + This sketch uses the SE05X to securely store and use an HMAC Key + and calculates the HMAC-SHA512 sum of a given message + + Circuit: + - Portenta C33 +*/ + +#include + +const int HMAC_KEY_ID = 667; +const byte hmac_key[32] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + + +void print_hex(const byte in[], size_t len) { + for (size_t i = 0; i < len; i++) { + Serial.print(in[i] >> 4, HEX); + Serial.print(in[i] & 0x0f, HEX); + } + Serial.println(); +} + +void setup() { + Serial.begin(9600); + while (!Serial); + + if (!SE05X.begin()) { + Serial.println("Error with secure element"); + while(1); + } + + SE05X.deleteBinaryObject(HMAC_KEY_ID); //remove key if already exists + + SE05X.writeHMACKey(HMAC_KEY_ID, hmac_key, sizeof(hmac_key)); + String message = "This is a test for the Arduino Portenta C33 to test HMAC with SHA512 algorithm. This are some bytes of data, which should work"; + + + byte buffer[64]; + for(int i = 0; i < 64; i++) + buffer[i] = 0; + + size_t len = 64; // 64 byte = 512 bit, length for SHA512 + SE05X.HMAC_Generate(HMAC_KEY_ID, kSE05x_MACAlgo_HMAC_SHA512, (const byte*)message.c_str(), message.length(), buffer, &len); + print_hex(buffer,len); +} + +void loop() { + +} diff --git a/libraries/SE05X/src/SE05X.cpp b/libraries/SE05X/src/SE05X.cpp index b70164637..438016650 100644 --- a/libraries/SE05X/src/SE05X.cpp +++ b/libraries/SE05X/src/SE05X.cpp @@ -646,6 +646,46 @@ int SE05XClass::writeAESKey(int objectId, const byte data[], size_t length) return 1; } +int SE05XClass::writeHMACKey(int objectId, const byte data[], size_t length) +{ + smStatus_t status; + SE05x_Result_t result; + uint8_t exists = 0; + uint16_t offset = 0; + uint16_t size; + + status = Se05x_API_CheckObjectExists(&_se05x_session, objectId, &result); + if (status != SM_OK) { + SMLOG_E("Error in Se05x_API_CheckObjectExists \n"); + return 0; + } + + if (result == kSE05x_Result_SUCCESS) { + SMLOG_E("Object exists \n"); + exists = 1; + } + + status = Se05x_API_WriteSymmKey(&_se05x_session, NULL, 0, objectId, SE05x_KeyID_KEK_NONE, data, length, kSE05x_INS_NA, kSE05x_SymmKeyType_HMAC); + + if (status != SM_OK) { + SMLOG_E("Error in Se05x_API_WriteSymmKey \n"); + return 0; + } + return 1; +} + +int SE05XClass::HMAC_Generate(int objectId, uint8_t mac_operation, const byte data[], size_t data_length, byte output[], size_t *output_len) +{ + smStatus_t status; + status = Se05x_API_MACOneShot_G(&_se05x_session, objectId, mac_operation, data, data_length, output, output_len); + + if (status != SM_OK) { + SMLOG_E("Error in Se05x_API_CipherOneShot \n"); + return status; + } + return 1; +} + int SE05XClass::writeBinaryObject(int objectId, const byte data[], size_t length) { smStatus_t status; @@ -719,7 +759,7 @@ int SE05XClass::deleteBinaryObject(int objectId) status = Se05x_API_DeleteSecureObject(&_se05x_session, objectId); if (status != SM_OK) { - SMLOG_E("Error in Se05x_API_CheckObjectExists \n"); + SMLOG_E("Error in Se05x_API_DeleteSecureObject \n"); return 0; } diff --git a/libraries/SE05X/src/SE05X.h b/libraries/SE05X/src/SE05X.h index 0754680e2..0ed95a60b 100644 --- a/libraries/SE05X/src/SE05X.h +++ b/libraries/SE05X/src/SE05X.h @@ -234,6 +234,34 @@ class SE05XClass */ int writeAESKey(int ObjectId, const byte data[], size_t length); + /** writeHMACKey + * + * Writes symmetric key into SE050 object. + * + * @param[in] ObjectId SE050 object ID for the hmac key + * @param[in] data Input data buffer + * @param[in] length Input data buffer size + * + * @return 0 on Failure 1 on Success + */ + int writeHMACKey(int ObjectId, const byte data[], size_t length); + + /** HMAC_Generate + * + * Computes the HMAC digest with SE050 chip + * + * @param[in] objectId SE050 object ID for the hmac key + * @param[in] mac_operation Type of Hash function for HMAC + * @param[in] data Input data buffer + * @param[in] length Input data buffer size + * @param[out] output Output data buffer + * @param[out] output_length Output data buffer size (should be 32 bytes for SHA256) + * + * @return 0 on Failure 1 on Success + */ + int HMAC_Generate(int objectId, uint8_t mac_operation, const byte data[], size_t data_length, byte output[], size_t *output_len); + + /** writeBinaryObject * * Writes binary data into SE050 object. diff --git a/libraries/SE05X/src/lib/apdu/se05x_APDU_apis.h b/libraries/SE05X/src/lib/apdu/se05x_APDU_apis.h index 2550d6e51..cb4c70976 100644 --- a/libraries/SE05X/src/lib/apdu/se05x_APDU_apis.h +++ b/libraries/SE05X/src/lib/apdu/se05x_APDU_apis.h @@ -1104,6 +1104,84 @@ smStatus_t Se05x_API_DigestOneShot(pSe05xSession_t session_ctx, uint8_t *hashValue, size_t *phashValueLen); + +/** Se05x_API_MACOneShot_G + * + * Generate. See @ref Se05x_API_MACOneShot_V for Verfiication. + * + * Performs a MAC operation in one shot (without keeping state). + * + * The 4-byte identifier of the key must refer to an AESKey, DESKey or HMACKey. + * + * # Command to Applet + * + * @rst + * +---------+------------------------+---------------------------------------------+ + * | Field | Value | Description | + * +=========+========================+=============================================+ + * | CLA | 0x80 | | + * +---------+------------------------+---------------------------------------------+ + * | INS | INS_CRYPTO | :cpp:type:`SE05x_INS_t` | + * +---------+------------------------+---------------------------------------------+ + * | P1 | P1_MAC | See :cpp:type:`SE05x_P1_t` | + * +---------+------------------------+---------------------------------------------+ + * | P2 | P2_GENERATE_ONESHOT or | See :cpp:type:`SE05x_P2_t` | + * | | P2_VALIDATE_ONESHOT | | + * +---------+------------------------+---------------------------------------------+ + * | Lc | #(Payload) | | + * +---------+------------------------+---------------------------------------------+ + * | Payload | TLV[TAG_1] | 4-byte identifier of the key object. | + * +---------+------------------------+---------------------------------------------+ + * | | TLV[TAG_2] | 1-byte :cpp:type:`MACAlgoRef` | + * +---------+------------------------+---------------------------------------------+ + * | | TLV[TAG_3] | Byte array containing data to be taken as | + * | | | input to MAC. | + * +---------+------------------------+---------------------------------------------+ + * | | TLV[TAG_5] | MAC to verify (when P2=P2_VALIDATE_ONESHOT) | + * +---------+------------------------+---------------------------------------------+ + * | Le | 0x00 | Expecting MAC or Result. | + * +---------+------------------------+---------------------------------------------+ + * @endrst + * + * # R-APDU Body + * + * @rst + * +------------+---------------------------------------+ + * | Value | Description | + * +============+=======================================+ + * | TLV[TAG_1] | MAC value (P2=P2_GENERATE_ONESHOT) or | + * | | :cpp:type:`SE05x_Result_t` (when | + * | | p2=P2_VALIDATE_ONESHOT). | + * +------------+---------------------------------------+ + * @endrst + * + * # R-APDU Trailer + * + * @rst + * +-------------+--------------------------------------+ + * | SW | Description | + * +=============+======================================+ + * | SW_NO_ERROR | The command is handled successfully. | + * +-------------+--------------------------------------+ + * @endrst + * + * @param[in] session_ctx Session Context [0:kSE05x_pSession] + * @param[in] objectID objectID [1:kSE05x_TAG_1] + * @param[in] macOperation macOperation [2:kSE05x_TAG_2] + * @param[in] inputData inputData [3:kSE05x_TAG_3] + * @param[in] inputDataLen Length of inputData + * @param[out] macValue [0:kSE05x_TAG_1] + * @param[in,out] pmacValueLen Length for macValue + */ +smStatus_t Se05x_API_MACOneShot_G(pSe05xSession_t session_ctx, + uint32_t objectID, + uint8_t macOperation, + const uint8_t *inputData, + size_t inputDataLen, + uint8_t *macValue, + size_t *pmacValueLen); + + /** Se05x_API_CreateCryptoObject * * Creates a Crypto Object on the SE05X . Once the Crypto Object is created, it diff --git a/libraries/SE05X/src/lib/apdu/se05x_APDU_impl.c b/libraries/SE05X/src/lib/apdu/se05x_APDU_impl.c index 3de6bd422..344df1e97 100644 --- a/libraries/SE05X/src/lib/apdu/se05x_APDU_impl.c +++ b/libraries/SE05X/src/lib/apdu/se05x_APDU_impl.c @@ -854,6 +854,62 @@ smStatus_t Se05x_API_DigestOneShot(pSe05xSession_t session_ctx, return retStatus; } + +smStatus_t Se05x_API_MACOneShot_G(pSe05xSession_t session_ctx, + uint32_t objectID, + uint8_t macOperation, + const uint8_t *inputData, + size_t inputDataLen, + uint8_t *macValue, + size_t *pmacValueLen) +{ + smStatus_t retStatus = SM_NOT_OK; + tlvHeader_t hdr = {{kSE05x_CLA, kSE05x_INS_CRYPTO, kSE05x_P1_MAC, kSE05x_P2_GENERATE_ONESHOT}}; + size_t cmdbufLen = 0; + uint8_t *pCmdbuf = NULL; + int tlvRet = 0; + uint8_t *pRspbuf = NULL; + size_t rspbufLen = 0; + + ENSURE_OR_GO_CLEANUP(session_ctx != NULL); + + SMLOG_D("APDU - Se05x_API_MACOneShot_G [] \n"); + + pCmdbuf = &session_ctx->apdu_buffer[0]; + pRspbuf = &session_ctx->apdu_buffer[0]; + rspbufLen = sizeof(session_ctx->apdu_buffer); + + tlvRet = TLVSET_U32("objectID", &pCmdbuf, &cmdbufLen, kSE05x_TAG_1, objectID); + if (0 != tlvRet) { + goto cleanup; + } + tlvRet = TLVSET_U8("macOperation", &pCmdbuf, &cmdbufLen, kSE05x_TAG_2, macOperation); + if (0 != tlvRet) { + goto cleanup; + } + tlvRet = TLVSET_u8bufOptional("inputData", &pCmdbuf, &cmdbufLen, kSE05x_TAG_3, inputData, inputDataLen); + if (0 != tlvRet) { + goto cleanup; + } + retStatus = DoAPDUTxRx(session_ctx, &hdr, session_ctx->apdu_buffer, cmdbufLen, pRspbuf, &rspbufLen, 0); + + if (retStatus == SM_OK) { + retStatus = SM_NOT_OK; + size_t rspIndex = 0; + tlvRet = tlvGet_u8buf(pRspbuf, &rspIndex, rspbufLen, kSE05x_TAG_1, macValue, pmacValueLen); + if (0 != tlvRet) { + goto cleanup; + } + if ((rspIndex + 2) == rspbufLen) { + retStatus = (smStatus_t)((pRspbuf[rspIndex] << 8) | (pRspbuf[rspIndex + 1])); + } + } + +cleanup: + return retStatus; +} + + smStatus_t Se05x_API_CreateCryptoObject(pSe05xSession_t session_ctx, SE05x_CryptoObjectID_t cryptoObjectID, SE05x_CryptoContext_t cryptoContext, diff --git a/libraries/SE05X/src/lib/apdu/se05x_types.h b/libraries/SE05X/src/lib/apdu/se05x_types.h index c16fad9af..876094d8e 100644 --- a/libraries/SE05X/src/lib/apdu/se05x_types.h +++ b/libraries/SE05X/src/lib/apdu/se05x_types.h @@ -198,6 +198,8 @@ typedef enum kSE05x_P2_DH = 0x0F, kSE05x_P2_ENCRYPT_ONESHOT = 0x37, kSE05x_P2_DECRYPT_ONESHOT = 0x38, + kSE05x_P2_GENERATE_ONESHOT = 0x45, + kSE05x_P2_VALIDATE_ONESHOT = 0x46, kSE05x_P2_RANDOM = 0x49, kSE05x_P2_SCP = 0x52, } SE05x_P2_t; From 355ca866b0f02827ea92c71a10720e1e6bc9d669 Mon Sep 17 00:00:00 2001 From: Mattia Pennasilico Date: Wed, 31 Jan 2024 15:20:30 +0100 Subject: [PATCH 12/33] Docs: UNO R4 WiFi fix command to flash bootloader Starting from release 0.2.0 of uno-r4-wifi-usb-bridge firmware -dtr flag is needed in order to flash the bootloader --- bootloaders/UNO_R4/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootloaders/UNO_R4/README.md b/bootloaders/UNO_R4/README.md index 4cdb9a9f0..4697edc42 100644 --- a/bootloaders/UNO_R4/README.md +++ b/bootloaders/UNO_R4/README.md @@ -45,7 +45,7 @@ stty -F $portname 2400 Then flash the bootloader with [`rfp-cli`](https://www.renesas.com/us/en/software-tool/renesas-flash-programmer-programming-gui#download) ``` -rfp-cli -device ra -port $portname -p dfu_wifi.hex +rfp-cli -device ra -dtr -port $portname -p dfu_wifi.hex ``` :rocket: `How to load bootloader (UNO R4 Minima)` From 1500f231f108ac553744f8d5ed489b6310d1bf92 Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 31 Jan 2024 16:41:01 +0100 Subject: [PATCH 13/33] Software AT Secure Element SATSE initial commit --- libraries/SoftwareATSE/.unor4_only | 0 .../SATSECertificate/SATSECertificate.ino | 83 ++++++ .../SATSEPrivateKey/SATSEPrivateKey.ino | 43 ++++ .../SATSERandomNumber/SATSERandomNumber.ino | 28 ++ .../SATSESerialNumber/SATSESerialNumber.ino | 28 ++ .../SATSESignAndVerify/SATSESignAndVerify.ino | 83 ++++++ libraries/SoftwareATSE/library.properties | 9 + libraries/SoftwareATSE/src/SoftwareATSE.cpp | 240 ++++++++++++++++++ libraries/SoftwareATSE/src/SoftwareATSE.h | 64 +++++ 9 files changed, 578 insertions(+) create mode 100644 libraries/SoftwareATSE/.unor4_only create mode 100644 libraries/SoftwareATSE/examples/SATSECertificate/SATSECertificate.ino create mode 100644 libraries/SoftwareATSE/examples/SATSEPrivateKey/SATSEPrivateKey.ino create mode 100644 libraries/SoftwareATSE/examples/SATSERandomNumber/SATSERandomNumber.ino create mode 100644 libraries/SoftwareATSE/examples/SATSESerialNumber/SATSESerialNumber.ino create mode 100644 libraries/SoftwareATSE/examples/SATSESignAndVerify/SATSESignAndVerify.ino create mode 100644 libraries/SoftwareATSE/library.properties create mode 100644 libraries/SoftwareATSE/src/SoftwareATSE.cpp create mode 100644 libraries/SoftwareATSE/src/SoftwareATSE.h diff --git a/libraries/SoftwareATSE/.unor4_only b/libraries/SoftwareATSE/.unor4_only new file mode 100644 index 000000000..e69de29bb diff --git a/libraries/SoftwareATSE/examples/SATSECertificate/SATSECertificate.ino b/libraries/SoftwareATSE/examples/SATSECertificate/SATSECertificate.ino new file mode 100644 index 000000000..4abf4cff7 --- /dev/null +++ b/libraries/SoftwareATSE/examples/SATSECertificate/SATSECertificate.ino @@ -0,0 +1,83 @@ +/* + Software Secure Element Certificate + + This sketch uses the Software Secure Element to store device certificate and read it back. + + Circuit: + - UNO R4 WiFi +*/ + +#include + +const byte certificate[410] = { + 0x30 ,0x82 ,0x01 ,0x96 ,0x30 ,0x82 ,0x01 ,0x3D ,0xA0 ,0x03 ,0x02 ,0x01 ,0x02 ,0x02 ,0x10 ,0x37, + 0xFE ,0x48 ,0x92 ,0xE6 ,0xC0 ,0xA0 ,0x64 ,0x68 ,0x91 ,0x66 ,0x5F ,0x7D ,0xE3 ,0x02 ,0xDE ,0x30, + 0x0A ,0x06 ,0x08 ,0x2A ,0x86 ,0x48 ,0xCE ,0x3D ,0x04 ,0x03 ,0x02 ,0x30 ,0x45 ,0x31 ,0x0B ,0x30, + 0x09 ,0x06 ,0x03 ,0x55 ,0x04 ,0x06 ,0x13 ,0x02 ,0x55 ,0x53 ,0x31 ,0x17 ,0x30 ,0x15 ,0x06 ,0x03, + 0x55 ,0x04 ,0x0A ,0x13 ,0x0E ,0x41 ,0x72 ,0x64 ,0x75 ,0x69 ,0x6E ,0x6F ,0x20 ,0x4C ,0x4C ,0x43, + 0x20 ,0x55 ,0x53 ,0x31 ,0x0B ,0x30 ,0x09 ,0x06 ,0x03 ,0x55 ,0x04 ,0x0B ,0x13 ,0x02 ,0x49 ,0x54, + 0x31 ,0x10 ,0x30 ,0x0E ,0x06 ,0x03 ,0x55 ,0x04 ,0x03 ,0x13 ,0x07 ,0x41 ,0x72 ,0x64 ,0x75 ,0x69, + 0x6E ,0x6F ,0x30 ,0x20 ,0x17 ,0x0D ,0x32 ,0x33 ,0x30 ,0x33 ,0x33 ,0x31 ,0x30 ,0x37 ,0x30 ,0x30, + 0x30 ,0x30 ,0x5A ,0x18 ,0x0F ,0x32 ,0x30 ,0x35 ,0x34 ,0x30 ,0x33 ,0x33 ,0x31 ,0x30 ,0x37 ,0x30, + 0x30 ,0x30 ,0x30 ,0x5A ,0x30 ,0x2F ,0x31 ,0x2D ,0x30 ,0x2B ,0x06 ,0x03 ,0x55 ,0x04 ,0x03 ,0x13, + 0x24 ,0x37 ,0x61 ,0x31 ,0x39 ,0x39 ,0x65 ,0x62 ,0x30 ,0x2D ,0x38 ,0x33 ,0x64 ,0x38 ,0x2D ,0x34, + 0x63 ,0x34 ,0x34 ,0x2D ,0x39 ,0x66 ,0x66 ,0x32 ,0x2D ,0x30 ,0x32 ,0x33 ,0x35 ,0x37 ,0x38 ,0x30, + 0x31 ,0x35 ,0x64 ,0x33 ,0x39 ,0x30 ,0x59 ,0x30 ,0x13 ,0x06 ,0x07 ,0x2A ,0x86 ,0x48 ,0xCE ,0x3D, + 0x02 ,0x01 ,0x06 ,0x08 ,0x2A ,0x86 ,0x48 ,0xCE ,0x3D ,0x03 ,0x01 ,0x07 ,0x03 ,0x42 ,0x00 ,0x04, + 0x60 ,0x53 ,0x94 ,0x10 ,0x8C ,0xA6 ,0xB6 ,0xC8 ,0xD2 ,0x05 ,0x22 ,0x61 ,0xD9 ,0x5D ,0xF8 ,0xDB, + 0xD1 ,0xF4 ,0xE4 ,0xAC ,0xC9 ,0x96 ,0x8E ,0xFF ,0xB8 ,0x7E ,0x0D ,0xDC ,0xA1 ,0xB8 ,0x0F ,0x4C, + 0xF5 ,0x66 ,0x68 ,0xF0 ,0xF4 ,0xF0 ,0x70 ,0xF3 ,0xF6 ,0xFD ,0x70 ,0xD2 ,0x7A ,0xFB ,0x20 ,0x70, + 0x30 ,0x82 ,0x5F ,0x34 ,0xF8 ,0x2A ,0x1B ,0xC5 ,0xB1 ,0x38 ,0xE5 ,0xA5 ,0xF7 ,0xC7 ,0xB4 ,0x62, + 0xA3 ,0x23 ,0x30 ,0x21 ,0x30 ,0x1F ,0x06 ,0x03 ,0x55 ,0x1D ,0x23 ,0x04 ,0x18 ,0x30 ,0x16 ,0x80, + 0x14 ,0x5B ,0x3E ,0x2A ,0x6B ,0x8E ,0xC9 ,0xB0 ,0x1A ,0xA8 ,0x54 ,0xE6 ,0x36 ,0x9B ,0x8C ,0x09, + 0xF9 ,0xFC ,0xE1 ,0xB9 ,0x80 ,0x30 ,0x0A ,0x06 ,0x08 ,0x2A ,0x86 ,0x48 ,0xCE ,0x3D ,0x04 ,0x03, + 0x02 ,0x03 ,0x47 ,0x00 ,0x30 ,0x44 ,0x02 ,0x20 ,0x16 ,0x85 ,0x8A ,0x58 ,0x07 ,0x28 ,0xEF ,0x6D, + 0x93 ,0x86 ,0xA0 ,0x0E ,0xC8 ,0xB0 ,0x0A ,0xAD ,0x3B ,0xCE ,0xBB ,0x6A ,0x19 ,0x94 ,0xF9 ,0xD3, + 0x05 ,0x2E ,0x15 ,0xF1 ,0x5E ,0x9F ,0x59 ,0xD2 ,0x02 ,0x20 ,0x45 ,0x30 ,0x88 ,0x1D ,0x24 ,0xDA, + 0xE4 ,0x60 ,0xE2 ,0xD0 ,0x6E ,0x02 ,0xB0 ,0x7D ,0x65 ,0xA8 ,0x09 ,0x63 ,0x0B ,0x44 ,0xBC ,0x24, + 0x1A ,0xE2 ,0xEC ,0x64 ,0x19 ,0xB4 ,0x59 ,0xB8 ,0x09 ,0x78 +}; + +void printBufferHex(const byte input[], size_t inputLength) { + Serial.println(inputLength); + for (size_t i = 0; i < inputLength; i++) { + Serial.print(input[i] >> 4, HEX); + Serial.print(input[i] & 0x0f, HEX); + } + Serial.println(); +} + +void setup() { + Serial.begin(9600); + while (!Serial); + + if (!SATSE.begin()) { + Serial.println("Failed to communicate with Software Secure Element!"); + while (1); + } + + const int certId = 799; + + if(SATSE.writeSlot(certId, certificate, sizeof(certificate))) { + Serial.println("Data stored"); + } else { + Serial.println("Failed to store data"); + return; + } + + byte buf[512]; + int len = 0; + + if((len = SATSE.readSlot(certId, buf, sizeof(buf))) > 0) { + Serial.print("Readback data is: "); + printBufferHex(buf, len); + } else { + Serial.println("Failed to read data"); + return; + } + +} + +void loop() { + +} diff --git a/libraries/SoftwareATSE/examples/SATSEPrivateKey/SATSEPrivateKey.ino b/libraries/SoftwareATSE/examples/SATSEPrivateKey/SATSEPrivateKey.ino new file mode 100644 index 000000000..0ae22552e --- /dev/null +++ b/libraries/SoftwareATSE/examples/SATSEPrivateKey/SATSEPrivateKey.ino @@ -0,0 +1,43 @@ +/* + Software Secure Element Private Key + + This sketch uses the Software Secure Element to generate a new EC NIST P-256 keypair + and store it with id 999, then the public key is printed in raw format. + + Circuit: + - UNO R4 WiFi +*/ + +#include +#include + +const int KeyId = 999; +byte rawBuf[64]; + +void printBufferHex(const byte input[], size_t inputLength) { + for (size_t i = 0; i < inputLength; i++) { + Serial.print(input[i] >> 4, HEX); + Serial.print(input[i] & 0x0f, HEX); + } + Serial.println(); +} + +void setup() { + Serial.begin(9600); + while (!Serial); + + if (!SATSE.begin()) { + Serial.println("Failed to communicate with Software Secure Element!"); + while (1); + } + + SATSE.generatePrivateKey(KeyId, rawBuf); + printBufferHex(rawBuf, sizeof(rawBuf)); + +} + +void loop() { + SATSE.generatePublicKey(KeyId, rawBuf); + printBufferHex(rawBuf, sizeof(rawBuf)); + delay(5000); +} diff --git a/libraries/SoftwareATSE/examples/SATSERandomNumber/SATSERandomNumber.ino b/libraries/SoftwareATSE/examples/SATSERandomNumber/SATSERandomNumber.ino new file mode 100644 index 000000000..2e5f9197e --- /dev/null +++ b/libraries/SoftwareATSE/examples/SATSERandomNumber/SATSERandomNumber.ino @@ -0,0 +1,28 @@ +/* + Software Secure Element Random Number + + This sketch uses the Software Secure Element to generate a random number + every second and print it to the Serial monitor + + Circuit: + - UNO R4 WiFi +*/ + +#include + +void setup() { + Serial.begin(9600); + while (!Serial); + + if (!SATSE.begin()) { + Serial.println("Failed to communicate with Software Secure Element!"); + while (1); + } +} + +void loop() { + Serial.print("Random number = "); + Serial.println(SATSE.random(65535)); + + delay(1000); +} diff --git a/libraries/SoftwareATSE/examples/SATSESerialNumber/SATSESerialNumber.ino b/libraries/SoftwareATSE/examples/SATSESerialNumber/SATSESerialNumber.ino new file mode 100644 index 000000000..243e327af --- /dev/null +++ b/libraries/SoftwareATSE/examples/SATSESerialNumber/SATSESerialNumber.ino @@ -0,0 +1,28 @@ +/* + Software Secure Element serial number + + This sketch prints the Software Secure Element serial number: + ESP32-S3-MINI-1 efuse mac address + + Circuit: + - UNO R4 WiFi +*/ + +#include + +void setup() { + Serial.begin(9600); + while (!Serial); + + if (!SATSE.begin()) { + Serial.println("Failed to communicate with Software Secure Element!"); + while (1); + } +} + +void loop() { + Serial.print("S/N = "); + Serial.println(SATSE.serialNumber()); + + delay(1000); +} diff --git a/libraries/SoftwareATSE/examples/SATSESignAndVerify/SATSESignAndVerify.ino b/libraries/SoftwareATSE/examples/SATSESignAndVerify/SATSESignAndVerify.ino new file mode 100644 index 000000000..45c8f61c4 --- /dev/null +++ b/libraries/SoftwareATSE/examples/SATSESignAndVerify/SATSESignAndVerify.ino @@ -0,0 +1,83 @@ +/* + Software Secure Element SignAndVerify + + This sketch uses the Software Secure Element to generate a new EC NIST P-256 keypair + and store it with id 999, then input buffer SHA256 is signed with the private + key and verified with the public key. + + Circuit: + - UNO R4 WiFi +*/ + +#include + +const byte input[64] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f +}; + +void printBufferHex(const byte input[], size_t inputLength) { + for (size_t i = 0; i < inputLength; i++) { + Serial.print(input[i] >> 4, HEX); + Serial.print(input[i] & 0x0f, HEX); + } + Serial.println(); +} + +void setup() { + Serial.begin(9600); + while (!Serial); + + if (!SATSE.begin()) { + Serial.println("Failed to communicate with Software Secure Element!"); + while (1); + } + + const int KeyId = 999; + byte pubKey[256]; + + SATSE.generatePrivateKey(KeyId, pubKey); + + // print the public key + Serial.print("Public key is: "); + printBufferHex(pubKey, 64); + + // print the input + Serial.print("Input is: "); + printBufferHex(input, sizeof(input)); + + // calculate the input SHA256 + byte sha256[256]; + size_t sha256Len; + SATSE.SHA256(input, sizeof(input), sha256); + Serial.print("Input SHA256 is: "); + printBufferHex(sha256, 32); + + // calculate the signature, input MUST be SHA256 + byte signature[256]; + SATSE.ecSign(KeyId, sha256, signature); + + // print the signature + Serial.print("Signature using KeyId "); + Serial.print(KeyId); + Serial.print(" is: "); + printBufferHex(signature, 64); + + Serial.println(); + + // To make the signature verifcation fail, uncomment the next line: + // signature[0] = 0x00; + + // validate the signature + if (SATSE.ecdsaVerify(sha256, signature, pubKey)) { + Serial.println("Verified signature successfully :D"); + } else { + Serial.println("oh no! failed to verify signature :("); + } +} + +void loop() { + +} diff --git a/libraries/SoftwareATSE/library.properties b/libraries/SoftwareATSE/library.properties new file mode 100644 index 000000000..c4820efeb --- /dev/null +++ b/libraries/SoftwareATSE/library.properties @@ -0,0 +1,9 @@ +name=SoftwareATSE +version=0.0.1 +author=Arduino +maintainer=Arduino +sentence=Arduino Library implementing base secure element functions in software +paragraph= +category=Communication +url= +architectures=renesas,renesas_uno \ No newline at end of file diff --git a/libraries/SoftwareATSE/src/SoftwareATSE.cpp b/libraries/SoftwareATSE/src/SoftwareATSE.cpp new file mode 100644 index 000000000..4f879dac6 --- /dev/null +++ b/libraries/SoftwareATSE/src/SoftwareATSE.cpp @@ -0,0 +1,240 @@ +/* + SoftwareATSE.cpp + Copyright (c) 2023 Arduino SA. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "SoftwareATSE.h" +#include "Modem.h" + +using namespace std; + +SoftwareATSEClass::SoftwareATSEClass() { + +} + +SoftwareATSEClass::~SoftwareATSEClass() { + end(); +} + +int SoftwareATSEClass::begin(const char * name, bool readOnly, const char* partition_label) +{ + string res = ""; + modem.begin(); + modem.debug(Serial,2); + if (name != nullptr && strlen(name) > 0) { + if (modem.write(string(PROMPT(_SOFTSE_BEGIN)), res, "%s%s,%d,%s\r\n", CMD_WRITE(_SOFTSE_BEGIN), name, readOnly, partition_label != NULL ? partition_label : "")) { + return atoi(res.c_str()); + } + } + return 0; +} + +void SoftwareATSEClass::end() +{ + string res = ""; + modem.write(string(PROMPT(_SOFTSE_END)), res, "%s", CMD(_SOFTSE_END)); +} + +String SoftwareATSEClass::serialNumber() +{ + string res = ""; + modem.read_using_size(); + if (modem.write(string(PROMPT(_SOFTSE_SERIAL)), res, "%s", CMD(_SOFTSE_SERIAL))) { + if (res.size()) { + String result = (char*)NULL; + result.reserve(res.size() * 2); + + for (size_t i = 0; i < res.size(); i++) { + byte b = res.data()[i]; + + if (b < 16) { + result += "0"; + } + result += String(b, HEX); + } + result.toUpperCase(); + return result; + } + } + return ""; +} + +long SoftwareATSEClass::random(long max) +{ + return random(0, max); +} + +long SoftwareATSEClass::random(long min, long max) +{ + if (min >= max) + { + return min; + } + + long diff = max - min; + + long r; + random((byte*)&r, sizeof(r)); + + if (r < 0) { + r = -r; + } + + r = (r % diff); + + return (r + min); +} + +int SoftwareATSEClass::random(byte data[], size_t length) +{ + string res = ""; + if (data != nullptr && length > 0) { + modem.read_using_size(); + if (modem.write(string(PROMPT(_SOFTSE_RND)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_RND), length)) { + if (res.size() >= length) { + memcpy(data, (uint8_t*)&res[0], length); + return 1; + } + } + } + return 0; +} + +int SoftwareATSEClass::generatePrivateKey(int keyID, byte publicKey[]) +{ + string res = ""; + if (publicKey != nullptr) { + modem.read_using_size(); + if (modem.write(string(PROMPT(_SOFTSE_PRI_KEY)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_PRI_KEY), keyID)) { + if (res.size() >= 64) { + memcpy(publicKey, (uint8_t*)&res[0], 64); + return 64; + } + } + } + return 0; +} + +int SoftwareATSEClass::generatePublicKey(int keyID, byte publicKey[]) +{ + string res = ""; + if (publicKey != nullptr) { + modem.read_using_size(); + if (modem.write(string(PROMPT(_SOFTSE_PUB_KEY)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_PUB_KEY), keyID)) { + if (res.size() >= 64) { + memcpy(publicKey, (uint8_t*)&res[0], 64); + return 64; + } + } + } + return 0; +} + +int SoftwareATSEClass::ecSign(int slot, const byte message[], byte signature[]) +{ + string res = ""; + if ( message != nullptr) { + modem.write_nowait(string(PROMPT(_SOFTSE_S_V_BUF_SET)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_S_V_BUF_SET), 32); + if(!modem.passthrough((uint8_t *)message, 32)) { + return 0; + } + } + + if (signature != nullptr) { + modem.read_using_size(); + if (modem.write(string(PROMPT(_SOFTSE_SIGN_GET)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_SIGN_GET), slot)) { + if (res.size() == 64) { + memcpy(signature, (uint8_t*)&res[0], 64); + return 64; + } + } + } + return 0; +} + +int SoftwareATSEClass::ecdsaVerify(const byte message[], const byte signature[], const byte pubkey[]) +{ + string res = ""; + if ( message != nullptr && signature!= nullptr) { + byte tmp[256]; + memcpy(tmp, message,32); + memcpy(&tmp[32], signature, 64); + memcpy(&tmp[32+64], pubkey, 64); + modem.write_nowait(string(PROMPT(_SOFTSE_S_V_BUF_SET)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_S_V_BUF_SET), 32+64+64); + if(!modem.passthrough((uint8_t *)tmp, 32+64+64)) { + return 0; + } + } + + if (signature != nullptr) { + if (modem.write(string(PROMPT(_SOFTSE_VERIFY_GET)), res, "%s", CMD(_SOFTSE_VERIFY_GET))) { + return atoi(res.c_str()) == 0 ? 1: 0; + } + } + return 0; +} + +int SoftwareATSEClass::SHA256(const uint8_t *buffer, size_t size, uint8_t *digest) { + string res = ""; + if ( buffer != nullptr) { + modem.write_nowait(string(PROMPT(_SOFTSE_S_V_BUF_SET)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_S_V_BUF_SET), size); + if(!modem.passthrough((uint8_t *)buffer, size)) { + return 0; + } + } + + if (digest != nullptr) { + modem.read_using_size(); + if (modem.write(string(PROMPT(_SOFTSE_SHA256_GET)), res, "%s", CMD(_SOFTSE_SHA256_GET))) { + if (res.size() == 32) { + memcpy(digest, (uint8_t*)&res[0], 32); + return 32; + } + } + } + return 0; +} + +int SoftwareATSEClass::readSlot(int slot, byte data[], int length) +{ + string res = ""; + if (data != nullptr) { + modem.read_using_size(); + if (modem.write(string(PROMPT(_SOFTSE_READ_SLOT)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_READ_SLOT), slot)) { + if (res.size()) { + int len = res.size() > length ? length : res.size(); + memcpy(data, (uint8_t*)&res[0], len); + return len; + } + } + } + return 0; +} + +int SoftwareATSEClass::writeSlot(int slot, const byte data[], int length) +{ + string res = ""; + if ( data != nullptr && length > 0) { + modem.write_nowait(string(PROMPT(_SOFTSE_WRITE_SLOT)), res, "%s%d,%d\r\n", CMD_WRITE(_SOFTSE_WRITE_SLOT), slot, length); + if(modem.passthrough((uint8_t *)data, length)) { + return length; + } + } + return 0; +} + +SoftwareATSEClass SATSE; diff --git a/libraries/SoftwareATSE/src/SoftwareATSE.h b/libraries/SoftwareATSE/src/SoftwareATSE.h new file mode 100644 index 000000000..d1f1502da --- /dev/null +++ b/libraries/SoftwareATSE/src/SoftwareATSE.h @@ -0,0 +1,64 @@ +/* + SoftwareATSE.h + Copyright (c) 2023 Arduino SA. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _SOFTWARE_ATSE_H_ +#define _SOFTWARE_ATSE_H_ + +#include + + +class SoftwareATSEClass +{ +public: + SoftwareATSEClass(); + virtual ~SoftwareATSEClass(); + + int begin(const char * name = "se", bool readOnly = false, const char* partition_label = NULL); + void end(); + + String serialNumber(); + + long random(long min, long max); + long random(long max); + int random(byte data[], size_t length); + + int generatePrivateKey(int slot, byte publicKey[]); + int generatePublicKey(int slot, byte publicKey[]); + + int ecdsaVerify(const byte message[], const byte signature[], const byte pubkey[]); + int ecSign(int slot, const byte message[], byte signature[]); + + int SHA256(const uint8_t *buffer, size_t size, uint8_t *digest); + + int readSlot(int slot, byte data[], int length); + int writeSlot(int slot, const byte data[], int length); + + inline int locked() { return 1; } + inline int lock() { return 1; } + + inline int writeConfiguration(const byte config[] = nullptr) { (void)config; return 1; } + + +private: + +}; + +extern SoftwareATSEClass SATSE; + +#endif From a8f7363e324c521d93f715f785d34fbf3228dc5b Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 31 Jan 2024 16:45:41 +0100 Subject: [PATCH 14/33] SATSE examples: add message about minimum required firmware version --- .../SoftwareATSE/examples/SATSECertificate/SATSECertificate.ino | 1 + .../SoftwareATSE/examples/SATSEPrivateKey/SATSEPrivateKey.ino | 1 + .../examples/SATSERandomNumber/SATSERandomNumber.ino | 1 + .../examples/SATSESerialNumber/SATSESerialNumber.ino | 1 + .../examples/SATSESignAndVerify/SATSESignAndVerify.ino | 1 + 5 files changed, 5 insertions(+) diff --git a/libraries/SoftwareATSE/examples/SATSECertificate/SATSECertificate.ino b/libraries/SoftwareATSE/examples/SATSECertificate/SATSECertificate.ino index 4abf4cff7..169dc3061 100644 --- a/libraries/SoftwareATSE/examples/SATSECertificate/SATSECertificate.ino +++ b/libraries/SoftwareATSE/examples/SATSECertificate/SATSECertificate.ino @@ -53,6 +53,7 @@ void setup() { if (!SATSE.begin()) { Serial.println("Failed to communicate with Software Secure Element!"); + Serial.println("Make sure your WiFi firmware version is greater than 0.3.0"); while (1); } diff --git a/libraries/SoftwareATSE/examples/SATSEPrivateKey/SATSEPrivateKey.ino b/libraries/SoftwareATSE/examples/SATSEPrivateKey/SATSEPrivateKey.ino index 0ae22552e..fe33374da 100644 --- a/libraries/SoftwareATSE/examples/SATSEPrivateKey/SATSEPrivateKey.ino +++ b/libraries/SoftwareATSE/examples/SATSEPrivateKey/SATSEPrivateKey.ino @@ -28,6 +28,7 @@ void setup() { if (!SATSE.begin()) { Serial.println("Failed to communicate with Software Secure Element!"); + Serial.println("Make sure your WiFi firmware version is greater than 0.3.0"); while (1); } diff --git a/libraries/SoftwareATSE/examples/SATSERandomNumber/SATSERandomNumber.ino b/libraries/SoftwareATSE/examples/SATSERandomNumber/SATSERandomNumber.ino index 2e5f9197e..fca8f40ad 100644 --- a/libraries/SoftwareATSE/examples/SATSERandomNumber/SATSERandomNumber.ino +++ b/libraries/SoftwareATSE/examples/SATSERandomNumber/SATSERandomNumber.ino @@ -16,6 +16,7 @@ void setup() { if (!SATSE.begin()) { Serial.println("Failed to communicate with Software Secure Element!"); + Serial.println("Make sure your WiFi firmware version is greater than 0.3.0"); while (1); } } diff --git a/libraries/SoftwareATSE/examples/SATSESerialNumber/SATSESerialNumber.ino b/libraries/SoftwareATSE/examples/SATSESerialNumber/SATSESerialNumber.ino index 243e327af..57a454587 100644 --- a/libraries/SoftwareATSE/examples/SATSESerialNumber/SATSESerialNumber.ino +++ b/libraries/SoftwareATSE/examples/SATSESerialNumber/SATSESerialNumber.ino @@ -16,6 +16,7 @@ void setup() { if (!SATSE.begin()) { Serial.println("Failed to communicate with Software Secure Element!"); + Serial.println("Make sure your WiFi firmware version is greater than 0.3.0"); while (1); } } diff --git a/libraries/SoftwareATSE/examples/SATSESignAndVerify/SATSESignAndVerify.ino b/libraries/SoftwareATSE/examples/SATSESignAndVerify/SATSESignAndVerify.ino index 45c8f61c4..25ce45f12 100644 --- a/libraries/SoftwareATSE/examples/SATSESignAndVerify/SATSESignAndVerify.ino +++ b/libraries/SoftwareATSE/examples/SATSESignAndVerify/SATSESignAndVerify.ino @@ -32,6 +32,7 @@ void setup() { if (!SATSE.begin()) { Serial.println("Failed to communicate with Software Secure Element!"); + Serial.println("Make sure your WiFi firmware version is greater than 0.3.0"); while (1); } From 779f1b3264376e90c371402cc529ffd131803c2b Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 1 Feb 2024 11:00:28 +0100 Subject: [PATCH 15/33] SATSE: add functions description --- libraries/SoftwareATSE/src/SoftwareATSE.h | 88 +++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/libraries/SoftwareATSE/src/SoftwareATSE.h b/libraries/SoftwareATSE/src/SoftwareATSE.h index d1f1502da..333b03136 100644 --- a/libraries/SoftwareATSE/src/SoftwareATSE.h +++ b/libraries/SoftwareATSE/src/SoftwareATSE.h @@ -38,15 +38,103 @@ class SoftwareATSEClass long random(long max); int random(byte data[], size_t length); + /** generatePrivateKey + * + * Create a new ECCurve_NIST_P256 keypair and stores it in the WiFi chip NVS. + * Public key X Y values will be available inside publicKey buffer that should + * be at least 64 bytes long. + * + * | Public key X Y values (64 bytes) | + * + * @param[in] slot objectID where to store the private key + * @param[out] publicKey Buffer containing the public key X Y values + * + * @return 0 on Failure 1 on Success + */ int generatePrivateKey(int slot, byte publicKey[]); + + /** generatePublicKey + * + * Reads ECCurve_NIST_P256 public key from KeyID. Public key X Y values will be available + * inside publicKey buffer that should be at least 64 bytes long. + * + * | Public key X Y values (64 bytes) | + * + * @param[in] slot objectID where is stored the keypair + * @param[out] pubkey Buffer containing the public key X Y values + * + * @return 0 on Failure 1 on Success + */ int generatePublicKey(int slot, byte publicKey[]); + /** ecdsaVerify + * + * Verify ECDSA signature using public key. + * + * Input SHA256 + * ? Match ? + * Signature -> public Key -> Original SHA256 + * + * @param[in] message Input SHA256 used to compute the signature 32 bytes + * @param[in] sig Input buffer containint the signature R S values 64bytes + * @param[in] pubkey Public key X Y values 64bytes + * + * @return 0 on Failure (Not match) 1 on Success (Match) + */ int ecdsaVerify(const byte message[], const byte signature[], const byte pubkey[]); + + /** ecSign + * + * Computes ECDSA signature using key stored in KeyID SE050 object. + * Output signature buffer is filled with the signature R S values + * and should be at least 64 bytes long: + * + * | R values 32 bytes | S values 32 bytes | + * + * SHA256 -> private Key -> Signature + * + * @param[in] slot object ID containing the key + * @param[in] message Input SHA256 used to compute the signature 32 bytes + * @param[out] signature Output buffer containint the signature 64 bytes + * + * @return 0 on Failure 1 on Success + */ int ecSign(int slot, const byte message[], byte signature[]); + /** SHA256 + * + * One-shot SHA256 + * + * @param[in] buffer Input data buffer + * @param[in] size Input data length + * @param[out] digest Output buffer should be at least 32 bytes long + * + * @return 0 on Failure 1 on Success + */ int SHA256(const uint8_t *buffer, size_t size, uint8_t *digest); + /** readSlot + * + * Reads binary data from Software AT Secure Element object. + * + * @param[in] slot object ID containing data + * @param[out] data Output data buffer + * @param[in] length Number of bytes to read + * + * @return 0 on Failure 1 on Success + */ int readSlot(int slot, byte data[], int length); + + /** writeSlot + * + * Writes binary data into Software AT Secure Element object. + * + * @param[in] slot object ID + * @param[in] data Input data buffer + * @param[in] length Number of bytes to write + * + * @return 0 on Failure 1 on Success + */ int writeSlot(int slot, const byte data[], int length); inline int locked() { return 1; } From 163b316092e88ba219c1b5250142f041d779bf71 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 1 Feb 2024 11:01:26 +0100 Subject: [PATCH 16/33] SATSE: Add separate function to configure debug --- libraries/SoftwareATSE/src/SoftwareATSE.cpp | 6 +++++- libraries/SoftwareATSE/src/SoftwareATSE.h | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/libraries/SoftwareATSE/src/SoftwareATSE.cpp b/libraries/SoftwareATSE/src/SoftwareATSE.cpp index 4f879dac6..19c0d9a0c 100644 --- a/libraries/SoftwareATSE/src/SoftwareATSE.cpp +++ b/libraries/SoftwareATSE/src/SoftwareATSE.cpp @@ -34,7 +34,6 @@ int SoftwareATSEClass::begin(const char * name, bool readOnly, const char* parti { string res = ""; modem.begin(); - modem.debug(Serial,2); if (name != nullptr && strlen(name) > 0) { if (modem.write(string(PROMPT(_SOFTSE_BEGIN)), res, "%s%s,%d,%s\r\n", CMD_WRITE(_SOFTSE_BEGIN), name, readOnly, partition_label != NULL ? partition_label : "")) { return atoi(res.c_str()); @@ -49,6 +48,11 @@ void SoftwareATSEClass::end() modem.write(string(PROMPT(_SOFTSE_END)), res, "%s", CMD(_SOFTSE_END)); } +void SoftwareATSEClass::debug(Stream &u, uint8_t level) +{ + modem.debug(u,level); +} + String SoftwareATSEClass::serialNumber() { string res = ""; diff --git a/libraries/SoftwareATSE/src/SoftwareATSE.h b/libraries/SoftwareATSE/src/SoftwareATSE.h index 333b03136..030d2fdb8 100644 --- a/libraries/SoftwareATSE/src/SoftwareATSE.h +++ b/libraries/SoftwareATSE/src/SoftwareATSE.h @@ -32,6 +32,8 @@ class SoftwareATSEClass int begin(const char * name = "se", bool readOnly = false, const char* partition_label = NULL); void end(); + void debug(Stream &u, uint8_t level = 0); + String serialNumber(); long random(long min, long max); From 6d7ca0e8cd7252d2ca40e8120414a90b64243511 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 1 Feb 2024 11:03:30 +0100 Subject: [PATCH 17/33] SATSE: Fix return values according function description Also: - Remove unnecessary type casts - Use constexpr instead of numbers --- libraries/SoftwareATSE/src/SoftwareATSE.cpp | 53 +++++++++++---------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/libraries/SoftwareATSE/src/SoftwareATSE.cpp b/libraries/SoftwareATSE/src/SoftwareATSE.cpp index 19c0d9a0c..43990aee3 100644 --- a/libraries/SoftwareATSE/src/SoftwareATSE.cpp +++ b/libraries/SoftwareATSE/src/SoftwareATSE.cpp @@ -22,6 +22,10 @@ using namespace std; +static uint8_t constexpr SATSE_SHA256_LENGTH = 32; +static uint8_t constexpr SATSE_EC256_SIGNATURE_LENGTH = 64; +static uint8_t constexpr SATSE_EC256_PUB_KEY_LENGTH = 64; + SoftwareATSEClass::SoftwareATSEClass() { } @@ -124,9 +128,9 @@ int SoftwareATSEClass::generatePrivateKey(int keyID, byte publicKey[]) if (publicKey != nullptr) { modem.read_using_size(); if (modem.write(string(PROMPT(_SOFTSE_PRI_KEY)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_PRI_KEY), keyID)) { - if (res.size() >= 64) { - memcpy(publicKey, (uint8_t*)&res[0], 64); - return 64; + if (res.size() == SATSE_EC256_PUB_KEY_LENGTH) { + memcpy(publicKey, (uint8_t*)&res[0], SATSE_EC256_PUB_KEY_LENGTH); + return 1; } } } @@ -139,9 +143,9 @@ int SoftwareATSEClass::generatePublicKey(int keyID, byte publicKey[]) if (publicKey != nullptr) { modem.read_using_size(); if (modem.write(string(PROMPT(_SOFTSE_PUB_KEY)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_PUB_KEY), keyID)) { - if (res.size() >= 64) { - memcpy(publicKey, (uint8_t*)&res[0], 64); - return 64; + if (res.size() == SATSE_EC256_PUB_KEY_LENGTH) { + memcpy(publicKey, (uint8_t*)&res[0], SATSE_EC256_PUB_KEY_LENGTH); + return 1; } } } @@ -152,8 +156,8 @@ int SoftwareATSEClass::ecSign(int slot, const byte message[], byte signature[]) { string res = ""; if ( message != nullptr) { - modem.write_nowait(string(PROMPT(_SOFTSE_S_V_BUF_SET)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_S_V_BUF_SET), 32); - if(!modem.passthrough((uint8_t *)message, 32)) { + modem.write_nowait(string(PROMPT(_SOFTSE_S_V_BUF_SET)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_S_V_BUF_SET), SATSE_SHA256_LENGTH); + if(!modem.passthrough(message, SATSE_SHA256_LENGTH)) { return 0; } } @@ -161,9 +165,9 @@ int SoftwareATSEClass::ecSign(int slot, const byte message[], byte signature[]) if (signature != nullptr) { modem.read_using_size(); if (modem.write(string(PROMPT(_SOFTSE_SIGN_GET)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_SIGN_GET), slot)) { - if (res.size() == 64) { - memcpy(signature, (uint8_t*)&res[0], 64); - return 64; + if (res.size() == SATSE_EC256_SIGNATURE_LENGTH) { + memcpy(signature, (uint8_t*)&res[0], SATSE_EC256_SIGNATURE_LENGTH); + return 1; } } } @@ -174,12 +178,13 @@ int SoftwareATSEClass::ecdsaVerify(const byte message[], const byte signature[], { string res = ""; if ( message != nullptr && signature!= nullptr) { - byte tmp[256]; - memcpy(tmp, message,32); - memcpy(&tmp[32], signature, 64); - memcpy(&tmp[32+64], pubkey, 64); - modem.write_nowait(string(PROMPT(_SOFTSE_S_V_BUF_SET)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_S_V_BUF_SET), 32+64+64); - if(!modem.passthrough((uint8_t *)tmp, 32+64+64)) { + static const byte len = SATSE_SHA256_LENGTH + SATSE_EC256_SIGNATURE_LENGTH + SATSE_EC256_PUB_KEY_LENGTH; + byte tmp[len]; + memcpy(tmp, message, SATSE_SHA256_LENGTH); + memcpy(&tmp[SATSE_SHA256_LENGTH], signature, SATSE_EC256_SIGNATURE_LENGTH); + memcpy(&tmp[SATSE_SHA256_LENGTH + SATSE_EC256_SIGNATURE_LENGTH], pubkey, SATSE_EC256_PUB_KEY_LENGTH); + modem.write_nowait(string(PROMPT(_SOFTSE_S_V_BUF_SET)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_S_V_BUF_SET), len); + if(!modem.passthrough(tmp, len)) { return 0; } } @@ -196,7 +201,7 @@ int SoftwareATSEClass::SHA256(const uint8_t *buffer, size_t size, uint8_t *diges string res = ""; if ( buffer != nullptr) { modem.write_nowait(string(PROMPT(_SOFTSE_S_V_BUF_SET)), res, "%s%d\r\n", CMD_WRITE(_SOFTSE_S_V_BUF_SET), size); - if(!modem.passthrough((uint8_t *)buffer, size)) { + if(!modem.passthrough(buffer, size)) { return 0; } } @@ -204,9 +209,9 @@ int SoftwareATSEClass::SHA256(const uint8_t *buffer, size_t size, uint8_t *diges if (digest != nullptr) { modem.read_using_size(); if (modem.write(string(PROMPT(_SOFTSE_SHA256_GET)), res, "%s", CMD(_SOFTSE_SHA256_GET))) { - if (res.size() == 32) { - memcpy(digest, (uint8_t*)&res[0], 32); - return 32; + if (res.size() == SATSE_SHA256_LENGTH) { + memcpy(digest, (uint8_t*)&res[0], SATSE_SHA256_LENGTH); + return 1; } } } @@ -222,7 +227,7 @@ int SoftwareATSEClass::readSlot(int slot, byte data[], int length) if (res.size()) { int len = res.size() > length ? length : res.size(); memcpy(data, (uint8_t*)&res[0], len); - return len; + return 1; } } } @@ -234,8 +239,8 @@ int SoftwareATSEClass::writeSlot(int slot, const byte data[], int length) string res = ""; if ( data != nullptr && length > 0) { modem.write_nowait(string(PROMPT(_SOFTSE_WRITE_SLOT)), res, "%s%d,%d\r\n", CMD_WRITE(_SOFTSE_WRITE_SLOT), slot, length); - if(modem.passthrough((uint8_t *)data, length)) { - return length; + if(modem.passthrough(data, length)) { + return 1; } } return 0; From 777dfc7483e20cd2673e57ec80399f735ee7d4fa Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 1 Feb 2024 12:17:04 +0100 Subject: [PATCH 18/33] SATSE examples: compute certificate length from payload --- .../examples/SATSECertificate/SATSECertificate.ino | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/SoftwareATSE/examples/SATSECertificate/SATSECertificate.ino b/libraries/SoftwareATSE/examples/SATSECertificate/SATSECertificate.ino index 169dc3061..54c54e82e 100644 --- a/libraries/SoftwareATSE/examples/SATSECertificate/SATSECertificate.ino +++ b/libraries/SoftwareATSE/examples/SATSECertificate/SATSECertificate.ino @@ -67,10 +67,11 @@ void setup() { } byte buf[512]; - int len = 0; + int ret = 0; - if((len = SATSE.readSlot(certId, buf, sizeof(buf))) > 0) { + if((ret = SATSE.readSlot(certId, buf, sizeof(buf))) > 0) { Serial.print("Readback data is: "); + int len = (buf[2] << 8) + buf[3] + 4; printBufferHex(buf, len); } else { Serial.println("Failed to read data"); From bd2c159b30e9395d2e7f6fc57e4fbe16114ddbcf Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Sun, 24 Sep 2023 16:57:19 +0200 Subject: [PATCH 19/33] WiFiS3 client connect timeout --- libraries/WiFiS3/src/WiFiClient.cpp | 18 ++++++++---------- libraries/WiFiS3/src/WiFiClient.h | 5 +++++ libraries/WiFiS3/src/WiFiSSLClient.cpp | 14 +++++++------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/libraries/WiFiS3/src/WiFiClient.cpp b/libraries/WiFiS3/src/WiFiClient.cpp index 3c8f9df7c..adb020053 100644 --- a/libraries/WiFiS3/src/WiFiClient.cpp +++ b/libraries/WiFiS3/src/WiFiClient.cpp @@ -39,16 +39,8 @@ void WiFiClient::getSocket() { /* -------------------------------------------------------------------------- */ int WiFiClient::connect(IPAddress ip, uint16_t port){ -/* -------------------------------------------------------------------------- */ - getSocket(); - if(_sock >= 0) { - string res = ""; - modem.begin(); - if(modem.write(string(PROMPT(_CLIENTCONNECTIP)),res, "%s%d,%s,%d\r\n" , CMD_WRITE(_CLIENTCONNECTIP), _sock, ip.toString().c_str(), port)) { - return 1; - } - } - return 0; +/* -------------------------------------------------------------------------- */ + return connect(ip.toString().c_str(), port); } /* -------------------------------------------------------------------------- */ @@ -58,9 +50,15 @@ int WiFiClient::connect(const char *host, uint16_t port){ if(_sock >= 0) { string res = ""; modem.begin(); + if (_connectionTimeout) { + if(modem.write(string(PROMPT(_CLIENTCONNECT)),res, "%s%d,%s,%d,%d\r\n" , CMD_WRITE(_CLIENTCONNECT), _sock, host,port, _connectionTimeout)) { + return 1; + } + } else { if(modem.write(string(PROMPT(_CLIENTCONNECTNAME)),res, "%s%d,%s,%d\r\n" , CMD_WRITE(_CLIENTCONNECTNAME), _sock, host,port)) { return 1; } + } } return 0; } diff --git a/libraries/WiFiS3/src/WiFiClient.h b/libraries/WiFiS3/src/WiFiClient.h index ab27ea29f..972b98b8a 100644 --- a/libraries/WiFiS3/src/WiFiClient.h +++ b/libraries/WiFiS3/src/WiFiClient.h @@ -62,12 +62,17 @@ class WiFiClient : public Client { virtual IPAddress remoteIP(); virtual uint16_t remotePort(); + void setConnectionTimeout(int timeout) { + _connectionTimeout = timeout; + } + friend class WiFiServer; using Print::write; protected: int _sock; + int _connectionTimeout = 0; void getSocket(); std::shared_ptr> rx_buffer; int _read(); diff --git a/libraries/WiFiS3/src/WiFiSSLClient.cpp b/libraries/WiFiS3/src/WiFiSSLClient.cpp index c1c451b7c..92b66f01b 100644 --- a/libraries/WiFiS3/src/WiFiSSLClient.cpp +++ b/libraries/WiFiS3/src/WiFiSSLClient.cpp @@ -29,13 +29,7 @@ void WiFiSSLClient::getSocket() { /* -------------------------------------------------------------------------- */ int WiFiSSLClient::connect(IPAddress ip, uint16_t port) { /* -------------------------------------------------------------------------- */ - getSocket(); - - string res = ""; - if(modem.write(string(PROMPT(_SSLCLIENTCONNECTIP)),res, "%s%d,%s,%d\r\n" , CMD_WRITE(_SSLCLIENTCONNECTIP), _sock, ip.toString(), port)) { - return 1; - } - return 0; + return connect(ip.toString().c_str(), port); } /* -------------------------------------------------------------------------- */ @@ -46,9 +40,15 @@ int WiFiSSLClient::connect(const char* host, uint16_t port) { setCACert(); } string res = ""; + if (_connectionTimeout) { + if(modem.write(string(PROMPT(_SSLCLIENTCONNECT)),res, "%s%d,%s,%d,%d\r\n" , CMD_WRITE(_SSLCLIENTCONNECT), _sock, host,port, _connectionTimeout)) { + return 1; + } + } else { if(modem.write(string(PROMPT(_SSLCLIENTCONNECTNAME)),res, "%s%d,%s,%d\r\n" , CMD_WRITE(_SSLCLIENTCONNECTNAME), _sock, host, port)) { return 1; } + } return 0; } From aaab68be5769e7bc36450e36801b36e7003fd4d3 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Fri, 22 Sep 2023 20:56:21 +0200 Subject: [PATCH 20/33] WiFiS3 WiFiServer::accept() --- .../WiFiAdvancedChatServer.ino | 104 ++++++++++++++++++ .../WiFiAdvancedChatServer/arduino_secrets.h | 2 + libraries/WiFiS3/src/WiFiServer.cpp | 15 +++ libraries/WiFiS3/src/WiFiServer.h | 1 + 4 files changed, 122 insertions(+) create mode 100644 libraries/WiFiS3/examples/WiFiAdvancedChatServer/WiFiAdvancedChatServer.ino create mode 100644 libraries/WiFiS3/examples/WiFiAdvancedChatServer/arduino_secrets.h diff --git a/libraries/WiFiS3/examples/WiFiAdvancedChatServer/WiFiAdvancedChatServer.ino b/libraries/WiFiS3/examples/WiFiAdvancedChatServer/WiFiAdvancedChatServer.ino new file mode 100644 index 000000000..eb2e7cf66 --- /dev/null +++ b/libraries/WiFiS3/examples/WiFiAdvancedChatServer/WiFiAdvancedChatServer.ino @@ -0,0 +1,104 @@ +/* + Advanced WiFi Chat Server + + A more advanced server that distributes any incoming messages + to all connected clients but the client the message comes from. + To use, telnet to your device's IP address and type. + You can see the client's input in the serial monitor as well. + + */ + +#include + +#include "arduino_secrets.h" +///////please enter your sensitive data in the Secret tab/arduino_secrets.h +char ssid[] = SECRET_SSID; // your network SSID (name) +char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP) + +int status = WL_IDLE_STATUS; + +// telnet defaults to port 23 +WiFiServer server(23); + +WiFiClient clients[8]; + +void setup() { + //Initialize serial and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + // check for the WiFi module: + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + // don't continue + while (true); + } + + String fv = WiFi.firmwareVersion(); + if (fv < WIFI_FIRMWARE_LATEST_VERSION) { + Serial.println("Please upgrade the firmware"); + } + + // attempt to connect to WiFi network: + while (status != WL_CONNECTED) { + Serial.print("Attempting to connect to SSID: "); + Serial.println(ssid); + // Connect to WPA/WPA2 network. Change this line if using open or WEP network: + status = WiFi.begin(ssid, pass); + + // wait 10 seconds for connection: + delay(10000); + } + + // start the server: + server.begin(); + + Serial.print("Chat server address:"); + Serial.println(WiFi.localIP()); +} + +void loop() { + // check for any new client connecting, and say hello (before any incoming data) + WiFiClient newClient = server.accept(); + if (newClient) { + for (byte i=0; i < 8; i++) { + if (!clients[i]) { + Serial.print("We have a new client #"); + Serial.println(i); + newClient.print("Hello, client number: "); + newClient.println(i); + // Once we "accept", the client is no longer tracked by WiFiServer + // so we must store it into our list of clients + clients[i] = newClient; + break; + } + } + } + + // check for incoming data from all clients + for (byte i=0; i < 8; i++) { + if (clients[i] && clients[i].available() > 0) { + // read bytes from a client + byte buffer[80]; + int count = clients[i].read(buffer, 80); + // write the bytes to all other connected clients + for (byte j=0; j < 8; j++) { + if (j != i && clients[j].connected()) { + clients[j].write(buffer, count); + } + } + } + } + + // stop any clients which disconnect + for (byte i=0; i < 8; i++) { + if (clients[i] && !clients[i].connected()) { + Serial.print("disconnect client #"); + Serial.println(i); + clients[i].stop(); + } + } + +} diff --git a/libraries/WiFiS3/examples/WiFiAdvancedChatServer/arduino_secrets.h b/libraries/WiFiS3/examples/WiFiAdvancedChatServer/arduino_secrets.h new file mode 100644 index 000000000..0c9fdd556 --- /dev/null +++ b/libraries/WiFiS3/examples/WiFiAdvancedChatServer/arduino_secrets.h @@ -0,0 +1,2 @@ +#define SECRET_SSID "" +#define SECRET_PASS "" diff --git a/libraries/WiFiS3/src/WiFiServer.cpp b/libraries/WiFiS3/src/WiFiServer.cpp index 4f9cf88ed..94940d688 100644 --- a/libraries/WiFiS3/src/WiFiServer.cpp +++ b/libraries/WiFiS3/src/WiFiServer.cpp @@ -32,6 +32,21 @@ WiFiClient WiFiServer::available() { return WiFiClient(); } +/* -------------------------------------------------------------------------- */ +WiFiClient WiFiServer::accept() { +/* -------------------------------------------------------------------------- */ + if(_sock != -1) { + string res = ""; + modem.begin(); + /* call the server accept on esp so that the accept is performed */ + if(modem.write(string(PROMPT(_SERVERACCEPT)),res, "%s%d\r\n" , CMD_WRITE(_SERVERACCEPT), _sock)) { + int client_sock = atoi(res.c_str()); + return WiFiClient(client_sock); + } + } + return WiFiClient(); +} + /* -------------------------------------------------------------------------- */ void WiFiServer::begin(int port) { /* -------------------------------------------------------------------------- */ diff --git a/libraries/WiFiS3/src/WiFiServer.h b/libraries/WiFiS3/src/WiFiServer.h index 4e2652379..eb749330b 100644 --- a/libraries/WiFiS3/src/WiFiServer.h +++ b/libraries/WiFiS3/src/WiFiServer.h @@ -37,6 +37,7 @@ class WiFiServer : public Server { WiFiServer(); WiFiServer(int p); WiFiClient available(); + WiFiClient accept(); void begin(int port); void begin(); virtual size_t write(uint8_t); From 6b1c652324a5a88e0ed06612150d637b78477179 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 8 Feb 2024 13:16:14 +0100 Subject: [PATCH 21/33] WiFiSSLClient: remove unused function declaration --- libraries/WiFiS3/src/WiFiSSLClient.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/WiFiS3/src/WiFiSSLClient.h b/libraries/WiFiS3/src/WiFiSSLClient.h index f96830168..4e6f0baf3 100644 --- a/libraries/WiFiS3/src/WiFiSSLClient.h +++ b/libraries/WiFiS3/src/WiFiSSLClient.h @@ -64,9 +64,6 @@ class WiFiSSLClient : public WiFiClient { void getSocket(); int _read(); void read_if_needed(size_t s); - -private: - void upload_default_Cert(); }; #endif /* WIFISSLCLIENT_H */ From ef1a152f50c9a9bd444b4052af9c4b0975f40aa1 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Wed, 14 Feb 2024 10:14:31 +0100 Subject: [PATCH 22/33] Fix: do not randomly clear the first line of the LED matrix. This fixes #259. Instead the root cause for this issue was within ArduinoGraphics, for a detailed explanation see here: https://github.com/arduino-libraries/ArduinoGraphics/pull/36 . --- libraries/Arduino_LED_Matrix/src/Arduino_LED_Matrix.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libraries/Arduino_LED_Matrix/src/Arduino_LED_Matrix.h b/libraries/Arduino_LED_Matrix/src/Arduino_LED_Matrix.h index 32a199831..6cd4a26c9 100644 --- a/libraries/Arduino_LED_Matrix/src/Arduino_LED_Matrix.h +++ b/libraries/Arduino_LED_Matrix/src/Arduino_LED_Matrix.h @@ -265,10 +265,6 @@ class ArduinoLEDMatrix // display the drawing void endDraw() { ArduinoGraphics::endDraw(); - // clear first line (no idea why it gets filled with random bits, probably some math not working fine for super small displays) - for (int i = 0; i < canvasWidth; i++) { - _canvasBuffer[0][i] = 0; - } renderBitmap(_canvasBuffer, canvasHeight, canvasWidth); } From 350d5a8a8d49d78ad28a592c117cdb48c0d3b102 Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 14 Feb 2024 16:15:32 +0100 Subject: [PATCH 23/33] unor4wifi: update firmware submodule --- extras/uno-r4-wifi-usb-bridge | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/uno-r4-wifi-usb-bridge b/extras/uno-r4-wifi-usb-bridge index 3f4e668d1..a634856e5 160000 --- a/extras/uno-r4-wifi-usb-bridge +++ b/extras/uno-r4-wifi-usb-bridge @@ -1 +1 @@ -Subproject commit 3f4e668d1318feeaa7088c788e7fd88a26a5a671 +Subproject commit a634856e5467022bc7587e7c8a856811255ea890 From 1f47145c05b014b8b075444ef391f4fc2d5355e3 Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 14 Feb 2024 16:29:23 +0100 Subject: [PATCH 24/33] Preferences: add library examples to compile examples workflow --- .github/workflows/compile-examples.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml index 1de1bc4c6..5da349cf5 100644 --- a/.github/workflows/compile-examples.yml +++ b/.github/workflows/compile-examples.yml @@ -95,6 +95,7 @@ jobs: - libraries/WiFiS3 - libraries/OTAUpdate - libraries/OPAMP + - libraries/Preferences - board: fqbn: "arduino-git:renesas:minima" additional-sketch-paths: | From a50ecd035576f63bc4fc9f054871810705753c8e Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 14 Feb 2024 16:32:48 +0100 Subject: [PATCH 25/33] SoftwareATSE: add library examples to compile examples workflow --- .github/workflows/compile-examples.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples.yml index 1de1bc4c6..4d813e52d 100644 --- a/.github/workflows/compile-examples.yml +++ b/.github/workflows/compile-examples.yml @@ -95,6 +95,7 @@ jobs: - libraries/WiFiS3 - libraries/OTAUpdate - libraries/OPAMP + - libraries/SoftwareATSE - board: fqbn: "arduino-git:renesas:minima" additional-sketch-paths: | From 9efbd3c7dbc24fef272fd464b68f37288ec5423e Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 6 Feb 2024 14:57:36 +0100 Subject: [PATCH 26/33] WiFiSSLClient: add setEccSlot method to configure client private key and certificate --- libraries/WiFiS3/src/WiFiSSLClient.cpp | 11 +++++++++++ libraries/WiFiS3/src/WiFiSSLClient.h | 1 + 2 files changed, 12 insertions(+) diff --git a/libraries/WiFiS3/src/WiFiSSLClient.cpp b/libraries/WiFiS3/src/WiFiSSLClient.cpp index 92b66f01b..0a5efd18f 100644 --- a/libraries/WiFiS3/src/WiFiSSLClient.cpp +++ b/libraries/WiFiS3/src/WiFiSSLClient.cpp @@ -67,6 +67,17 @@ void WiFiSSLClient::setCACert(const char* root_ca, size_t size) { } } +/* -------------------------------------------------------------------------- */ +void WiFiSSLClient::setEccSlot(int ecc508KeySlot, const byte cert[], int certLength) { +/* -------------------------------------------------------------------------- */ + getSocket(); + string res = ""; + if(certLength > 0) { + modem.write_nowait(string(PROMPT(_SETECCSLOT)),res, "%s%d,%d,%d\r\n" , CMD_WRITE(_SETECCSLOT), _sock, ecc508KeySlot, certLength); + modem.passthrough((uint8_t *)cert, certLength); + } +} + /* -------------------------------------------------------------------------- */ size_t WiFiSSLClient::write(uint8_t b){ /* -------------------------------------------------------------------------- */ diff --git a/libraries/WiFiS3/src/WiFiSSLClient.h b/libraries/WiFiS3/src/WiFiSSLClient.h index 4e6f0baf3..59a585ed7 100644 --- a/libraries/WiFiS3/src/WiFiSSLClient.h +++ b/libraries/WiFiS3/src/WiFiSSLClient.h @@ -34,6 +34,7 @@ class WiFiSSLClient : public WiFiClient { virtual int connect(IPAddress ip, uint16_t port); virtual int connect(const char* host, uint16_t port); void setCACert(const char* root_ca = NULL, size_t size = 0); + void setEccSlot(int ecc508KeySlot, const byte cert[], int certLength); virtual size_t write(uint8_t); virtual size_t write(const uint8_t *buf, size_t size); virtual int available(); From 267cae554bd29bfd9da9d9fe37e05dded610bb33 Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 14 Feb 2024 17:07:30 +0100 Subject: [PATCH 27/33] WiFiSSLClient: configure cusutom root_ca or client credentials on connect --- libraries/WiFiS3/src/WiFiSSLClient.cpp | 12 ++++++++++-- libraries/WiFiS3/src/WiFiSSLClient.h | 6 +++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libraries/WiFiS3/src/WiFiSSLClient.cpp b/libraries/WiFiS3/src/WiFiSSLClient.cpp index 0a5efd18f..973e5700c 100644 --- a/libraries/WiFiS3/src/WiFiSSLClient.cpp +++ b/libraries/WiFiS3/src/WiFiSSLClient.cpp @@ -36,9 +36,14 @@ int WiFiSSLClient::connect(IPAddress ip, uint16_t port) { int WiFiSSLClient::connect(const char* host, uint16_t port) { /* -------------------------------------------------------------------------- */ getSocket(); - if (!_custom_root) { + if (_root_ca != nullptr) { + setCACert(_root_ca); + } else { setCACert(); } + if ((_ecc_slot != -1) && (_ecc_cert != nullptr) && (_ecc_cert_len != 0)) { + setEccSlot(_ecc_slot, _ecc_cert, _ecc_cert_len); + } string res = ""; if (_connectionTimeout) { if(modem.write(string(PROMPT(_SSLCLIENTCONNECT)),res, "%s%d,%s,%d,%d\r\n" , CMD_WRITE(_SSLCLIENTCONNECT), _sock, host,port, _connectionTimeout)) { @@ -60,7 +65,7 @@ void WiFiSSLClient::setCACert(const char* root_ca, size_t size) { if(size > 0) { modem.write_nowait(string(PROMPT(_SETCAROOT)),res, "%s%d,%d\r\n" , CMD_WRITE(_SETCAROOT), _sock, size); if(modem.passthrough((uint8_t *)root_ca, size)) { - _custom_root = true; + _root_ca = root_ca; } } else { modem.write(string(PROMPT(_SETCAROOT)),res, "%s%d\r\n" , CMD_WRITE(_SETCAROOT), _sock); @@ -75,6 +80,9 @@ void WiFiSSLClient::setEccSlot(int ecc508KeySlot, const byte cert[], int certLen if(certLength > 0) { modem.write_nowait(string(PROMPT(_SETECCSLOT)),res, "%s%d,%d,%d\r\n" , CMD_WRITE(_SETECCSLOT), _sock, ecc508KeySlot, certLength); modem.passthrough((uint8_t *)cert, certLength); + _ecc_slot = ecc508KeySlot; + _ecc_cert = cert; + _ecc_cert_len = certLength; } } diff --git a/libraries/WiFiS3/src/WiFiSSLClient.h b/libraries/WiFiS3/src/WiFiSSLClient.h index 59a585ed7..9f6f5c98e 100644 --- a/libraries/WiFiS3/src/WiFiSSLClient.h +++ b/libraries/WiFiS3/src/WiFiSSLClient.h @@ -61,10 +61,14 @@ class WiFiSSLClient : public WiFiClient { private: int _sock; - bool _custom_root = false; void getSocket(); int _read(); void read_if_needed(size_t s); + const char* _root_ca = nullptr; + int _ecc_slot = -1; + const byte* _ecc_cert = nullptr; + int _ecc_cert_len = 0; + }; #endif /* WIFISSLCLIENT_H */ From 59fc84e8bcc82696f3d5c7a8d7e0d631a0e8917c Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 15 Feb 2024 15:33:37 +0100 Subject: [PATCH 28/33] WiFiS3 WiFiSSLClient: avoid duplicated AT message calls using setCACert and setEccSlot - Also fix setCACert signature to be consistent with other core implementations --- libraries/WiFiS3/src/WiFiSSLClient.cpp | 57 +++++++++++++------------- libraries/WiFiS3/src/WiFiSSLClient.h | 2 +- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/libraries/WiFiS3/src/WiFiSSLClient.cpp b/libraries/WiFiS3/src/WiFiSSLClient.cpp index 973e5700c..f67c30896 100644 --- a/libraries/WiFiS3/src/WiFiSSLClient.cpp +++ b/libraries/WiFiS3/src/WiFiSSLClient.cpp @@ -36,54 +36,53 @@ int WiFiSSLClient::connect(IPAddress ip, uint16_t port) { int WiFiSSLClient::connect(const char* host, uint16_t port) { /* -------------------------------------------------------------------------- */ getSocket(); - if (_root_ca != nullptr) { - setCACert(_root_ca); + + /* if _root_ca is NULL it configures default root ca bundle */ + string res = ""; + if(_root_ca != nullptr) { + size_t size = strlen(_root_ca); + modem.write_nowait(string(PROMPT(_SETCAROOT)),res, "%s%d,%d\r\n" , CMD_WRITE(_SETCAROOT), _sock, size); + if(!modem.passthrough((uint8_t *)_root_ca, size)) { + return 0; + } } else { - setCACert(); + if(!modem.write(string(PROMPT(_SETCAROOT)),res, "%s%d\r\n" , CMD_WRITE(_SETCAROOT), _sock)) { + return 0; + } } - if ((_ecc_slot != -1) && (_ecc_cert != nullptr) && (_ecc_cert_len != 0)) { - setEccSlot(_ecc_slot, _ecc_cert, _ecc_cert_len); + + /* if needed configure software SE for mTLS */ + if((_ecc_cert_len > 0) && (_ecc_cert != nullptr) && (_ecc_slot >= 0)) { + modem.write_nowait(string(PROMPT(_SETECCSLOT)),res, "%s%d,%d,%d\r\n" , CMD_WRITE(_SETECCSLOT), _sock, _ecc_slot, _ecc_cert_len); + if(!modem.passthrough((uint8_t *)_ecc_cert, _ecc_cert_len)) { + return 0; + } } - string res = ""; + if (_connectionTimeout) { if(modem.write(string(PROMPT(_SSLCLIENTCONNECT)),res, "%s%d,%s,%d,%d\r\n" , CMD_WRITE(_SSLCLIENTCONNECT), _sock, host,port, _connectionTimeout)) { return 1; } } else { - if(modem.write(string(PROMPT(_SSLCLIENTCONNECTNAME)),res, "%s%d,%s,%d\r\n" , CMD_WRITE(_SSLCLIENTCONNECTNAME), _sock, host, port)) { - return 1; - } + if(modem.write(string(PROMPT(_SSLCLIENTCONNECTNAME)),res, "%s%d,%s,%d\r\n" , CMD_WRITE(_SSLCLIENTCONNECTNAME), _sock, host, port)) { + return 1; + } } return 0; } /* -------------------------------------------------------------------------- */ -void WiFiSSLClient::setCACert(const char* root_ca, size_t size) { +void WiFiSSLClient::setCACert(const char* root_ca) { /* -------------------------------------------------------------------------- */ - getSocket(); - string res = ""; - if(size > 0) { - modem.write_nowait(string(PROMPT(_SETCAROOT)),res, "%s%d,%d\r\n" , CMD_WRITE(_SETCAROOT), _sock, size); - if(modem.passthrough((uint8_t *)root_ca, size)) { - _root_ca = root_ca; - } - } else { - modem.write(string(PROMPT(_SETCAROOT)),res, "%s%d\r\n" , CMD_WRITE(_SETCAROOT), _sock); - } + _root_ca = root_ca; } /* -------------------------------------------------------------------------- */ void WiFiSSLClient::setEccSlot(int ecc508KeySlot, const byte cert[], int certLength) { /* -------------------------------------------------------------------------- */ - getSocket(); - string res = ""; - if(certLength > 0) { - modem.write_nowait(string(PROMPT(_SETECCSLOT)),res, "%s%d,%d,%d\r\n" , CMD_WRITE(_SETECCSLOT), _sock, ecc508KeySlot, certLength); - modem.passthrough((uint8_t *)cert, certLength); - _ecc_slot = ecc508KeySlot; - _ecc_cert = cert; - _ecc_cert_len = certLength; - } + _ecc_slot = ecc508KeySlot; + _ecc_cert = cert; + _ecc_cert_len = certLength; } /* -------------------------------------------------------------------------- */ diff --git a/libraries/WiFiS3/src/WiFiSSLClient.h b/libraries/WiFiS3/src/WiFiSSLClient.h index 9f6f5c98e..c021a0a16 100644 --- a/libraries/WiFiS3/src/WiFiSSLClient.h +++ b/libraries/WiFiS3/src/WiFiSSLClient.h @@ -33,7 +33,7 @@ class WiFiSSLClient : public WiFiClient { ~WiFiSSLClient(); virtual int connect(IPAddress ip, uint16_t port); virtual int connect(const char* host, uint16_t port); - void setCACert(const char* root_ca = NULL, size_t size = 0); + void setCACert(const char* root_ca); void setEccSlot(int ecc508KeySlot, const byte cert[], int certLength); virtual size_t write(uint8_t); virtual size_t write(const uint8_t *buf, size_t size); From d27eff5c542d6f84d8d04f2bbe1c0119c34d7bb0 Mon Sep 17 00:00:00 2001 From: Juraj Andrassy Date: Tue, 23 Jan 2024 19:55:04 +0100 Subject: [PATCH 29/33] ESPHost - fix softAP password check --- libraries/ESPhost/src/CCtrlWrapper.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/ESPhost/src/CCtrlWrapper.h b/libraries/ESPhost/src/CCtrlWrapper.h index ae5fd5d70..e84557845 100644 --- a/libraries/ESPhost/src/CCtrlWrapper.h +++ b/libraries/ESPhost/src/CCtrlWrapper.h @@ -729,8 +729,8 @@ class CCtrlMsgWrapper { cfg_ok = false; } - if((strlen((char *)&cfg.pwd) > MAX_PWD_LENGTH) || - ((cfg.encryption_mode == WIFI_AUTH_OPEN) && + if((cfg.encryption_mode != WIFI_AUTH_OPEN) && + ((strlen((char *)&cfg.pwd) > MAX_PWD_LENGTH) || (strlen((char *)&cfg.pwd) < MIN_PWD_LENGTH)) ) { /* INVALID BASS*/ Serial.println("[ERROR]: Invalid password"); From 358db484cb7843949335183a4af6e076ad2cdb9d Mon Sep 17 00:00:00 2001 From: Mattia Pennasilico Date: Fri, 16 Feb 2024 14:38:55 +0100 Subject: [PATCH 30/33] Update WIFI_FIRMWARE_LATEST_VERSION to 0.4.1 --- libraries/WiFiS3/src/WiFi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/WiFiS3/src/WiFi.h b/libraries/WiFiS3/src/WiFi.h index 9958b7c17..0cf1d31c9 100644 --- a/libraries/WiFiS3/src/WiFi.h +++ b/libraries/WiFiS3/src/WiFi.h @@ -14,7 +14,7 @@ #define DEFAULT_NM_AP_ADDRESS IPAddress(255,255,255,0) -#define WIFI_FIRMWARE_LATEST_VERSION "0.3.0" +#define WIFI_FIRMWARE_LATEST_VERSION "0.4.1" class CAccessPoint { public: From cb21927ec8f988ae99b7b21e683cf44a4a20e702 Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 16 Feb 2024 17:35:03 +0100 Subject: [PATCH 31/33] OTAUpdate: change root certificate to download binary from download.arduino.cc --- libraries/OTAUpdate/examples/OTA/root_ca.h | 172 ++++++++++-------- .../examples/WiFiFirmwareOTA/root_ca.h | 172 ++++++++++-------- 2 files changed, 190 insertions(+), 154 deletions(-) diff --git a/libraries/OTAUpdate/examples/OTA/root_ca.h b/libraries/OTAUpdate/examples/OTA/root_ca.h index ff7d2f738..57e61f92f 100644 --- a/libraries/OTAUpdate/examples/OTA/root_ca.h +++ b/libraries/OTAUpdate/examples/OTA/root_ca.h @@ -1,88 +1,106 @@ const char* root_ca = \ -/* Baltimore CyberTrust Root */ +/* GTS Root R1 */ "-----BEGIN CERTIFICATE-----\n" \ -"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\n" \ +"bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c\n" \ "-----END CERTIFICATE-----\n" \ -/* Amazon Root CA 1 */ +/* GTS Root R2 */ "-----BEGIN CERTIFICATE-----\n" \ -"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\n" \ +"6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL\n" \ "-----END CERTIFICATE-----\n" \ -/* Amazon Root CA 2 */ +/* GTS Root R3 */ "-----BEGIN CERTIFICATE-----\n" \ -"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\n" \ "-----END CERTIFICATE-----\n" \ -/* Amazon Root CA 3 */ +/* GTS Root R4 */ "-----BEGIN CERTIFICATE-----\n" \ -"MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG\n" \ -"EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy\n" \ -"NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ\n" \ -"MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB\n" \ -"f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr\n" \ -"Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43\n" \ -"rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc\n" \ -"eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw==\n" \ +"MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD\n" \ +"VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG\n" \ +"A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw\n" \ +"WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz\n" \ +"IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi\n" \ +"AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi\n" \ +"QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR\n" \ +"HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW\n" \ +"BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D\n" \ +"9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8\n" \ +"p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD\n" \ "-----END CERTIFICATE-----\n" \ -/* Amazon Root CA 4 */ +/* GlobalSign R4 */ "-----BEGIN CERTIFICATE-----\n" \ -"MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG\n" \ -"EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy\n" \ -"NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ\n" \ -"MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN\n" \ -"/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri\n" \ -"83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\n" \ -"HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA\n" \ -"MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1\n" \ -"AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA==\n" \ +"MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD\n" \ +"VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh\n" \ +"bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw\n" \ +"MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g\n" \ +"UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT\n" \ +"BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx\n" \ +"uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV\n" \ +"HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/\n" \ +"+wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147\n" \ +"bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm\n" \ "-----END CERTIFICATE-----\n"; diff --git a/libraries/OTAUpdate/examples/WiFiFirmwareOTA/root_ca.h b/libraries/OTAUpdate/examples/WiFiFirmwareOTA/root_ca.h index ff7d2f738..57e61f92f 100644 --- a/libraries/OTAUpdate/examples/WiFiFirmwareOTA/root_ca.h +++ b/libraries/OTAUpdate/examples/WiFiFirmwareOTA/root_ca.h @@ -1,88 +1,106 @@ const char* root_ca = \ -/* Baltimore CyberTrust Root */ +/* GTS Root R1 */ "-----BEGIN CERTIFICATE-----\n" \ -"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\n" \ +"bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c\n" \ "-----END CERTIFICATE-----\n" \ -/* Amazon Root CA 1 */ +/* GTS Root R2 */ "-----BEGIN CERTIFICATE-----\n" \ -"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\n" \ +"6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjWHYbL\n" \ "-----END CERTIFICATE-----\n" \ -/* Amazon Root CA 2 */ +/* GTS Root R3 */ "-----BEGIN CERTIFICATE-----\n" \ -"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\n" \ "-----END CERTIFICATE-----\n" \ -/* Amazon Root CA 3 */ +/* GTS Root R4 */ "-----BEGIN CERTIFICATE-----\n" \ -"MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG\n" \ -"EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy\n" \ -"NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ\n" \ -"MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB\n" \ -"f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr\n" \ -"Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43\n" \ -"rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc\n" \ -"eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw==\n" \ +"MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD\n" \ +"VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG\n" \ +"A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw\n" \ +"WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz\n" \ +"IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi\n" \ +"AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi\n" \ +"QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR\n" \ +"HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW\n" \ +"BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D\n" \ +"9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8\n" \ +"p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD\n" \ "-----END CERTIFICATE-----\n" \ -/* Amazon Root CA 4 */ +/* GlobalSign R4 */ "-----BEGIN CERTIFICATE-----\n" \ -"MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG\n" \ -"EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy\n" \ -"NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ\n" \ -"MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN\n" \ -"/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri\n" \ -"83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\n" \ -"HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA\n" \ -"MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1\n" \ -"AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA==\n" \ +"MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD\n" \ +"VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh\n" \ +"bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw\n" \ +"MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g\n" \ +"UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT\n" \ +"BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx\n" \ +"uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV\n" \ +"HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/\n" \ +"+wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147\n" \ +"bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm\n" \ "-----END CERTIFICATE-----\n"; From 390232902f491f2d90957dda78c9c1b326c7486f Mon Sep 17 00:00:00 2001 From: pennam Date: Fri, 16 Feb 2024 17:39:02 +0100 Subject: [PATCH 32/33] OTAUpdate: warn the user about what firmware will be installed on WiFi chip --- .../WiFiFirmwareOTA/WiFiFirmwareOTA.ino | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/libraries/OTAUpdate/examples/WiFiFirmwareOTA/WiFiFirmwareOTA.ino b/libraries/OTAUpdate/examples/WiFiFirmwareOTA/WiFiFirmwareOTA.ino index 4b84fa109..c86822fe9 100644 --- a/libraries/OTAUpdate/examples/WiFiFirmwareOTA/WiFiFirmwareOTA.ino +++ b/libraries/OTAUpdate/examples/WiFiFirmwareOTA/WiFiFirmwareOTA.ino @@ -27,6 +27,31 @@ int status = WL_IDLE_STATUS; OTAUpdate ota; static char const OTA_FILE_LOCATION[] = "https://downloads.arduino.cc/ota/UNOR4USBBridge.ino.ota"; +/* -------------------------------------------------------------------------- */ +bool waitResponse() { +/* -------------------------------------------------------------------------- */ + bool confirmation = false; + while (confirmation == false) { + if (Serial.available()) { + char choice = Serial.read(); + switch (choice) { + case 'y': + case 'Y': + confirmation = true; + return true; + break; + case 'n': + case 'N': + confirmation = true; + return false; + break; + default: + continue; + } + } + } +} + /* -------------------------------------------------------------------------- */ void setup() { /* -------------------------------------------------------------------------- */ @@ -64,6 +89,13 @@ void setup() { printWiFiStatus(); + Serial.println("\nWARNING! Running the sketch a test version of the WiFi firmware will be flashed on your board."); + Serial.println("Do you want to proceed? Y/[n]"); + + if (false == waitResponse()) { + return; + } + int ret = ota.begin(); if(ret != OTAUpdate::OTA_ERROR_NONE) { Serial.println("ota.begin() error: "); @@ -108,7 +140,7 @@ void loop() { /* -------------------------------------------------------------------------- */ String fv = WiFi.firmwareVersion(); - Serial.print("Updated Wi-Fi firmware version: "); + Serial.print("Wi-Fi firmware version: "); Serial.println(fv); delay(1000); } From ca1526336776f7fe216317ad645cfa83e30d2ec5 Mon Sep 17 00:00:00 2001 From: pennam Date: Mon, 26 Feb 2024 15:36:57 +0100 Subject: [PATCH 33/33] Publish 1.1.0 --- platform.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform.txt b/platform.txt index 22e6cae70..557f5a3df 100644 --- a/platform.txt +++ b/platform.txt @@ -3,7 +3,7 @@ # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification name=Arduino Renesas fsp Boards -version=1.0.5 +version=1.1.0 # Compile variables # ------------------------