diff --git a/ChangeLog.md b/ChangeLog.md index 09728ee..ed7c9a8 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,3 +1,76 @@ +# wolfSSL Release 5.8.4 (Nov. 20, 2025) + +Release 5.8.4 has been developed according to wolfSSL's development and QA +process (see link below) and successfully passed the quality criteria. +https://www.wolfssl.com/about/wolfssl-software-development-process-quality-assurance + +NOTE: * --enable-heapmath is deprecated + * MD5 is now disabled by default + +PR stands for Pull Request, and PR references a GitHub pull request number where the code change was added. + +## Vulnerabilities +* [Low CVE-2025-12888] Vulnerability in X25519 constant-time cryptographic implementations due to timing side channels introduced by compiler optimizations and CPU architecture limitations, specifically with the Xtensa-based ESP32 chips. If targeting Xtensa it is recommended to use the low memory implementations of X25519, which is now turned on as the default for Xtensa. Thanks to Adrian Cinal for the report. Fixed in PR 9275. + + +* [Med. CVE-2025-11936] Potential DoS vulnerability due to a memory leak through multiple KeyShareEntry with the same group in malicious TLS 1.3 ClientHello messages. This affects users who are running wolfSSL on the server side with TLS 1.3. Thanks to Jaehun Lee and Kyungmin Bae, Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9117. + +* [Low CVE-2025-11935] PSK with PFS (Perfect Forward Secrecy) downgrades to PSK without PFS during TLS 1.3 handshake. If the client sends a ClientHello that has a key share extension and the server responds with a ServerHello that does not have a key share extension the connection would previously continue on without using PFS. Thanks to Jaehun Lee from Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9112. + +* [Low CVE-2025-11934] Signature Algorithm downgrade from ECDSA P521 to P256 during TLS 1.3 handshake. When a client sends ECDSA P521 as the supported signature algorithm the server previously could respond as ECDSA P256 being the accepted signature algorithm and the connection would continue with using ECDSA P256. Thanks to Jaehun Lee from Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9113. + + +* [Low CVE-2025-11933] DoS Vulnerability in wolfSSL TLS 1.3 CKS extension parsing. Previously duplicate CKS extensions were not rejected leading to a potential memory leak when processing a ClientHello. Thanks to Jaehun Lee from Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9132. + + +* [Low CVE-2025-11931] Integer Underflow Leads to Out-of-Bounds Access in XChaCha20-Poly1305 Decrypt. This issue is hit specifically with a call to the function wc_XChaCha20Poly1305_Decrypt() which is not used with TLS connections, only from direct calls from an application. Thanks to Luigino Camastra from Aisle Research for the report. Fixed in PR 9223. + +* [Low CVE-2025-11932] Timing Side-Channel in PSK Binder Verification. The server previously verified the TLS 1.3 PSK binder using a non-constant time method which could potentially leak information about the PSK binder. Thanks to Luigino Camastra from Aisle Research for the report. Fixed in PR 9223. + +* [Low CVE-2025-12889] With TLS 1.2 connections a client can use any digest, specifically a weaker digest, rather than those in the CertificateRequest. Thanks to Jaehun Lee from Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9395 + +## New Features +* New ML-KEM / ML-DSA APIs and seed/import PKCS8 support; added _new/_delete APIs for ML-KEM/ML-DSA. (PR 9039, 9000, 9049) +* Initial wolfCrypt FreeBSD kernel module support (PR 9392) +* Expanded PKCS7/CMS capabilities: decode SymmetricKeyPackage / OneSymmetricKey, add wc_PKCS7_GetEnvelopedDataKariRid, and allow PKCS7 builds with AES keywrap unset. (PR 9018, 9029, 9032) +* Add custom AES key wrap/unwrap callbacks and crypto callback copy/free operations. (PR 9002, 9309) +* Add support for certificate_authorities extension in ClientHello and certificate manager CA-type selection/unloading. (PR 9209, 9046) +* Large expansion of Rust wrapper modules: random, aes, rsa, ecc, dh, sha, hmac, cmac, ed25519/ed448, pbkdf2/PKCS#12, kdf/prf, SRTP KDFs, and conditional compilation options. (PR 9191, 9212, 9273, 9306, 9320, 9328, 9368, 9389, 9357, 9433) +* Rust: support optional heap and dev_id parameters and enable conditional compilation based on C build options. (PR 9407, 9433) +* STM32 fixes (benchmarking and platform fixes) and PSoC6 hardware acceleration additions. (PR 9228, 9256, 9185) +* STM32U5 added support for SAES and DHUK. (PR 9087) +* Add --enable-curl=tiny option for a smaller build when used with cURL. (PR 9174) + +## Improvements / Optimizations +* Regression test fixes and expansion: TLS 1.3/1.2 tests, ARDUINO examples, libssh2 tests, hostap workflows, and nightly test improvements. (PR 9096, 9141, 9091, 9122, 9388) +* Improved test ordering and CI test stability (random tests run order changes, FIPS test fixes). (PR 9204, 9257) +* Docs and readme fixes, docstring updates, AsconAEAD comment placement, and example certificate renewals. (PR 9131, 9293, 9262, 9429) +* Updated GPL exception lists (GPLv2 and GPLv3 exception updates: add Fetchmail and OpenVPN). (PR 9398, 9413) +* Introduced WOLFSSL_DEBUG_CERTS and additional debug/logging refinements. (PR 8902, 9055) +* Expanded crypto-callback support (SHA family, HKDF, SHA-224, sha512_family digest selection) and improved crypto-only build cases. (PR 9070, 9252, 9271, 9100, 9194) +* AES & HW offload improvements including AES-CTR support in PKCS11 driver and AES ECB offload sizing fix. (PR 9277, 9364) +* ESP32: PSRAM allocator support and SHA HW fixes for ESP-IDF v6/v5. (PR 8987, 9225, 9264) +* Renesas FSP / RA examples updated and security-module TLS context improvements. (PR 9047, 9010, 9158, 9150) +* Broad configure/CMake/Autotools workflow improvements (Apple options tracking, Watcom pinning, Debian packaging, ESP-IDF pinning). (PR 9037, 9167, 9161, 9264) +* New assembly introspection / performance helpers for RISC-V and PPC32; benchmarking enhancements (cycle counts). (PR 9101, 9317) +* Update to SGX build for using assembly optimizations. (PR 8463, 9138) +* Testing with Fil-C compiler version to 0.674 (PR 9396) +* Refactors and compressing of small stack code (PR 9153) + +## Bug Fixes +* Removed the test feature using popen when defining the macro WOLFSSL_USE_POPEN_HOST and not having HAVE_GETADDRINFO defined, along with having the macro HAVE_HTTP_CLIENT set. There was the potential for vulnerable behavior with the use of popen when the API wolfSSL_BIO_new_connect() was called with this specific build. This exact build configuration is only intended for testing with QEMU and is not enabled with any autoconf/cmake flags. Thanks to linraymond2006 for the report. (PR 9038) +* Fix for C# wrapper Ed25519 potential crash and heap overwrite with raw public key import when using the API Ed25519ImportPublic.This was a broken API with the C# wrapper that would crash on use. Thanks to Luigino Camastra from Aisle Research for the bug report. (PR 9291) +* Coverity, cppcheck, MISRA, clang-tidy, ZeroPath and other static-analysis driven fixes across the codebase. (PR 9006, 9078, 9068, 9265, 9324) +* TLS 1.2/DTLS improvements: client message order checks, DTLS cookie/exchange and replay protections, better DTLS early-data handling. (PR 9387, 9253, 9205, 9367) +* Improved X.509 & cert handling: allow larger pathLen in Basic Constraints, restore inner server name for ECH, retrying cert candidate chains. (PR 8890, 9234, 8692) +* Sniffer robustness: fix infinite recursion, better handling of OOO appData and partial overlaps, and improved retransmission detection. (PR 9051, 9106, 9140, 9094) +* Numerous linuxkm (kernel-mode) fixes, relocation/PIE normalization, and FIPS-related build tweaks across many iterations. (PR 9025, 9035, 9067, 9111, 9121) +* ML-KEM/Kyber and ML-DSA fixes for out-of-bounds and seed-import correctness; multiple ML-related safety fixes. (PR 9142, 9105, 9439) +* Avoid uninitialized-variable and GCC warnings; several fixes for undefined-shift/overflow issues. (PR 9020, 9372, 9195) +* Memory & leak fixes in X509 verification and various struct sizing fixes for WOLFSSL_NO_MALLOC usage. (PR 9258, 9036) +* Fixed RSA / signing / verify-only warnings allowing WOLFSSL_NO_CT_OPS when WOLFSSL_RSA_VERIFY_ONLY is used and API cleanups for using const. (PR 9031, 9263) + + # wolfSSL Release 5.8.2 (July 17, 2025) Release 5.8.2 has been developed according to wolfSSL's development and QA @@ -9,7 +82,7 @@ NOTE: * wolfSSL is now GPLv3 instead of GPLv2 * MD5 is now disabled by default -PR stands for Pull Request, and PR references a GitHub pull request number where the code change was added. +PR stands for Pull Request, and PR (NUMBER) references a GitHub pull request number where the code change was added. ## Vulnerabilities @@ -68,7 +141,8 @@ Blinding enabled by default in PR https://github.com/wolfSSL/wolfssl/pull/8736 * Implemented distro fix for the Linux Kernel Module. (PR #8994) * Fixed page-flags-h in the Linux Kernel Module. (PR #9001) * Added MODULE_LICENSE for the Linux Kernel Module. (PR #9005) -* Post-Quantum Cryptography (PQC) & Asymmetric Algorithms + +### Post-Quantum Cryptography (PQC) & Asymmetric Algorithms * Kyber has been updated to the MLKEM ARM file for Zephyr (PR #8781) * Backward compatibility has been implemented for ML_KEM IDs (PR #8827) * ASN.1 is now ensured to be enabled when only building PQ algorithms (PR #8884) @@ -207,7 +281,7 @@ https://www.wolfssl.com/about/wolfssl-software-development-process-quality-assur NOTE: * --enable-heapmath is deprecated -PR stands for Pull Request, and PR references a GitHub pull request +PR stands for Pull Request, and PR (NUMBER) references a GitHub pull request number where the code change was added. @@ -423,7 +497,7 @@ NOTE: user_settings.h. -PR stands for Pull Request, and PR references a GitHub pull request +PR stands for Pull Request, and PR (NUMBER) references a GitHub pull request number where the code change was added. @@ -543,7 +617,7 @@ https://www.wolfssl.com/about/wolfssl-software-development-process-quality-assur NOTE: * --enable-heapmath is being deprecated and will be removed by end of 2024 -PR stands for Pull Request, and PR references a GitHub pull request +PR stands for Pull Request, and PR (NUMBER) references a GitHub pull request number where the code change was added. diff --git a/LICENSING b/LICENSING index cf1d098..14b0801 100644 --- a/LICENSING +++ b/LICENSING @@ -1,9 +1,24 @@ +The wolfSSL, Inc. software (“wolfSSL Software”) to which this text is appended +is made available under the GNU General Public License version 3 (“GPLv3”) with +the following exception: When this wolfSSL Software is combined with the +software listed below (“Exception Software”), licensee may elect to license +this wolfSSL Software under the GNU General Public License version 2 (“GPLv2”) +instead of GPLv3. -wolfSSL (formerly known as CyaSSL) and wolfCrypt are either licensed for use -under the GPLv3 (or at your option any later version) or a standard commercial -license. For our users who cannot use wolfSSL under GPLv3 -(or any later version), a commercial license to wolfSSL and wolfCrypt is -available. +Exception Software: + +MariaDB Server + +MariaDB Client Libraries + +OpenVPN-NL + +Fetchmail + +OpenVPN + +For our users who cannot use wolfSSL under GPLv3, a commercial license to +wolfSSL and wolfCrypt is available. Please contact wolfSSL Inc. directly at: diff --git a/README b/README index a8e5f76..6a0e29a 100644 --- a/README +++ b/README @@ -29,24 +29,29 @@ of the wolfSSL manual. (https://www.wolfssl.com/docs/wolfssl-manual/ch4/) *** Notes, Please read *** Note 1) -wolfSSL as of 3.6.6 no longer enables SSLv3 by default. wolfSSL also no longer -supports static key cipher suites with PSK, RSA, or ECDH. This means if you -plan to use TLS cipher suites you must enable DH (DH is on by default), or -enable ECC (ECC is on by default), or you must enable static key cipher suites -with - - WOLFSSL_STATIC_DH - WOLFSSL_STATIC_RSA - or - WOLFSSL_STATIC_PSK - -though static key cipher suites are deprecated and will be removed from future -versions of TLS. They also lower your security by removing PFS. - -When compiling ssl.c, wolfSSL will now issue a compiler error if no cipher +wolfSSL as of 3.6.6 no longer enables SSLv3 by default. By default, wolfSSL +disables static key cipher suites that use PSK, RSA, or ECDH without ephemeral +key exchange. Instead, wolfSSL enables cipher suites that provide perfect +forward secrecy (PFS) using ephemeral Diffie-Hellman (DH) or Elliptic Curve +(ECC) key exchange, both of which are enabled by default. + +If you need to support legacy systems that require static key cipher suites, +you can enable them using one or more of these defines: + +WOLFSSL_STATIC_DH +WOLFSSL_STATIC_RSA +WOLFSSL_STATIC_PSK + +Important: Static key cipher suites reduce security by eliminating perfect +forward secrecy. These cipher suites reuse the same long-term private key for +all session key exchanges. In contrast, PFS-enabled cipher suites (the wolfSSL +default) generate a new ephemeral key for each session, ensuring that +compromising a long-term key cannot decrypt past sessions. + +When compiling `ssl.c`, wolfSSL will now issue a compiler error if no cipher suites are available. You can remove this error by defining -WOLFSSL_ALLOW_NO_SUITES in the event that you desire that, i.e., you're not -using TLS cipher suites. +`WOLFSSL_ALLOW_NO_SUITES` in the event that you desire that, i.e., you're +not using TLS cipher suites. Note 2) wolfSSL takes a different approach to certificate verification than OpenSSL @@ -70,205 +75,77 @@ should be used for the enum name. *** end Notes *** -# wolfSSL Release 5.8.2 (July 17, 2025) +# wolfSSL Release 5.8.4 (Nov. 20, 2025) -Release 5.8.2 has been developed according to wolfSSL's development and QA +Release 5.8.4 has been developed according to wolfSSL's development and QA process (see link below) and successfully passed the quality criteria. https://www.wolfssl.com/about/wolfssl-software-development-process-quality-assurance -NOTE: * wolfSSL is now GPLv3 instead of GPLv2 - * --enable-heapmath is deprecated +NOTE: * --enable-heapmath is deprecated * MD5 is now disabled by default - PR stands for Pull Request, and PR references a GitHub pull request number where the code change was added. ## Vulnerabilities +* [Low CVE-2025-12888] Vulnerability in X25519 constant-time cryptographic implementations due to timing side channels introduced by compiler optimizations and CPU architecture limitations, specifically with the Xtensa-based ESP32 chips. If targeting Xtensa it is recommended to use the low memory implementations of X25519, which is now turned on as the default for Xtensa. Thanks to Adrian Cinal for the report. Fixed in PR 9275. -* [Low] There is the potential for a fault injection attack on ECC and Ed25519 verify operations. In versions of wolfSSL 5.7.6 and later the --enable-faultharden option is available to help mitigate against potential fault injection attacks. The mitigation added in wolfSSL version 5.7.6 is to help harden applications relying on the results of the verify operations, such as when used with wolfBoot. If doing ECC or Ed25519 verify operations on a device at risk for fault injection attacks then --enable-faultharden could be used to help mitigate it. Thanks to Kevin from Fraunhofer AISEC for the report. -Hardening option added in PR https://github.com/wolfSSL/wolfssl/pull/8289 +* [Med. CVE-2025-11936] Potential DoS vulnerability due to a memory leak through multiple KeyShareEntry with the same group in malicious TLS 1.3 ClientHello messages. This affects users who are running wolfSSL on the server side with TLS 1.3. Thanks to Jaehun Lee and Kyungmin Bae, Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9117. +* [Low CVE-2025-11935] PSK with PFS (Perfect Forward Secrecy) downgrades to PSK without PFS during TLS 1.3 handshake. If the client sends a ClientHello that has a key share extension and the server responds with a ServerHello that does not have a key share extension the connection would previously continue on without using PFS. Thanks to Jaehun Lee from Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9112. -* [High CVE-2025-7395] When using WOLFSSL_SYS_CA_CERTS and WOLFSSL_APPLE_NATIVE_CERT_VALIDATION on an Apple platform, the native trust store verification routine overrides errors produced elsewhere in the wolfSSL certificate verification process including failures due to hostname matching/SNI, OCSP, CRL, etc. This allows any trusted cert chain to override other errors detected during chain verification that should have resulted in termination of the TLS connection. If building wolfSSL on versions after 5.7.6 and before 5.8.2 with use of the system CA support and the apple native cert validation feature enabled on Apple devices (on by default for non-macOS Apple targets when using autotools or CMake) we recommend updating to the latest version of wolfSSL. Thanks to Thomas Leong from ExpressVPN for the report. +* [Low CVE-2025-11934] Signature Algorithm downgrade from ECDSA P521 to P256 during TLS 1.3 handshake. When a client sends ECDSA P521 as the supported signature algorithm the server previously could respond as ECDSA P256 being the accepted signature algorithm and the connection would continue with using ECDSA P256. Thanks to Jaehun Lee from Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9113. -Fixed in PR https://github.com/wolfSSL/wolfssl/pull/8833 +* [Low CVE-2025-11933] DoS Vulnerability in wolfSSL TLS 1.3 CKS extension parsing. Previously duplicate CKS extensions were not rejected leading to a potential memory leak when processing a ClientHello. Thanks to Jaehun Lee from Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9132. -* [Med. CVE-2025-7394] In the OpenSSL compatibility layer implementation, the function RAND_poll() was not behaving as expected and leading to the potential for predictable values returned from RAND_bytes() after fork() is called. This can lead to weak or predictable random numbers generated in applications that are both using RAND_bytes() and doing fork() operations. This only affects applications explicitly calling RAND_bytes() after fork() and does not affect any internal TLS operations. Although RAND_bytes() documentation in OpenSSL calls out not being safe for use with fork() without first calling RAND_poll(), an additional code change was also made in wolfSSL to make RAND_bytes() behave similar to OpenSSL after a fork() call without calling RAND_poll(). Now the Hash-DRBG used gets reseeded after detecting running in a new process. If making use of RAND_bytes() and calling fork() we recommend updating to the latest version of wolfSSL. Thanks to Per Allansson from Appgate for the report. -Fixed in the following PR’s -https://github.com/wolfSSL/wolfssl/pull/8849 -https://github.com/wolfSSL/wolfssl/pull/8867 -https://github.com/wolfSSL/wolfssl/pull/8898 +* [Low CVE-2025-11931] Integer Underflow Leads to Out-of-Bounds Access in XChaCha20-Poly1305 Decrypt. This issue is hit specifically with a call to the function wc_XChaCha20Poly1305_Decrypt() which is not used with TLS connections, only from direct calls from an application. Thanks to Luigino Camastra from Aisle Research for the report. Fixed in PR 9223. +* [Low CVE-2025-11932] Timing Side-Channel in PSK Binder Verification. The server previously verified the TLS 1.3 PSK binder using a non-constant time method which could potentially leak information about the PSK binder. Thanks to Luigino Camastra from Aisle Research for the report. Fixed in PR 9223. - -* [Low CVE-2025-7396] In wolfSSL 5.8.0 the option of hardening the C implementation of Curve25519 private key operations was added with the addition of blinding support (https://www.wolfssl.com/curve25519-blinding-support-added-in-wolfssl-5-8-0/). In wolfSSL release 5.8.2 that blinding support is turned on by default in applicable builds. The blinding configure option is only for the base C implementation of Curve25519. It is not needed, or available with; ARM assembly builds, Intel assembly builds, and the small Curve25519 feature. While the attack would be very difficult to execute in practice, enabling blinding provides an additional layer of protection for devices that may be more susceptible to physical access or side-channel observation. Thanks to Arnaud Varillon, Laurent Sauvage, and Allan Delautre from Telecom Paris for the report. - -Blinding enabled by default in PR https://github.com/wolfSSL/wolfssl/pull/8736 - +* [Low CVE-2025-12889] With TLS 1.2 connections a client can use any digest, specifically a weaker digest, rather than those in the CertificateRequest. Thanks to Jaehun Lee from Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9395 ## New Features -* Multiple sessions are now supported in the sniffer due to the removal of a cached check. (PR #8723) -* New API ssl_RemoveSession() has been implemented for sniffer cleanup operations. (PR #8768) -* The new ASN X509 API, `wc_GetSubjectPubKeyInfoDerFromCert`, has been introduced for retrieving public key information from certificates. (PR #8758) -* `wc_PKCS12_create()` has been enhanced to support PBE_AES(256|128)_CBC key and certificate encryptions. (PR #8782, PR #8822, PR #8859) -* `wc_PKCS7_DecodeEncryptedKeyPackage()` has been added for decoding encrypted key packages. (PR #8976) -* All AES, SHA, and HMAC functionality has been implemented within the Linux Kernel Module. (PR #8998) -* Additions to the compatibility layer have been introduced for X.509 extensions and RSA PSS. Adding the API i2d_PrivateKey_bio, BN_ucmp and X509v3_get_ext_by_NID. (PR #8897) -* Added support for STM32N6. (PR #8914) -* Implemented SHA-256 for PPC 32 assembly. (PR #8894) +* New ML-KEM / ML-DSA APIs and seed/import PKCS8 support; added _new/_delete APIs for ML-KEM/ML-DSA. (PR 9039, 9000, 9049) +* Initial wolfCrypt FreeBSD kernel module support (PR 9392) +* Expanded PKCS7/CMS capabilities: decode SymmetricKeyPackage / OneSymmetricKey, add wc_PKCS7_GetEnvelopedDataKariRid, and allow PKCS7 builds with AES keywrap unset. (PR 9018, 9029, 9032) +* Add custom AES key wrap/unwrap callbacks and crypto callback copy/free operations. (PR 9002, 9309) +* Add support for certificate_authorities extension in ClientHello and certificate manager CA-type selection/unloading. (PR 9209, 9046) +* Large expansion of Rust wrapper modules: random, aes, rsa, ecc, dh, sha, hmac, cmac, ed25519/ed448, pbkdf2/PKCS#12, kdf/prf, SRTP KDFs, and conditional compilation options. (PR 9191, 9212, 9273, 9306, 9320, 9328, 9368, 9389, 9357, 9433) +* Rust: support optional heap and dev_id parameters and enable conditional compilation based on C build options. (PR 9407, 9433) +* STM32 fixes (benchmarking and platform fixes) and PSoC6 hardware acceleration additions. (PR 9228, 9256, 9185) +* STM32U5 added support for SAES and DHUK. (PR 9087) +* Add --enable-curl=tiny option for a smaller build when used with cURL. (PR 9174) ## Improvements / Optimizations - -### Linux Kernel Module (LinuxKM) Enhancements -* Registered DH and FFDHE for the Linux Kernel Module. (PR #8707) -* Implemented fixes for standard RNG in the Linux Kernel Module. (PR #8718) -* Added an ECDSA workaround for the Linux Kernel Module. (PR #8727) -* Added more PKCS1 pad SHA variants for RSA in the Linux Kernel Module. (PR #8730) -* Set default priority to 100000 for LKCAPI in the Linux Kernel Module. (PR #8740) -* Ensured ECDH never has FIPS enabled in the Linux Kernel Module. (PR #8751) -* Implemented further Linux Kernel Module and SP tweaks. (PR #8773) -* Added sig_alg support for Linux 6.13 RSA in the Linux Kernel Module. (PR #8796) -* Optimized wc_linuxkm_fpu_state_assoc. (PR #8828) -* Ensured DRBG is multithread-round-1 in the Linux Kernel Module. (PR #8840) -* Prevented toggling of fips_enabled in the Linux Kernel Module. (PR #8873) -* Refactored drbg_ctx clear in the Linux Kernel Module. (PR #8876) -* Set sig_alg max_size and digest_size callbacks for RSA in the Linux Kernel Module. (PR #8915) -* Added get_random_bytes for the Linux Kernel Module. (PR #8943) -* Implemented distro fix for the Linux Kernel Module. (PR #8994) -* Fixed page-flags-h in the Linux Kernel Module. (PR #9001) -* Added MODULE_LICENSE for the Linux Kernel Module. (PR #9005) -* Post-Quantum Cryptography (PQC) & Asymmetric Algorithms -* Kyber has been updated to the MLKEM ARM file for Zephyr (PR #8781) -* Backward compatibility has been implemented for ML_KEM IDs (PR #8827) -* ASN.1 is now ensured to be enabled when only building PQ algorithms (PR #8884) -* Building LMS with verify-only has been fixed (PR #8913) -* Parameters for LMS SHA-256_192 have been corrected (PR #8912) -* State can now be saved with the private key for LMS (PR #8836) -* Support for OpenSSL format has been added for ML-DSA/Dilithium (PR #8947) -* `dilithium_coeff_eta2[]` has been explicitly declared as signed (PR #8955) - -### Build System & Portability -* Prepared for the inclusion of v5.8.0 in the Ada Alire index. (PR #8714) -* Introduced a new build option to allow reuse of the Windows crypt provider handle. (PR #8706) -* Introduced general fixes for various build configurations. (PR #8763) -* Made improvements for portability using older GCC 4.8.2. (PR #8753) -* Macro guards updated to allow tests to build with opensslall and no server. (PR #8776) -* Added a check for STDC_NO_ATOMICS macro before use of atomics. (PR #8885) -* Introduced CMakePresets.json and CMakeSettings.json. (PR #8905) -* Added an option to not use constant time code with min/max. (PR #8830) -* Implemented proper MacOS dispatch for conditional signal/wait. (PR #8928) -* Disabled MD5 by default for both general and CMake builds. (PR #8895, PR #8948) -* Improved to allow building OPENSSL_EXTRA without KEEP_PEER_CERT. (PR #8926) -* Added introspection for Intel and ARM assembly speedups. (PR #8954) -* Fixed cURL config to set HAVE_EX_DATA and HAVE_ALPN. (PR #8973) -* Moved FREESCALE forced algorithm HAVE_ECC to IDE/MQX/user_settings.h. (PR #8977) - -### Testing & Debugging -* Fixed the exit status for testwolfcrypt. (PR #8762) -* Added WOLFSSL_DEBUG_PRINTF and WOLFSSL_DEBUG_CERTIFICATE_LOADS for improved debugging output. (PR #8769, PR #8770) -* Guarded some benchmark tests with NO_SW_BENCH. (PR #8760) -* Added an additional unit test for wolfcrypt PKCS12 file to improve code coverage. (PR #8831) -* Added an additional unit test for increased DH code coverage. (PR #8837) -* Adjusted for warnings with NO_TLS build and added GitHub actions test. (PR #8851) -* Added additional compatibility layer RAND tests. (PR #8852) -* Added an API unit test for checking domain name. (PR #8863) -* Added bind v9.18.33 testing. (PR #8888) -* Fixed issue with benchmark help options and descriptions not lining up. (PR #8957) - -### Certificates & ASN.1 -* Changed the algorithm for sum in ASN.1 OIDs. (PR #8655) -* Updated PKCS7 to use X509 STORE for internal verification. (PR #8748) -* Improved handling of temporary buffer size for X509 extension printing. (PR #8710) -* Marked IP address as WOLFSSL_V_ASN1_OCTET_STRING for ALT_NAMES_OID. (PR #8842) -* Fixed printing empty names in certificates. (PR #8880) -* Allowed CA:FALSE on wolftpm. (PR #8925) -* Fixed several inconsistent function prototype parameter names in wc/asn. (PR #8949) -* Accounted for custom extensions when creating a Cert from a WOLFSSL_X509. (PR #8960) - -### TLS/DTLS & Handshake -* Checked group correctness outside of TLS 1.3 too for TLSX_UseSupportedCurve. (PR #8785) -* Dropped records that span datagrams in DTLS. (PR #8642) -* Implemented WC_NID_netscape_cert_type. (PR #8800) -* Refactored GetHandshakeHeader/GetHandShakeHeader into one function. (PR #8787) -* Correctly set the current peer in dtlsProcessPendingPeer. (PR #8848) -* Fixed set_groups for TLS. (PR #8824) -* Allowed trusted_ca_keys with TLSv1.3. (PR #8860) -* Moved Dtls13NewEpoch into DeriveTls13Keys. (PR #8858) -* Cleared tls1_3 on downgrade. (PR #8861) -* Always sent ACKs on detected retransmission for DTLS1.3. (PR #8882) -* Removed DTLS from echo examples. (PR #8889) -* Recalculated suites at SSL initialization. (PR #8757) -* No longer using BIO for ALPN. (PR #8969) -* Fixed wolfSSL_BIO_new_connect's handling of IPV6 addresses. (PR #8815) -* Memory Management & Optimizations -* Performed small stack refactors, improved stack size with mlkem and dilithium, and added additional tests. (PR #8779) -* Implemented FREE_MP_INT_SIZE in heap math. (PR #8881) -* Detected correct MAX_ENCODED_SIG_SZ based on max support in math lib. (PR #8931) -* Fixed improper access of sp_int_minimal using sp_int. (PR #8985) - -### Cryptography & Hash Functions -* Implemented WC_SIPHASH_NO_ASM for not using assembly optimizations with siphash. (PR #8789, PR #8791) -* Added missing DH_MAX_SIZE define for FIPS and corrected wolfssl.rc FILETYPE to VFT_DLL. (PR #8794) -* Implemented WC_SHA3_NO_ASM for not using assembly with SHA3. (PR #8817) -* Improved Aarch64 XFENCE. (PR #8832) -* Omitted frame pointer for ARM32/Thumb2/RISC-V 64 assembly. (PR #8893) -* Fixed branch instruction in ARMv7a ASM. (PR #8933) -* Enabled EVP HMAC to work with WOLFSSL_HMAC_COPY_HASH. (PR #8944) -* Platform-Specific & Hardware Integration -* Added HAVE_HKDF for wolfssl_test and explicit support for ESP32P4. (PR #8742) -* Corrected Espressif default time setting. (PR #8829) -* Made wc_tsip_* APIs public. (PR #8717) -* Improved PlatformIO Certificate Bundle Support. (PR #8847) -* Fixed the TSIP TLS example program. (PR #8857) -* Added crypto callback functions for TROPIC01 secure element. (PR #8812) -* Added Renesas RX TSIP AES CTR support. (PR #8854) -* Fixed TSIP port using crypto callback. (PR #8937) - -### General Improvements & Refactoring -* Attempted wolfssl_read_bio_file in read_bio even when XFSEEK is available. (PR #8703) -* Refactored GetHandshakeHeader/GetHandShakeHeader into one function. (PR #8787) -* Updated libspdm from 3.3.0 to 3.7.0. (PR #8906) -* Fixed missing dashes on the end of header and footer for Falcon PEM key. (PR #8904) -* Fixed minor code typos for macos signal and types.h max block size. (PR #8934) -* Make the API wolfSSL_X509_STORE_CTX_get_error accessible to more build configurations for ease of getting the "store" error code and depth with certificate failure callback implementations. (PR #8903) +* Regression test fixes and expansion: TLS 1.3/1.2 tests, ARDUINO examples, libssh2 tests, hostap workflows, and nightly test improvements. (PR 9096, 9141, 9091, 9122, 9388) +* Improved test ordering and CI test stability (random tests run order changes, FIPS test fixes). (PR 9204, 9257) +* Docs and readme fixes, docstring updates, AsconAEAD comment placement, and example certificate renewals. (PR 9131, 9293, 9262, 9429) +* Updated GPL exception lists (GPLv2 and GPLv3 exception updates: add Fetchmail and OpenVPN). (PR 9398, 9413) +* Introduced WOLFSSL_DEBUG_CERTS and additional debug/logging refinements. (PR 8902, 9055) +* Expanded crypto-callback support (SHA family, HKDF, SHA-224, sha512_family digest selection) and improved crypto-only build cases. (PR 9070, 9252, 9271, 9100, 9194) +* AES & HW offload improvements including AES-CTR support in PKCS11 driver and AES ECB offload sizing fix. (PR 9277, 9364) +* ESP32: PSRAM allocator support and SHA HW fixes for ESP-IDF v6/v5. (PR 8987, 9225, 9264) +* Renesas FSP / RA examples updated and security-module TLS context improvements. (PR 9047, 9010, 9158, 9150) +* Broad configure/CMake/Autotools workflow improvements (Apple options tracking, Watcom pinning, Debian packaging, ESP-IDF pinning). (PR 9037, 9167, 9161, 9264) +* New assembly introspection / performance helpers for RISC-V and PPC32; benchmarking enhancements (cycle counts). (PR 9101, 9317) +* Update to SGX build for using assembly optimizations. (PR 8463, 9138) +* Testing with Fil-C compiler version to 0.674 (PR 9396) +* Refactors and compressing of small stack code (PR 9153) ## Bug Fixes -* Fixed issues to support _WIN32_WCE (VS 2008 with WinCE 6.0/7.0). (PR #8709) -* Fixed STM32 Hash with IRQ enabled. (PR #8705) -* Fixed raw hash when using crypto instructions on RISC-V 64-bit. (PR #8733) -* Fixed ECDH decode secret in the Linux Kernel Module. (PR #8729) -* Passed in the correct hash type to wolfSSL_RSA_verify_ex. (PR #8726) -* Fixed issues for Intel QuickAssist latest driver (4.28). (PR #8728) -* Speculative fix for CodeSonar overflow issue in ssl_certman.c. (PR #8715) -* Fixed Arduino progmem print and AVR WOLFSSL_USER_IO. (PR #8668) -* Correctly advanced the index in wc_HKDF_Expand_ex. (PR #8737) -* Fixed STM32 hash status check logic, including NO_AES_192 and NO_AES_256. (PR #8732) -* Added missing call to wolfSSL_RefFree in FreeCRL to prevent memory leaks. (PR #8750) -* Fixed sanity check on --group with unit test app and null sanity check with des decrypt. (PR #8711) -* Fixed Curve25519 and static ephemeral issue with blinding. (PR #8766) -* Fixed edge case issue with STM32 AES GCM auth padding. (PR #8745) -* Removed redefinition of MlKemKey and fixed build issue in benchmark. (PR #8755) -* Used proper heap hint when freeing CRL in error case. (PR #8713) -* Added support for no malloc with wc_CheckCertSigPubKey. (PR #8725) -* Fixed C# wrapper Release build. (PR #8802) -* Handled malformed CCS and CCS before CH in TLS1.3. (PR #8788) -* Fixed ML-DSA with WOLFSSL_DILITHIUM_NO_SIGN. (PR #8798) -* Fixed AesGcmCrypt_1 no-stream in the Linux Kernel Module. (PR #8814) -* Fixed return value usage for crypto_sig_sign in the Linux Kernel Module. (PR #8816) -* Fixed issue with CSharp and Windows CE with conversion of ASCII and Unicode. (PR #8799) -* Fixed Renesas SCE on RA6M4. (PR #8838) -* Fixed tests for different configs for ML-DSA. (PR #8865) -* Fixed bug in ParseCRL_Extensions around the size of a CRL number handled and CRL number OID. (PR #8587) -* Fixed uninitialized wc_FreeRng in prime_test. (PR #8886) -* Fixed ECC configuration issues with ECC verify only and no RNG. (PR #8901) -* Fixed issues with max size, openssl.test netcat, and clang-tidy. (PR #8909) -* Fixed for casting down and uninit issues in Dilithium/ML-DSA. (PR #8868) -* Fixed memory allocation failure testing and related unit test cases. (PR #8945, PR #8952) -* Fixed build issue with ML-DSA 44 only. (PR #8981) -* Fixed possible memory leak with X509 reference counter when using x509small. (PR #8982) +* Removed the test feature using popen when defining the macro WOLFSSL_USE_POPEN_HOST and not having HAVE_GETADDRINFO defined, along with having the macro HAVE_HTTP_CLIENT set. There was the potential for vulnerable behavior with the use of popen when the API wolfSSL_BIO_new_connect() was called with this specific build. This exact build configuration is only intended for testing with QEMU and is not enabled with any autoconf/cmake flags. Thanks to linraymond2006 for the report. (PR 9038) +* Fix for C# wrapper Ed25519 potential crash and heap overwrite with raw public key import when using the API Ed25519ImportPublic.This was a broken API with the C# wrapper that would crash on use. Thanks to Luigino Camastra from Aisle Research for the bug report. (PR 9291) +* Coverity, cppcheck, MISRA, clang-tidy, ZeroPath and other static-analysis driven fixes across the codebase. (PR 9006, 9078, 9068, 9265, 9324) +* TLS 1.2/DTLS improvements: client message order checks, DTLS cookie/exchange and replay protections, better DTLS early-data handling. (PR 9387, 9253, 9205, 9367) +* Improved X.509 & cert handling: allow larger pathLen in Basic Constraints, restore inner server name for ECH, retrying cert candidate chains. (PR 8890, 9234, 8692) +* Sniffer robustness: fix infinite recursion, better handling of OOO appData and partial overlaps, and improved retransmission detection. (PR 9051, 9106, 9140, 9094) +* Numerous linuxkm (kernel-mode) fixes, relocation/PIE normalization, and FIPS-related build tweaks across many iterations. (PR 9025, 9035, 9067, 9111, 9121) +* ML-KEM/Kyber and ML-DSA fixes for out-of-bounds and seed-import correctness; multiple ML-related safety fixes. (PR 9142, 9105, 9439) +* Avoid uninitialized-variable and GCC warnings; several fixes for undefined-shift/overflow issues. (PR 9020, 9372, 9195) +* Memory & leak fixes in X509 verification and various struct sizing fixes for WOLFSSL_NO_MALLOC usage. (PR 9258, 9036) +* Fixed RSA / signing / verify-only warnings allowing WOLFSSL_NO_CT_OPS when WOLFSSL_RSA_VERIFY_ONLY is used and API cleanups for using const. (PR 9031, 9263) For additional vulnerability information visit the vulnerability page at: https://www.wolfssl.com/docs/security-vulnerabilities/ diff --git a/README.md b/README.md index 13265b3..905411a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Arduino wolfSSL Library -This library is restructured from [wolfSSL](https://github.com/wolfSSL/wolfssl/) Release 5.8.2 for the Arduino platform. +This library is restructured from [wolfSSL](https://github.com/wolfSSL/wolfssl/) Release 5.8.4 for the Arduino platform. The Official wolfSSL Arduino Library is found in [The Library Manager index](http://downloads.arduino.cc/libraries/library_index.json). @@ -40,13 +40,10 @@ Additional wolfSSL examples can be found at: ## Arduino Releases -This release of wolfSSL is version [5.7.6](https://github.com/wolfSSL/wolfssl/releases/tag/v5.7.6-stable). - See GitHub for [all Arduino wolfSSL releases](https://github.com/wolfSSL/Arduino-wolfSSL/releases). -The first Official wolfSSL Arduino Library was `5.6.6-Arduino.1`: a slightly modified, post [release 5.6.6](https://github.com/wolfSSL/wolfssl/releases/tag/v5.6.6-stable) version update. - The `./wolfssl-arduino.sh INSTALL` [script](https://github.com/wolfSSL/wolfssl/tree/master/IDE/ARDUINO) can be used to install specific GitHub versions as needed. + # wolfSSL Embedded SSL/TLS Library The [wolfSSL embedded SSL library](https://www.wolfssl.com/products/wolfssl/) @@ -82,19 +79,24 @@ of the wolfSSL manual. ## Notes, Please Read ### Note 1 -wolfSSL as of 3.6.6 no longer enables SSLv3 by default. wolfSSL also no longer -supports static key cipher suites with PSK, RSA, or ECDH. This means if you -plan to use TLS cipher suites you must enable DH (DH is on by default), or -enable ECC (ECC is on by default), or you must enable static key cipher suites -with one or more of the following defines: +wolfSSL as of 3.6.6 no longer enables SSLv3 by default. By default, wolfSSL +disables static key cipher suites that use PSK, RSA, or ECDH without ephemeral +key exchange. Instead, wolfSSL enables cipher suites that provide perfect +forward secrecy (PFS) using ephemeral Diffie-Hellman (DH) or Elliptic Curve +(ECC) key exchange, both of which are enabled by default. -``` -WOLFSSL_STATIC_DH -WOLFSSL_STATIC_RSA -WOLFSSL_STATIC_PSK -``` -Though static key cipher suites are deprecated and will be removed from future -versions of TLS. They also lower your security by removing PFS. +If you need to support legacy systems that require static key cipher suites, +you can enable them using one or more of these defines: + +* `WOLFSSL_STATIC_DH` +* `WOLFSSL_STATIC_RSA` +* `WOLFSSL_STATIC_PSK` + +**Important:** Static key cipher suites reduce security by eliminating perfect +forward secrecy. These cipher suites reuse the same long-term private key for +all session key exchanges. In contrast, PFS-enabled cipher suites (the wolfSSL +default) generate a new ephemeral key for each session, ensuring that +compromising a long-term key cannot decrypt past sessions. When compiling `ssl.c`, wolfSSL will now issue a compiler error if no cipher suites are available. You can remove this error by defining @@ -124,205 +126,77 @@ single call hash function. Instead the name `WC_SHA`, `WC_SHA256`, `WC_SHA384` a `WC_SHA512` should be used for the enum name. -# wolfSSL Release 5.8.2 (July 17, 2025) +# wolfSSL Release 5.8.4 (Nov. 20, 2025) -Release 5.8.2 has been developed according to wolfSSL's development and QA +Release 5.8.4 has been developed according to wolfSSL's development and QA process (see link below) and successfully passed the quality criteria. https://www.wolfssl.com/about/wolfssl-software-development-process-quality-assurance -NOTE: * wolfSSL is now GPLv3 instead of GPLv2 - * --enable-heapmath is deprecated +NOTE: * --enable-heapmath is deprecated * MD5 is now disabled by default - PR stands for Pull Request, and PR references a GitHub pull request number where the code change was added. ## Vulnerabilities +* [Low CVE-2025-12888] Vulnerability in X25519 constant-time cryptographic implementations due to timing side channels introduced by compiler optimizations and CPU architecture limitations, specifically with the Xtensa-based ESP32 chips. If targeting Xtensa it is recommended to use the low memory implementations of X25519, which is now turned on as the default for Xtensa. Thanks to Adrian Cinal for the report. Fixed in PR 9275. -* [Low] There is the potential for a fault injection attack on ECC and Ed25519 verify operations. In versions of wolfSSL 5.7.6 and later the --enable-faultharden option is available to help mitigate against potential fault injection attacks. The mitigation added in wolfSSL version 5.7.6 is to help harden applications relying on the results of the verify operations, such as when used with wolfBoot. If doing ECC or Ed25519 verify operations on a device at risk for fault injection attacks then --enable-faultharden could be used to help mitigate it. Thanks to Kevin from Fraunhofer AISEC for the report. - -Hardening option added in PR https://github.com/wolfSSL/wolfssl/pull/8289 +* [Med. CVE-2025-11936] Potential DoS vulnerability due to a memory leak through multiple KeyShareEntry with the same group in malicious TLS 1.3 ClientHello messages. This affects users who are running wolfSSL on the server side with TLS 1.3. Thanks to Jaehun Lee and Kyungmin Bae, Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9117. -* [High CVE-2025-7395] When using WOLFSSL_SYS_CA_CERTS and WOLFSSL_APPLE_NATIVE_CERT_VALIDATION on an Apple platform, the native trust store verification routine overrides errors produced elsewhere in the wolfSSL certificate verification process including failures due to hostname matching/SNI, OCSP, CRL, etc. This allows any trusted cert chain to override other errors detected during chain verification that should have resulted in termination of the TLS connection. If building wolfSSL on versions after 5.7.6 and before 5.8.2 with use of the system CA support and the apple native cert validation feature enabled on Apple devices (on by default for non-macOS Apple targets when using autotools or CMake) we recommend updating to the latest version of wolfSSL. Thanks to Thomas Leong from ExpressVPN for the report. +* [Low CVE-2025-11935] PSK with PFS (Perfect Forward Secrecy) downgrades to PSK without PFS during TLS 1.3 handshake. If the client sends a ClientHello that has a key share extension and the server responds with a ServerHello that does not have a key share extension the connection would previously continue on without using PFS. Thanks to Jaehun Lee from Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9112. -Fixed in PR https://github.com/wolfSSL/wolfssl/pull/8833 +* [Low CVE-2025-11934] Signature Algorithm downgrade from ECDSA P521 to P256 during TLS 1.3 handshake. When a client sends ECDSA P521 as the supported signature algorithm the server previously could respond as ECDSA P256 being the accepted signature algorithm and the connection would continue with using ECDSA P256. Thanks to Jaehun Lee from Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9113. -* [Med. CVE-2025-7394] In the OpenSSL compatibility layer implementation, the function RAND_poll() was not behaving as expected and leading to the potential for predictable values returned from RAND_bytes() after fork() is called. This can lead to weak or predictable random numbers generated in applications that are both using RAND_bytes() and doing fork() operations. This only affects applications explicitly calling RAND_bytes() after fork() and does not affect any internal TLS operations. Although RAND_bytes() documentation in OpenSSL calls out not being safe for use with fork() without first calling RAND_poll(), an additional code change was also made in wolfSSL to make RAND_bytes() behave similar to OpenSSL after a fork() call without calling RAND_poll(). Now the Hash-DRBG used gets reseeded after detecting running in a new process. If making use of RAND_bytes() and calling fork() we recommend updating to the latest version of wolfSSL. Thanks to Per Allansson from Appgate for the report. +* [Low CVE-2025-11933] DoS Vulnerability in wolfSSL TLS 1.3 CKS extension parsing. Previously duplicate CKS extensions were not rejected leading to a potential memory leak when processing a ClientHello. Thanks to Jaehun Lee from Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9132. -Fixed in the following PR’s -https://github.com/wolfSSL/wolfssl/pull/8849 -https://github.com/wolfSSL/wolfssl/pull/8867 -https://github.com/wolfSSL/wolfssl/pull/8898 +* [Low CVE-2025-11931] Integer Underflow Leads to Out-of-Bounds Access in XChaCha20-Poly1305 Decrypt. This issue is hit specifically with a call to the function wc_XChaCha20Poly1305_Decrypt() which is not used with TLS connections, only from direct calls from an application. Thanks to Luigino Camastra from Aisle Research for the report. Fixed in PR 9223. +* [Low CVE-2025-11932] Timing Side-Channel in PSK Binder Verification. The server previously verified the TLS 1.3 PSK binder using a non-constant time method which could potentially leak information about the PSK binder. Thanks to Luigino Camastra from Aisle Research for the report. Fixed in PR 9223. -* [Low CVE-2025-7396] In wolfSSL 5.8.0 the option of hardening the C implementation of Curve25519 private key operations was added with the addition of blinding support (https://www.wolfssl.com/curve25519-blinding-support-added-in-wolfssl-5-8-0/). In wolfSSL release 5.8.2 that blinding support is turned on by default in applicable builds. The blinding configure option is only for the base C implementation of Curve25519. It is not needed, or available with; ARM assembly builds, Intel assembly builds, and the small Curve25519 feature. While the attack would be very difficult to execute in practice, enabling blinding provides an additional layer of protection for devices that may be more susceptible to physical access or side-channel observation. Thanks to Arnaud Varillon, Laurent Sauvage, and Allan Delautre from Telecom Paris for the report. - -Blinding enabled by default in PR https://github.com/wolfSSL/wolfssl/pull/8736 - +* [Low CVE-2025-12889] With TLS 1.2 connections a client can use any digest, specifically a weaker digest, rather than those in the CertificateRequest. Thanks to Jaehun Lee from Pohang University of Science and Technology (POSTECH) for the report. Fixed in PR 9395 ## New Features -* Multiple sessions are now supported in the sniffer due to the removal of a cached check. (PR #8723) -* New API ssl_RemoveSession() has been implemented for sniffer cleanup operations. (PR #8768) -* The new ASN X509 API, `wc_GetSubjectPubKeyInfoDerFromCert`, has been introduced for retrieving public key information from certificates. (PR #8758) -* `wc_PKCS12_create()` has been enhanced to support PBE_AES(256|128)_CBC key and certificate encryptions. (PR #8782, PR #8822, PR #8859) -* `wc_PKCS7_DecodeEncryptedKeyPackage()` has been added for decoding encrypted key packages. (PR #8976) -* All AES, SHA, and HMAC functionality has been implemented within the Linux Kernel Module. (PR #8998) -* Additions to the compatibility layer have been introduced for X.509 extensions and RSA PSS. Adding the API i2d_PrivateKey_bio, BN_ucmp and X509v3_get_ext_by_NID. (PR #8897) -* Added support for STM32N6. (PR #8914) -* Implemented SHA-256 for PPC 32 assembly. (PR #8894) +* New ML-KEM / ML-DSA APIs and seed/import PKCS8 support; added _new/_delete APIs for ML-KEM/ML-DSA. (PR 9039, 9000, 9049) +* Initial wolfCrypt FreeBSD kernel module support (PR 9392) +* Expanded PKCS7/CMS capabilities: decode SymmetricKeyPackage / OneSymmetricKey, add wc_PKCS7_GetEnvelopedDataKariRid, and allow PKCS7 builds with AES keywrap unset. (PR 9018, 9029, 9032) +* Add custom AES key wrap/unwrap callbacks and crypto callback copy/free operations. (PR 9002, 9309) +* Add support for certificate_authorities extension in ClientHello and certificate manager CA-type selection/unloading. (PR 9209, 9046) +* Large expansion of Rust wrapper modules: random, aes, rsa, ecc, dh, sha, hmac, cmac, ed25519/ed448, pbkdf2/PKCS#12, kdf/prf, SRTP KDFs, and conditional compilation options. (PR 9191, 9212, 9273, 9306, 9320, 9328, 9368, 9389, 9357, 9433) +* Rust: support optional heap and dev_id parameters and enable conditional compilation based on C build options. (PR 9407, 9433) +* STM32 fixes (benchmarking and platform fixes) and PSoC6 hardware acceleration additions. (PR 9228, 9256, 9185) +* STM32U5 added support for SAES and DHUK. (PR 9087) +* Add --enable-curl=tiny option for a smaller build when used with cURL. (PR 9174) ## Improvements / Optimizations - -### Linux Kernel Module (LinuxKM) Enhancements -* Registered DH and FFDHE for the Linux Kernel Module. (PR #8707) -* Implemented fixes for standard RNG in the Linux Kernel Module. (PR #8718) -* Added an ECDSA workaround for the Linux Kernel Module. (PR #8727) -* Added more PKCS1 pad SHA variants for RSA in the Linux Kernel Module. (PR #8730) -* Set default priority to 100000 for LKCAPI in the Linux Kernel Module. (PR #8740) -* Ensured ECDH never has FIPS enabled in the Linux Kernel Module. (PR #8751) -* Implemented further Linux Kernel Module and SP tweaks. (PR #8773) -* Added sig_alg support for Linux 6.13 RSA in the Linux Kernel Module. (PR #8796) -* Optimized wc_linuxkm_fpu_state_assoc. (PR #8828) -* Ensured DRBG is multithread-round-1 in the Linux Kernel Module. (PR #8840) -* Prevented toggling of fips_enabled in the Linux Kernel Module. (PR #8873) -* Refactored drbg_ctx clear in the Linux Kernel Module. (PR #8876) -* Set sig_alg max_size and digest_size callbacks for RSA in the Linux Kernel Module. (PR #8915) -* Added get_random_bytes for the Linux Kernel Module. (PR #8943) -* Implemented distro fix for the Linux Kernel Module. (PR #8994) -* Fixed page-flags-h in the Linux Kernel Module. (PR #9001) -* Added MODULE_LICENSE for the Linux Kernel Module. (PR #9005) -* Post-Quantum Cryptography (PQC) & Asymmetric Algorithms -* Kyber has been updated to the MLKEM ARM file for Zephyr (PR #8781) -* Backward compatibility has been implemented for ML_KEM IDs (PR #8827) -* ASN.1 is now ensured to be enabled when only building PQ algorithms (PR #8884) -* Building LMS with verify-only has been fixed (PR #8913) -* Parameters for LMS SHA-256_192 have been corrected (PR #8912) -* State can now be saved with the private key for LMS (PR #8836) -* Support for OpenSSL format has been added for ML-DSA/Dilithium (PR #8947) -* `dilithium_coeff_eta2[]` has been explicitly declared as signed (PR #8955) - -### Build System & Portability -* Prepared for the inclusion of v5.8.0 in the Ada Alire index. (PR #8714) -* Introduced a new build option to allow reuse of the Windows crypt provider handle. (PR #8706) -* Introduced general fixes for various build configurations. (PR #8763) -* Made improvements for portability using older GCC 4.8.2. (PR #8753) -* Macro guards updated to allow tests to build with opensslall and no server. (PR #8776) -* Added a check for STDC_NO_ATOMICS macro before use of atomics. (PR #8885) -* Introduced CMakePresets.json and CMakeSettings.json. (PR #8905) -* Added an option to not use constant time code with min/max. (PR #8830) -* Implemented proper MacOS dispatch for conditional signal/wait. (PR #8928) -* Disabled MD5 by default for both general and CMake builds. (PR #8895, PR #8948) -* Improved to allow building OPENSSL_EXTRA without KEEP_PEER_CERT. (PR #8926) -* Added introspection for Intel and ARM assembly speedups. (PR #8954) -* Fixed cURL config to set HAVE_EX_DATA and HAVE_ALPN. (PR #8973) -* Moved FREESCALE forced algorithm HAVE_ECC to IDE/MQX/user_settings.h. (PR #8977) - -### Testing & Debugging -* Fixed the exit status for testwolfcrypt. (PR #8762) -* Added WOLFSSL_DEBUG_PRINTF and WOLFSSL_DEBUG_CERTIFICATE_LOADS for improved debugging output. (PR #8769, PR #8770) -* Guarded some benchmark tests with NO_SW_BENCH. (PR #8760) -* Added an additional unit test for wolfcrypt PKCS12 file to improve code coverage. (PR #8831) -* Added an additional unit test for increased DH code coverage. (PR #8837) -* Adjusted for warnings with NO_TLS build and added GitHub actions test. (PR #8851) -* Added additional compatibility layer RAND tests. (PR #8852) -* Added an API unit test for checking domain name. (PR #8863) -* Added bind v9.18.33 testing. (PR #8888) -* Fixed issue with benchmark help options and descriptions not lining up. (PR #8957) - -### Certificates & ASN.1 -* Changed the algorithm for sum in ASN.1 OIDs. (PR #8655) -* Updated PKCS7 to use X509 STORE for internal verification. (PR #8748) -* Improved handling of temporary buffer size for X509 extension printing. (PR #8710) -* Marked IP address as WOLFSSL_V_ASN1_OCTET_STRING for ALT_NAMES_OID. (PR #8842) -* Fixed printing empty names in certificates. (PR #8880) -* Allowed CA:FALSE on wolftpm. (PR #8925) -* Fixed several inconsistent function prototype parameter names in wc/asn. (PR #8949) -* Accounted for custom extensions when creating a Cert from a WOLFSSL_X509. (PR #8960) - -### TLS/DTLS & Handshake -* Checked group correctness outside of TLS 1.3 too for TLSX_UseSupportedCurve. (PR #8785) -* Dropped records that span datagrams in DTLS. (PR #8642) -* Implemented WC_NID_netscape_cert_type. (PR #8800) -* Refactored GetHandshakeHeader/GetHandShakeHeader into one function. (PR #8787) -* Correctly set the current peer in dtlsProcessPendingPeer. (PR #8848) -* Fixed set_groups for TLS. (PR #8824) -* Allowed trusted_ca_keys with TLSv1.3. (PR #8860) -* Moved Dtls13NewEpoch into DeriveTls13Keys. (PR #8858) -* Cleared tls1_3 on downgrade. (PR #8861) -* Always sent ACKs on detected retransmission for DTLS1.3. (PR #8882) -* Removed DTLS from echo examples. (PR #8889) -* Recalculated suites at SSL initialization. (PR #8757) -* No longer using BIO for ALPN. (PR #8969) -* Fixed wolfSSL_BIO_new_connect's handling of IPV6 addresses. (PR #8815) -* Memory Management & Optimizations -* Performed small stack refactors, improved stack size with mlkem and dilithium, and added additional tests. (PR #8779) -* Implemented FREE_MP_INT_SIZE in heap math. (PR #8881) -* Detected correct MAX_ENCODED_SIG_SZ based on max support in math lib. (PR #8931) -* Fixed improper access of sp_int_minimal using sp_int. (PR #8985) - -### Cryptography & Hash Functions -* Implemented WC_SIPHASH_NO_ASM for not using assembly optimizations with siphash. (PR #8789, PR #8791) -* Added missing DH_MAX_SIZE define for FIPS and corrected wolfssl.rc FILETYPE to VFT_DLL. (PR #8794) -* Implemented WC_SHA3_NO_ASM for not using assembly with SHA3. (PR #8817) -* Improved Aarch64 XFENCE. (PR #8832) -* Omitted frame pointer for ARM32/Thumb2/RISC-V 64 assembly. (PR #8893) -* Fixed branch instruction in ARMv7a ASM. (PR #8933) -* Enabled EVP HMAC to work with WOLFSSL_HMAC_COPY_HASH. (PR #8944) -* Platform-Specific & Hardware Integration -* Added HAVE_HKDF for wolfssl_test and explicit support for ESP32P4. (PR #8742) -* Corrected Espressif default time setting. (PR #8829) -* Made wc_tsip_* APIs public. (PR #8717) -* Improved PlatformIO Certificate Bundle Support. (PR #8847) -* Fixed the TSIP TLS example program. (PR #8857) -* Added crypto callback functions for TROPIC01 secure element. (PR #8812) -* Added Renesas RX TSIP AES CTR support. (PR #8854) -* Fixed TSIP port using crypto callback. (PR #8937) - -### General Improvements & Refactoring -* Attempted wolfssl_read_bio_file in read_bio even when XFSEEK is available. (PR #8703) -* Refactored GetHandshakeHeader/GetHandShakeHeader into one function. (PR #8787) -* Updated libspdm from 3.3.0 to 3.7.0. (PR #8906) -* Fixed missing dashes on the end of header and footer for Falcon PEM key. (PR #8904) -* Fixed minor code typos for macos signal and types.h max block size. (PR #8934) -* Make the API wolfSSL_X509_STORE_CTX_get_error accessible to more build configurations for ease of getting the "store" error code and depth with certificate failure callback implementations. (PR #8903) +* Regression test fixes and expansion: TLS 1.3/1.2 tests, ARDUINO examples, libssh2 tests, hostap workflows, and nightly test improvements. (PR 9096, 9141, 9091, 9122, 9388) +* Improved test ordering and CI test stability (random tests run order changes, FIPS test fixes). (PR 9204, 9257) +* Docs and readme fixes, docstring updates, AsconAEAD comment placement, and example certificate renewals. (PR 9131, 9293, 9262, 9429) +* Updated GPL exception lists (GPLv2 and GPLv3 exception updates: add Fetchmail and OpenVPN). (PR 9398, 9413) +* Introduced WOLFSSL_DEBUG_CERTS and additional debug/logging refinements. (PR 8902, 9055) +* Expanded crypto-callback support (SHA family, HKDF, SHA-224, sha512_family digest selection) and improved crypto-only build cases. (PR 9070, 9252, 9271, 9100, 9194) +* AES & HW offload improvements including AES-CTR support in PKCS11 driver and AES ECB offload sizing fix. (PR 9277, 9364) +* ESP32: PSRAM allocator support and SHA HW fixes for ESP-IDF v6/v5. (PR 8987, 9225, 9264) +* Renesas FSP / RA examples updated and security-module TLS context improvements. (PR 9047, 9010, 9158, 9150) +* Broad configure/CMake/Autotools workflow improvements (Apple options tracking, Watcom pinning, Debian packaging, ESP-IDF pinning). (PR 9037, 9167, 9161, 9264) +* New assembly introspection / performance helpers for RISC-V and PPC32; benchmarking enhancements (cycle counts). (PR 9101, 9317) +* Update to SGX build for using assembly optimizations. (PR 8463, 9138) +* Testing with Fil-C compiler version to 0.674 (PR 9396) +* Refactors and compressing of small stack code (PR 9153) ## Bug Fixes -* Fixed issues to support _WIN32_WCE (VS 2008 with WinCE 6.0/7.0). (PR #8709) -* Fixed STM32 Hash with IRQ enabled. (PR #8705) -* Fixed raw hash when using crypto instructions on RISC-V 64-bit. (PR #8733) -* Fixed ECDH decode secret in the Linux Kernel Module. (PR #8729) -* Passed in the correct hash type to wolfSSL_RSA_verify_ex. (PR #8726) -* Fixed issues for Intel QuickAssist latest driver (4.28). (PR #8728) -* Speculative fix for CodeSonar overflow issue in ssl_certman.c. (PR #8715) -* Fixed Arduino progmem print and AVR WOLFSSL_USER_IO. (PR #8668) -* Correctly advanced the index in wc_HKDF_Expand_ex. (PR #8737) -* Fixed STM32 hash status check logic, including NO_AES_192 and NO_AES_256. (PR #8732) -* Added missing call to wolfSSL_RefFree in FreeCRL to prevent memory leaks. (PR #8750) -* Fixed sanity check on --group with unit test app and null sanity check with des decrypt. (PR #8711) -* Fixed Curve25519 and static ephemeral issue with blinding. (PR #8766) -* Fixed edge case issue with STM32 AES GCM auth padding. (PR #8745) -* Removed redefinition of MlKemKey and fixed build issue in benchmark. (PR #8755) -* Used proper heap hint when freeing CRL in error case. (PR #8713) -* Added support for no malloc with wc_CheckCertSigPubKey. (PR #8725) -* Fixed C# wrapper Release build. (PR #8802) -* Handled malformed CCS and CCS before CH in TLS1.3. (PR #8788) -* Fixed ML-DSA with WOLFSSL_DILITHIUM_NO_SIGN. (PR #8798) -* Fixed AesGcmCrypt_1 no-stream in the Linux Kernel Module. (PR #8814) -* Fixed return value usage for crypto_sig_sign in the Linux Kernel Module. (PR #8816) -* Fixed issue with CSharp and Windows CE with conversion of ASCII and Unicode. (PR #8799) -* Fixed Renesas SCE on RA6M4. (PR #8838) -* Fixed tests for different configs for ML-DSA. (PR #8865) -* Fixed bug in ParseCRL_Extensions around the size of a CRL number handled and CRL number OID. (PR #8587) -* Fixed uninitialized wc_FreeRng in prime_test. (PR #8886) -* Fixed ECC configuration issues with ECC verify only and no RNG. (PR #8901) -* Fixed issues with max size, openssl.test netcat, and clang-tidy. (PR #8909) -* Fixed for casting down and uninit issues in Dilithium/ML-DSA. (PR #8868) -* Fixed memory allocation failure testing and related unit test cases. (PR #8945, PR #8952) -* Fixed build issue with ML-DSA 44 only. (PR #8981) -* Fixed possible memory leak with X509 reference counter when using x509small. (PR #8982) +* Removed the test feature using popen when defining the macro WOLFSSL_USE_POPEN_HOST and not having HAVE_GETADDRINFO defined, along with having the macro HAVE_HTTP_CLIENT set. There was the potential for vulnerable behavior with the use of popen when the API wolfSSL_BIO_new_connect() was called with this specific build. This exact build configuration is only intended for testing with QEMU and is not enabled with any autoconf/cmake flags. Thanks to linraymond2006 for the report. (PR 9038) +* Fix for C# wrapper Ed25519 potential crash and heap overwrite with raw public key import when using the API Ed25519ImportPublic.This was a broken API with the C# wrapper that would crash on use. Thanks to Luigino Camastra from Aisle Research for the bug report. (PR 9291) +* Coverity, cppcheck, MISRA, clang-tidy, ZeroPath and other static-analysis driven fixes across the codebase. (PR 9006, 9078, 9068, 9265, 9324) +* TLS 1.2/DTLS improvements: client message order checks, DTLS cookie/exchange and replay protections, better DTLS early-data handling. (PR 9387, 9253, 9205, 9367) +* Improved X.509 & cert handling: allow larger pathLen in Basic Constraints, restore inner server name for ECH, retrying cert candidate chains. (PR 8890, 9234, 8692) +* Sniffer robustness: fix infinite recursion, better handling of OOO appData and partial overlaps, and improved retransmission detection. (PR 9051, 9106, 9140, 9094) +* Numerous linuxkm (kernel-mode) fixes, relocation/PIE normalization, and FIPS-related build tweaks across many iterations. (PR 9025, 9035, 9067, 9111, 9121) +* ML-KEM/Kyber and ML-DSA fixes for out-of-bounds and seed-import correctness; multiple ML-related safety fixes. (PR 9142, 9105, 9439) +* Avoid uninitialized-variable and GCC warnings; several fixes for undefined-shift/overflow issues. (PR 9020, 9372, 9195) +* Memory & leak fixes in X509 verification and various struct sizing fixes for WOLFSSL_NO_MALLOC usage. (PR 9258, 9036) +* Fixed RSA / signing / verify-only warnings allowing WOLFSSL_NO_CT_OPS when WOLFSSL_RSA_VERIFY_ONLY is used and API cleanups for using const. (PR 9031, 9263) For additional vulnerability information visit the vulnerability page at: https://www.wolfssl.com/docs/security-vulnerabilities/ @@ -356,46 +230,46 @@ More info can be found on-line at: https://wolfssl.com/wolfSSL/Docs.html ``` -├── certs [Certificates used in tests and examples] -├── cmake [Cmake build utilities] -├── debian [Debian packaging files] -├── doc [Documentation for wolfSSL (Doxygen)] -├── Docker [Prebuilt Docker environments] -├── examples [wolfSSL examples] -│   ├── asn1 [ASN.1 printing example] -│   ├── async [Asynchronous Cryptography example] -│   ├── benchmark [TLS benchmark example] -│   ├── client [Client example] -│   ├── configs [Example build configurations] -│   ├── echoclient [Echoclient example] -│   ├── echoserver [Echoserver example] -│   ├── pem [Example for convert between PEM and DER] -│   ├── sctp [Servers and clients that demonstrate wolfSSL's DTLS-SCTP support] -│   └── server [Server example] -├── IDE [Contains example projects for various development environments] -├── linuxkm [Linux Kernel Module implementation] -├── m4 [Autotools utilities] -├── mcapi [wolfSSL MPLAB X Project Files] -├── mplabx [wolfSSL MPLAB X Project Files] -├── mqx [wolfSSL Freescale CodeWarrior Project Files] -├── rpm [RPM packaging metadata] -├── RTOS -│   └── nuttx [Port of wolfSSL for NuttX] -├── scripts [Testing scripts] -├── src [wolfSSL source code] -├── sslSniffer [wolfSSL sniffer can be used to passively sniff SSL traffic] -├── support [Contains the pkg-config file] -├── tests [Unit and configuration testing] -├── testsuite [Test application that orchestrates tests] -├── tirtos [Port of wolfSSL for TI RTOS] -├── wolfcrypt [The wolfCrypt component] -│   ├── benchmark [Cryptography benchmarking application] -│   ├── src [wolfCrypt source code] -│   │   └── port [Supported hardware acceleration ports] -│   └── test [Cryptography testing application] -├── wolfssl [Header files] -│   ├── openssl [Compatibility layer headers] -│   └── wolfcrypt [Header files] -├── wrapper [wolfSSL language wrappers] -└── zephyr [Port of wolfSSL for Zephyr RTOS] +├── certs [Certificates used in tests and examples] +├── cmake [Cmake build utilities] +├── debian [Debian packaging files] +├── doc [Documentation for wolfSSL (Doxygen)] +├── Docker [Prebuilt Docker environments] +├── examples [wolfSSL examples] +│   ├── asn1 [ASN.1 printing example] +│   ├── async [Asynchronous Cryptography example] +│   ├── benchmark [TLS benchmark example] +│   ├── client [Client example] +│   ├── configs [Example build configurations] +│   ├── echoclient [Echoclient example] +│   ├── echoserver [Echoserver example] +│   ├── pem [Example for convert between PEM and DER] +│   ├── sctp [Servers and clients that demonstrate wolfSSL's DTLS-SCTP support] +│   └── server [Server example] +├── IDE [Contains example projects for various development environments] +├── linuxkm [Linux Kernel Module implementation] +├── m4 [Autotools utilities] +├── mcapi [wolfSSL MPLAB X Project Files] +├── mplabx [wolfSSL MPLAB X Project Files] +├── mqx [wolfSSL Freescale CodeWarrior Project Files] +├── rpm [RPM packaging metadata] +├── RTOS +│   └── nuttx [Port of wolfSSL for NuttX] +├── scripts [Testing scripts] +├── src [wolfSSL source code] +├── sslSniffer [wolfSSL sniffer can be used to passively sniff SSL traffic] +├── support [Contains the pkg-config file] +├── tests [Unit and configuration testing] +├── testsuite [Test application that orchestrates tests] +├── tirtos [Port of wolfSSL for TI RTOS] +├── wolfcrypt [The wolfCrypt component] +│   ├── benchmark [Cryptography benchmarking application] +│   ├── src [wolfCrypt source code] +│   │   └── port [Supported hardware acceleration ports] +│   └── test [Cryptography testing application] +├── wolfssl [Header files] +│   ├── openssl [Compatibility layer headers] +│   └── wolfcrypt [Header files] +├── wrapper [wolfSSL language wrappers] +└── zephyr [Port of wolfSSL for Zephyr RTOS] ``` diff --git a/examples/template/template.ino b/examples/template/template.ino index 8998976..0d0f8d8 100644 --- a/examples/template/template.ino +++ b/examples/template/template.ino @@ -6,7 +6,7 @@ * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, @@ -21,6 +21,13 @@ #include +#if defined(ARDUINO_PORTENTA_X8) + /* The Portenta is a Linux device. See wolfSSL examples: + * https://github.com/wolfSSL/wolfssl/tree/master/examples + * By default Serial is disabled and mapped to ErrorSerial */ + #include +#endif + /* wolfSSL user_settings.h must be included from settings.h * Make all configurations changes in user_settings.h * Do not edit wolfSSL `settings.h` or `config.h` files. diff --git a/examples/template/wolfssl_helper.c b/examples/template/wolfssl_helper.c index f4eeb57..c6dcd39 100644 --- a/examples/template/wolfssl_helper.c +++ b/examples/template/wolfssl_helper.c @@ -6,7 +6,7 @@ * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, @@ -26,10 +26,36 @@ * Be sure to include these files in all libraries that reference * wolfssl in this order: */ -#include -/* settings.h is typically included in wolfssl.h, but here as a reminder: */ -#include -#include +#if defined(ARDUINO_PORTENTA_X8) + /* This file is purposely a c and not .cpp file for testing. + * On Portenta X8 the core headers assume C++, and things like A6, + * PIN_SPI_MOSI, etc. - rely on C++-only constructs. + * So don't include Arduino.h here for Portenta. */ + + #include + #include /* The ssl.h usually included by wolfssl.h */ + + #ifdef __cplusplus + extern "C" { + #endif + + /* Sample source code is C, but Arduino is compiling with C++ + * Declare a helper function to be used in wolfssl/wolfcrypt/logging.c */ + int wolfSSL_Arduino_Serial_Print(const char* const s); + + #ifdef __cplusplus + } + #endif +#else + /* Assume all other target boards would want to include Arduino.h in a + * helper such as this one. Not needed in this wolfssl_helper.c example. */ + #include + + /* settings.h is typically included in wolfssl.h, but here as a reminder: */ + #include + #include /* The wolfssl core Arduino library file */ +#endif + #include "wolfssl_helper.h" diff --git a/examples/template/wolfssl_helper.h b/examples/template/wolfssl_helper.h index 844f022..1291dbe 100644 --- a/examples/template/wolfssl_helper.h +++ b/examples/template/wolfssl_helper.h @@ -6,7 +6,7 @@ * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, diff --git a/examples/wolfssl_AES_CTR/wolfssl_AES_CTR.ino b/examples/wolfssl_AES_CTR/wolfssl_AES_CTR.ino index 31ef797..a47d096 100644 --- a/examples/wolfssl_AES_CTR/wolfssl_AES_CTR.ino +++ b/examples/wolfssl_AES_CTR/wolfssl_AES_CTR.ino @@ -6,7 +6,7 @@ * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, @@ -19,6 +19,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include + +#if defined(ARDUINO_PORTENTA_X8) + /* The Portenta is a Linux device. See wolfSSL examples: + * https://github.com/wolfSSL/wolfssl/tree/master/examples + * By default Serial is disabled and mapped to ErrorSerial */ + #include +#endif + /* The Advanced Encryption Standard (AES) is a specification for the encryption of electronic data established by the U.S. National Institute of Standards and Technology (NIST) in 2001. @@ -50,7 +59,21 @@ Teensy 4.1 (ARM Cortex M7) */ #define WOLFSSL_AES_CTR_EXAMPLE +/* wolfSSL user_settings.h must be included from settings.h + * Make all configurations changes in user_settings.h + * Do not edit wolfSSL `settings.h` or `config.h` files. + * Do not explicitly include user_settings.h in any source code. + * Each Arduino sketch that uses wolfSSL must have: #include "wolfssl.h" + * C/C++ source files can use: #include + * The wolfSSL "settings.h" must be included in each source file using wolfSSL. + * The wolfSSL "settings.h" must appear before any other wolfSSL include. + */ #include + + /* settings.h is included from Arduino `wolfssl.h`, but a good practice to + * include before any other wolfssl headers. As a reminder here: */ +#include + #include #if defined(NO_AES) or !defined(WOLFSSL_AES_COUNTER) or !defined(WOLFSSL_AES_128) diff --git a/examples/wolfssl_client/wolfssl_client.ino b/examples/wolfssl_client/wolfssl_client.ino index 8af1eaf..c56de7f 100644 --- a/examples/wolfssl_client/wolfssl_client.ino +++ b/examples/wolfssl_client/wolfssl_client.ino @@ -6,7 +6,7 @@ * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, @@ -39,6 +39,18 @@ Tested with: /* If you have a private include, define it here, otherwise edit WiFi params */ /* #define MY_PRIVATE_CONFIG "/workspace/my_private_config.h" */ +#if defined(ARDUINO) && defined(ESP8266) + #warning "This example is not yet supported on Arduino ESP8266" +#endif + +#if defined(DEBUG_WOLFSSL) + /* Optionally enabled verbose wolfSSL debugging */ + #define DEBUG_WOLFSSL_MESSAGES_ON +#else + /* DEBUG_WOLFSSL needs to be enabled */ + #undef DEBUG_WOLFSSL_MESSAGES_ON +#endif + /* set REPEAT_CONNECTION to a non-zero value to continually run the example. */ #define REPEAT_CONNECTION 0 @@ -68,12 +80,12 @@ Tested with: /* the /workspace directory may contain a private config * excluded from GitHub with items such as WiFi passwords */ #include MY_PRIVATE_CONFIG - static const char ssid[] PROGMEM = MY_ARDUINO_WIFI_SSID; - static const char password[] PROGMEM = MY_ARDUINO_WIFI_PASSWORD; + static const char ssid[] PROGMEM = MY_ARDUINO_WIFI_SSID; + static const char password[] PROGMEM = MY_ARDUINO_WIFI_PASSWORD; #else /* when using WiFi capable boards: */ - static const char ssid[] PROGMEM = "your_SSID"; - static const char password[] PROGMEM = "your_PASSWORD"; + static const char ssid[] PROGMEM = "your_SSID"; + static const char password[] PROGMEM = "your_PASSWORD"; #endif #define BROADCAST_ADDRESS "255.255.255.255" @@ -132,6 +144,10 @@ Tested with: #elif defined(ESP8266) #define USING_WIFI #include + /* Ensure the F() flash macro is defined */ + #ifndef F + #define F + #endif WiFiClient client; #elif defined(ARDUINO_SAM_DUE) @@ -140,7 +156,10 @@ Tested with: /* Needs "Ethernet by Various" library to be installed. Tested with V2.0.2 */ #include EthernetClient client; - +#elif defined(ARDUINO_AVR_ETHERNET) || defined(ARDUINO_AVR_LEONARDO_ETH) + /* Boards such as arduino:avr:ethernet and arduino:avr:leonardoeth */ + #include + EthernetClient client; #elif defined(ARDUINO_SAMD_NANO_33_IOT) #define USING_WIFI #include @@ -153,6 +172,36 @@ Tested with: #include WiFiClient client; +#elif defined(ARDUINO_SAMD_TIAN) + #include + #include + HttpClient client; + /* Arduino Tian does not support network shields like the standard Ethernet or Wi-Fi shields. */ + #error "HttpClient cannot be used for this example" +#elif defined(ARDUINO_PORTENTA_X8) + /* The Portenta is a Linux device. See wolfSSL examples: + * https://github.com/wolfSSL/wolfssl/tree/master/examples + * By default Serial is disabled and mapped to ErrorSerial */ + #include + + /* ----No - network placeholders(compile - only) ---- */ + #include + struct X8NoNetClient { + int write(const uint8_t*, size_t) { return -1; } + int available() { return 0; } + int read() { return -1; } + void stop() {} + bool connected() { return false; } + IPAddress remoteIP() { return IPAddress(0, 0, 0, 0); } + }; + struct X8NoNetServer { + explicit X8NoNetServer(uint16_t) {} + void begin() {} + X8NoNetClient available() { return X8NoNetClient(); } + }; + + X8NoNetClient client; + X8NoNetServer server(WOLFSSL_PORT); #elif defined(USING_WIFI) #define USING_WIFI #include @@ -205,7 +254,10 @@ static char errBuf[80]; static int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx); static int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx); static int reconnect = RECONNECT_ATTEMPTS; +#if 0 +/* optional showPeerEx, currently disabled */ static int lng_index PROGMEM = 0; /* 0 = English */ +#endif #if defined(__arm__) #include @@ -462,7 +514,8 @@ int setup_network(void) { /*****************************************************************************/ /* Arduino setup_wolfssl() */ /*****************************************************************************/ -int setup_wolfssl(void) { +int setup_wolfssl(void) +{ int ret = 0; WOLFSSL_METHOD* method; @@ -482,8 +535,14 @@ int setup_wolfssl(void) { #endif #if defined(DEBUG_WOLFSSL) - wolfSSL_Debugging_ON(); - Serial.println(F("wolfSSL Debugging is On!")); + Serial.println(F("wolfSSL Debugging is available! (DEBUG_WOLFSSL)")); + #if defined(DEBUG_WOLFSSL_MESSAGES_ON) + Serial.println(F("Enabling verbose messages wolfSSL_Debugging_ON")); + wolfSSL_Debugging_ON(); + #else + Serial.println(F("Enable verbose messages with wolfSSL_Debugging_ON")); + Serial.println(F("or define DEBUG_WOLFSSL_MESSAGES_ON")); + #endif #else Serial.println(F("wolfSSL Debugging is Off! (enable with DEBUG_WOLFSSL)")); #endif @@ -509,6 +568,7 @@ int setup_wolfssl(void) { * It is best on embedded devices to choose a TLS session cache size. */ #endif + /* Initialize wolfSSL before assigning ctx */ ret = wolfSSL_Init(); if (ret == WOLFSSL_SUCCESS) { Serial.println("Successfully called wolfSSL_Init"); @@ -543,7 +603,8 @@ int setup_wolfssl(void) { /*****************************************************************************/ /* Arduino setup_certificates() */ /*****************************************************************************/ -int setup_certificates(void) { +int setup_certificates(void) +{ int ret = 0; Serial.println(F("Initializing certificates...")); @@ -609,7 +670,8 @@ int setup_certificates(void) { /* Arduino setup() */ /*****************************************************************************/ /*****************************************************************************/ -void setup(void) { +void setup(void) +{ int i = 0; Serial.begin(SERIAL_BAUD); while (!Serial && (i < 10)) { @@ -650,13 +712,17 @@ void setup(void) { wolfSSL_SetIOSend(ctx, EthernetSend); wolfSSL_SetIORecv(ctx, EthernetReceive); +#if defined THIS_USER_SETTINGS_VERSION + Serial.print(F("This user_settings.h version:")) + Serial.println(THIS_USER_SETTINGS_VERSION) +#endif + Serial.println(F("Completed Arduino setup!")); /* See companion wolfssl_server.ino code; server begins listening here * https://github.com/wolfSSL/wolfssl/tree/master/IDE/ARDUINO/sketches/wolfssl_server * Any other server will work. See also: * https://github.com/wolfSSL/wolfssl/tree/master/examples/client */ - /* See companion wolfssl_server.ino code */ return; } /* Arduino setup */ @@ -731,7 +797,7 @@ int error_check_ssl(WOLFSSL* ssl, int this_ret, bool halt_on_error, } return err; -} +} /* error_check_ssl */ /*****************************************************************************/ /*****************************************************************************/ diff --git a/examples/wolfssl_client_dtls/README.md b/examples/wolfssl_client_dtls/README.md new file mode 100644 index 0000000..924225b --- /dev/null +++ b/examples/wolfssl_client_dtls/README.md @@ -0,0 +1,28 @@ +# Arduino Basic DTLS Listening Client + +Open the [wolfssl_client_dtls.ino](./wolfssl_client_dtls.ino) file in the Arduino IDE. + +If using WiFi, be sure to set `ssid` and `password` values. + +May need "Ethernet by Various" library to be installed. Tested with v2.0.2 and v2.8.1. + +See the `#define WOLFSSL_TLS_SERVER_HOST` to set your own server address. + +Other IDE products are also supported, such as: + +- [PlatformIO in VS Code](https://docs.platformio.org/en/latest/frameworks/arduino.html) +- [VisualGDB](https://visualgdb.com/tutorials/arduino/) +- [VisualMicro](https://www.visualmicro.com/) + +For examples on other platforms, see the [IDE directory](https://github.com/wolfssl/wolfssl/tree/master/IDE). +Additional examples can be found on [wolfSSL/wolfssl-examples](https://github.com/wolfSSL/wolfssl-examples/). + + +### Troubleshooting + +When encountering odd errors such as `undefined reference to ``_impure_ptr'`, try cleaning the Arduino +cache directories. For Windows, that's typically in: + +```text +C:\Users\%USERNAME%\AppData\Local\Temp\arduino\sketches +``` diff --git a/examples/wolfssl_client_dtls/wolfssl_client_dtls.ino b/examples/wolfssl_client_dtls/wolfssl_client_dtls.ino new file mode 100644 index 0000000..e4e8fec --- /dev/null +++ b/examples/wolfssl_client_dtls/wolfssl_client_dtls.ino @@ -0,0 +1,950 @@ +/* + * client-dtls13.c + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + * + *============================================================================= + * + * Bare-bones example of a DTLS 1.3 client for instructional/learning purposes. + * This example uses blocking sockets for simplicity. + * + * Define USE_DTLS12 to use DTLS 1.2 instead of DTLS 1.3 +/* +Tested with: + +1) Intel Galileo acting as the Client, with a laptop acting as a server using + the server example provided in examples/server. + Legacy Arduino v1.86 was used to compile and program the Galileo + +2) Espressif ESP32 WiFi + +3) Arduino Due, Nano33 IoT, Nano RP-2040 +*/ + +/* + * Note to code editors: the Arduino client and server examples are edited in + * parallel for side-by-side comparison between examples. + */ + +/* If you have a private include, define it here, otherwise edit WiFi params */ +/* #define MY_PRIVATE_CONFIG "/workspace/my_private_config.h" */ + +#if defined(ARDUINO) && defined(ESP8266) + #warning "This example is not yet supported on Arduino ESP8266" +#endif + +#if defined(DEBUG_WOLFSSL) + /* Optionally enabled verbose wolfSSL debugging */ + #define DEBUG_WOLFSSL_MESSAGES_ON +#else + /* DEBUG_WOLFSSL needs to be enabled */ + #undef DEBUG_WOLFSSL_MESSAGES_ON +#endif + +/* set REPEAT_CONNECTION to a non-zero value to continually run the example. */ +#define REPEAT_CONNECTION 0 + +/* Edit this with your other DTLS host server address to connect to: */ +#define WOLFSSL_DTLS_SERVER_HOST "192.168.1.107" + +/* wolfssl TLS examples communicate on port 11111 */ +#define WOLFSSL_PORT 11111 + +/* Choose a monitor serial baud rate: 9600, 14400, 19200, 57600, 74880, etc. */ +#define SERIAL_BAUD 115200 + +/* We'll wait up to 2000 milliseconds to properly shut down connection */ +#define SHUTDOWN_DELAY_MS 2000 + +/* Number of times to retry connection. */ +#define RECONNECT_ATTEMPTS 20 + +/* Number of DTLS messages to send. Use -1 for continual messages. */ +#define DTLS_MESSAGE_CT 42 + +/* Assume bad socket until proven otherwise */ +#define INVALID_SOCKET -1 + +/* Maximum size in bytes of buffer to send and receive */ +#define MAXLINE 128 + +/* Optional stress test. Define to consume memory until exhausted: */ +/* #define MEMORY_STRESS_TEST */ + +/* Choose client or server example, not both. */ +#define WOLFSSL_CLIENT_EXAMPLE +/* #define WOLFSSL_SERVER_EXAMPLE */ + +#if defined(MY_PRIVATE_CONFIG) + /* the /workspace directory may contain a private config + * excluded from GitHub with items such as WiFi passwords */ + #include MY_PRIVATE_CONFIG + static const char ssid[] PROGMEM = MY_ARDUINO_WIFI_SSID; + static const char password[] PROGMEM = MY_ARDUINO_WIFI_PASSWORD; +#else + /* when using WiFi capable boards: */ + static const char ssid[] PROGMEM = "your_SSID"; + static const char password[] PROGMEM = "your_PASSWORD"; +#endif + +#define BROADCAST_ADDRESS "255.255.255.255" + +/* There's an optional 3rd party NTPClient library by Fabrice Weinberg. + * If it is installed, uncomment define USE_NTP_LIB here: */ +/* #define USE_NTP_LIB */ +#ifdef USE_NTP_LIB + #include +#endif + +/* wolfSSL user_settings.h must be included from settings.h + * Make all configurations changes in user_settings.h + * Do not edit wolfSSL `settings.h` or `config.h` files. + * Do not explicitly include user_settings.h in any source code. + * Each Arduino sketch that uses wolfSSL must have: #include "wolfssl.h" + * C/C++ source files can use: #include + * The wolfSSL "settings.h" must be included in each source file using wolfSSL. + * The wolfSSL "settings.h" must appear before any other wolfSSL include. + */ +#include +/* Important: make sure settings.h appears before any other wolfSSL headers */ +#include +/* Reminder: settings.h includes user_settings.h + * For ALL project wolfSSL settings, see: + * [your path]/Arduino\libraries\wolfSSL\src\user_settings.h */ +#include +#include +#include + +#ifndef WOLFSSL_DTLS + /* Support for DTLS by default was added after wolfSSL v5.8.2 release */ + #error "This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library" +#endif + +/* Define DEBUG_WOLFSSL in user_settings.h for more verbose logging. */ +#if defined(DEBUG_WOLFSSL) + #define PROGRESS_DOT F("") +#else + #define PROGRESS_DOT F(".") +#endif + +/* Convert a macro to a string */ +#define xstr(x) str(x) +#define str(x) #x + +/* optional board-specific networking includes */ +#if defined(ESP32) + #define USING_WIFI + #include + #include + #ifdef USE_NTP_LIB + WiFiUDP ntpUDP; + #endif + /* Ensure the F() flash macro is defined */ + #ifndef F + #define F + #endif + WiFiClient client; + +#elif defined(ESP8266) + #define USING_WIFI + #include + WiFiClient client; + +#elif defined(ARDUINO_SAM_DUE) + #include + /* There's no WiFi/Ethernet on the Due. Requires Ethernet Shield. + /* Needs "Ethernet by Various" library to be installed. Tested with V2.0.2 */ + #include + EthernetClient client; +#elif defined(ARDUINO_AVR_ETHERNET) || defined(ARDUINO_AVR_LEONARDO_ETH) + /* Boards such as arduino:avr:ethernet and arduino:avr:leonardoeth */ + #include + EthernetClient client; + +#elif defined(ARDUINO_SAMD_NANO_33_IOT) + #define USING_WIFI + #include + #include /* Needs Arduino WiFiNINA library installed manually */ + WiFiClient client; + +#elif defined(ARDUINO_ARCH_RP2040) + #define USING_WIFI + #include + #include + WiFiClient client; + +#elif defined(ARDUINO_SAMD_TIAN) + #include + #include + HttpClient client; + /* Arduino Tian does not support network shields like the standard Ethernet or Wi-Fi shields. */ + #error "HttpClient cannot be used for this example" +#elif defined(ARDUINO_PORTENTA_X8) + /* The Portenta is a Linux device. See wolfSSL examples: + * https://github.com/wolfSSL/wolfssl/tree/master/examples + * By default Serial is disabled and mapped to ErrorSerial */ + #include + + /* ----No - network placeholders(compile - only) ---- */ + #include + struct X8NoNetClient { + int write(const uint8_t*, size_t) { return -1; } + int available() { return 0; } + int read() { return -1; } + void stop() {} + bool connected() { return false; } + IPAddress remoteIP() { return IPAddress(0, 0, 0, 0); } + }; + struct X8NoNetServer { + explicit X8NoNetServer(uint16_t) {} + void begin() {} + X8NoNetClient available() { return X8NoNetClient(); } + }; + + X8NoNetClient client; + X8NoNetServer server(WOLFSSL_PORT); +#elif defined(USING_WIFI) + #define USING_WIFI + #include + #include + #ifdef USE_NTP_LIB + WiFiUDP ntpUDP; + #endif + WiFiClient client; + +/* TODO +#elif defined(OTHER_BOARD) +*/ +#else + /* assume all other boards using WiFi library. Edit as needed: */ + #include + #define USING_WIFI + WiFiClient client; +#endif + +/* Only for syntax highlighters to show interesting options enabled: */ +#if defined(HAVE_SNI) \ + || defined(HAVE_MAX_FRAGMENT) \ + || defined(HAVE_TRUSTED_CA) \ + || defined(HAVE_TRUNCATED_HMAC) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) \ + || defined(HAVE_SUPPORTED_CURVES) \ + || defined(HAVE_ALPN) \ + || defined(HAVE_SESSION_TICKET) \ + || defined(HAVE_SECURE_RENEGOTIATION) \ + || defined(HAVE_SERVER_RENEGOTIATION_INFO) +#endif + +static const char host[] PROGMEM = WOLFSSL_DTLS_SERVER_HOST; /* server to connect to */ +static const int port PROGMEM = WOLFSSL_PORT; /* port on server to connect to */ + +static WOLFSSL_CTX* ctx = NULL; +static WOLFSSL* ssl = NULL; +static char* wc_error_message = (char*)malloc(80 + 1); +static char errBuf[80]; + +#if defined(MEMORY_STRESS_TEST) + #define MEMORY_STRESS_ITERATIONS 100 + #define MEMORY_STRESS_BLOCK_SIZE 1024 + #define MEMORY_STRESS_INITIAL (4*1024) + static char* memory_stress[MEMORY_STRESS_ITERATIONS]; /* typically 1K per item */ + static int mem_ctr = 0; +#endif + +static int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx); +static int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx); +static int reconnect = RECONNECT_ATTEMPTS; +#if 0 +/* optional showPeerEx, currently disabled */ +static int lng_index PROGMEM = 0; /* 0 = English */ +#endif + +#if defined(__arm__) + #include + extern char _end; + extern "C" char *sbrk(int i); + static char *ramstart=(char *)0x20070000; + static char *ramend=(char *)0x20088000; +#endif + +/*****************************************************************************/ +/* fail_wait - in case of unrecoverable error */ +/*****************************************************************************/ +int fail_wait(void) { + show_memory(); + + Serial.println(F("Failed. Halt.")); + while (1) { + delay(1000); + } + return 0; +} + +/*****************************************************************************/ +/* show_memory() to optionally view during debugging. */ +/*****************************************************************************/ +int show_memory(void) +{ +#if defined(__arm__) + struct mallinfo mi = mallinfo(); + + char *heapend=sbrk(0); + register char * stack_ptr asm("sp"); + #if defined(DEBUG_WOLFSSL_VERBOSE) + Serial.print(" arena="); + Serial.println(mi.arena); + Serial.print(" ordblks="); + Serial.println(mi.ordblks); + Serial.print(" uordblks="); + Serial.println(mi.uordblks); + Serial.print(" fordblks="); + Serial.println(mi.fordblks); + Serial.print(" keepcost="); + Serial.println(mi.keepcost); + #endif + + #if defined(DEBUG_WOLFSSL) || defined(MEMORY_STRESS_TEST) + Serial.print("Estimated free memory: "); + Serial.print(stack_ptr - heapend + mi.fordblks); + Serial.println(F(" bytes")); + #endif + + #if (0) + /* Experimental: not supported on all devices: */ + Serial.print("RAM Start %lx\n", (unsigned long)ramstart); + Serial.print("Data/Bss end %lx\n", (unsigned long)&_end); + Serial.print("Heap End %lx\n", (unsigned long)heapend); + Serial.print("Stack Ptr %lx\n",(unsigned long)stack_ptr); + Serial.print("RAM End %lx\n", (unsigned long)ramend); + + Serial.print("Heap RAM Used: ",mi.uordblks); + Serial.print("Program RAM Used ",&_end - ramstart); + Serial.print("Stack RAM Used ",ramend - stack_ptr); + + Serial.print("Estimated Free RAM: %d\n\n",stack_ptr - heapend + mi.fordblks); + #endif +#else + Serial.println(F("show_memory() not implemented for this platform")); +#endif + return 0; +} + +/*****************************************************************************/ +/* Arduino setup_hardware() */ +/*****************************************************************************/ +int setup_hardware(void) { + int ret = 0; + +#if defined(ARDUINO_SAMD_NANO_33_IOT) + Serial.println(F("Detected known tested and working Arduino Nano 33 IoT")); +#elif defined(ARDUINO_ARCH_RP2040) + Serial.println(F("Detected known tested and working Arduino RP-2040")); +#elif defined(__arm__) && defined(ID_TRNG) && defined(TRNG) + /* need to manually turn on random number generator on Arduino Due, etc. */ + pmc_enable_periph_clk(ID_TRNG); + trng_enable(TRNG); + Serial.println(F("Enabled ARM TRNG")); +#endif + + show_memory(); + randomSeed(analogRead(0)); + return ret; +} + +/*****************************************************************************/ +/* Arduino setup_datetime() */ +/* The device needs to have a valid date within the valid range of certs. */ +/*****************************************************************************/ +int setup_datetime(void) { + int ret = 0; + int ntp_tries = 20; + + /* we need a date in the range of cert expiration */ +#ifdef USE_NTP_LIB + #if defined(ESP32) + NTPClient timeClient(ntpUDP, "pool.ntp.org"); + + timeClient.begin(); + timeClient.update(); + delay(1000); + while (!timeClient.isTimeSet() && (ntp_tries > 0)) { + timeClient.forceUpdate(); + Serial.println(F("Waiting for NTP update")); + delay(2000); + ntp_tries--; + } + if (ntp_tries <= 0) { + Serial.println(F("Warning: gave up waiting on NTP")); + } + Serial.println(timeClient.getFormattedTime()); + Serial.println(timeClient.getEpochTime()); + #endif +#endif + +#if defined(ESP32) + /* see esp32-hal-time.c */ + ntp_tries = 5; + /* Replace "pool.ntp.org" with your preferred NTP server */ + configTime(0, 0, "pool.ntp.org"); + + /* Wait for time to be set */ + while ((time(nullptr) <= 100000) && ntp_tries > 0) { + Serial.println(F("Waiting for time to be set...")); + delay(2000); + ntp_tries--; + } +#endif + + return ret; +} /* setup_datetime */ + +/*****************************************************************************/ +/* Arduino setup_network() */ +/*****************************************************************************/ +int setup_network(void) { + int ret = 0; + +#if defined(USING_WIFI) + int status = WL_IDLE_STATUS; + + /* The ESP8266 & ESP32 support both AP and STA. We'll use STA: */ + #if defined(ESP8266) || defined(ESP32) + WiFi.mode(WIFI_STA); + #else + String fv; + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + /* don't continue if no network */ + while (true) ; + } + + fv = WiFi.firmwareVersion(); + if (fv < WIFI_FIRMWARE_LATEST_VERSION) { + Serial.println("Please upgrade the firmware"); + } + #endif + + Serial.print(F("Connecting to WiFi ")); + Serial.print(ssid); + status = WiFi.begin(ssid, password); + while (status != WL_CONNECTED) { + delay(1000); + Serial.print(F(".")); + Serial.print(status); + status = WiFi.status(); + } + + Serial.println(F(" Connected!")); +#else + /* Newer Ethernet shields have a + * MAC address printed on a sticker on the shield */ + byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; + IPAddress ip(192, 168, 1, 42); + IPAddress myDns(192, 168, 1, 1); + Ethernet.init(10); /* Most Arduino shields */ + /* Ethernet.init(5); * MKR ETH Shield */ + /* Ethernet.init(0); * Teensy 2.0 */ + /* Ethernet.init(20); * Teensy++ 2.0 */ + /* Ethernet.init(15); * ESP8266 with Adafruit FeatherWing Ethernet */ + /* Ethernet.init(33); * ESP32 with Adafruit FeatherWing Ethernet */ + Serial.println(F("Initialize Ethernet with DHCP:")); + if (Ethernet.begin(mac) == 0) { + Serial.println(F("Failed to configure Ethernet using DHCP")); + /* Check for Ethernet hardware present */ + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println(F("Ethernet shield was not found.")); + while (true) { + delay(1); /* do nothing */ + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println(F("Ethernet cable is not connected.")); + } + /* try to configure using IP address instead of DHCP : */ + Ethernet.begin(mac, ip, myDns); + } + else { + Serial.print(F(" DHCP assigned IP ")); + Serial.println(Ethernet.localIP()); + } + /* We'll assume the Ethernet connection is ready to go. */ +#endif + + Serial.println(F("********************************************************")); + Serial.print(F(" wolfSSL Example Client IP = ")); +#if defined(USING_WIFI) + Serial.println(WiFi.localIP()); +#else + Serial.println(Ethernet.localIP()); +#endif + Serial.print(F(" Configured Server Host to connect to: ")); + Serial.println(host); + Serial.println(F("********************************************************")); + Serial.println(F("Setup network complete.")); + + return ret; +} + +/*****************************************************************************/ +/* Arduino setup_wolfssl() */ +/*****************************************************************************/ +int setup_wolfssl(void) +{ + int ret = 0; + WOLFSSL_METHOD* method; + + /* Show a revision of wolfssl user_settings.h file in use when available: */ +#if defined(WOLFSSL_USER_SETTINGS_ID) + Serial.print(F("WOLFSSL_USER_SETTINGS_ID: ")); + Serial.println(F(WOLFSSL_USER_SETTINGS_ID)); +#else + Serial.println(F("No WOLFSSL_USER_SETTINGS_ID found.")); +#endif + +#if defined(NO_WOLFSSL_SERVER) + Serial.println(F("wolfSSL server code disabled to save space.")); +#endif +#if defined(NO_WOLFSSL_CLIENT) + Serial.println(F("wolfSSL client code disabled to save space.")); +#endif + +#if defined(DEBUG_WOLFSSL) + Serial.println(F("wolfSSL Debugging is available! (DEBUG_WOLFSSL)")); + #if defined(DEBUG_WOLFSSL_MESSAGES_ON) + Serial.println(F("Enabling verbose messages wolfSSL_Debugging_ON")); + wolfSSL_Debugging_ON(); + #else + Serial.println(F("Enable verbose messages with wolfSSL_Debugging_ON")); + Serial.println(F("or define DEBUG_WOLFSSL_MESSAGES_ON")); + #endif +#else + Serial.println(F("wolfSSL Debugging is Off! (enable with DEBUG_WOLFSSL)")); +#endif + + /* See ssl.c for TLS cache settings. Larger cache = use more RAM. */ +#if defined(NO_SESSION_CACHE) + Serial.println(F("wolfSSL TLS NO_SESSION_CACHE")); +#elif defined(MICRO_SESSION_CACHEx) + Serial.println(F("wolfSSL TLS MICRO_SESSION_CACHE")); +#elif defined(SMALL_SESSION_CACHE) + Serial.println(F("wolfSSL TLS SMALL_SESSION_CACHE")); +#elif defined(MEDIUM_SESSION_CACHE) + Serial.println(F("wolfSSL TLS MEDIUM_SESSION_CACHE")); +#elif defined(BIG_SESSION_CACHE) + Serial.println(F("wolfSSL TLS BIG_SESSION_CACHE")); +#elif defined(HUGE_SESSION_CACHE) + Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE")); +#elif defined(HUGE_SESSION_CACHE) + Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE")); +#else + Serial.println(F("WARNING: Unknown or no TLS session cache setting.")); + /* See wolfssl/src/ssl.c for amount of memory used. + * It is best on embedded devices to choose a TLS session cache size. */ +#endif + + /* Initialize wolfSSL before assigning ctx */ + ret = wolfSSL_Init(); + if (ret == WOLFSSL_SUCCESS) { + Serial.println("Successfully called wolfSSL_Init"); + } + else { + Serial.println("ERROR: wolfSSL_Init failed"); + } + + /* See companion server example with wolfSSLv23_server_method here. + * method = wolfSSLv23_client_method()); SSL 3.0 - TLS 1.3. + * method = wolfTLSv1_2_client_method(); only TLS 1.2 + * method = wolfTLSv1_3_client_method(); only TLS 1.3 + * + * see Arduino\libraries\wolfssl\src\user_settings.h */ + + Serial.println("Here we go!"); + +#ifdef WOLFSSL_DTLS13 + Serial.println(F("Setting wolfDTLSv1_3_client_method")); + method = wolfDTLSv1_3_client_method(); +#else + Serial.println(F("Setting wolfDTLSv1_2_client_method")); + method = wolfDTLSv1_2_client_method(); +#endif + ctx = wolfSSL_CTX_new(method); + if (ctx == NULL) { + fail_wait(); + } + + if (method == NULL) { + Serial.println(F("Unable to get wolfssl client method")); + fail_wait(); + } + + ctx = wolfSSL_CTX_new(method); + if (ctx == NULL) { + Serial.println(F("unable to get ctx")); + fail_wait(); + } + + return ret; +} + +/*****************************************************************************/ +/* Arduino setup_certificates() */ +/*****************************************************************************/ +int setup_certificates(void) +{ + int ret = 0; + + /* See user_settings.h that should have included wolfssl/certs_test.h */ + + Serial.println(F("Initializing certificates...")); + show_memory(); + + /* Use built-in validation, No verification callback function: */ + wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, 0); + + /* Certificate */ + Serial.println("Initializing certificates..."); + ret = wolfSSL_CTX_use_certificate_buffer(ctx, + CTX_CLIENT_CERT, + CTX_CLIENT_CERT_SIZE, + CTX_CLIENT_CERT_TYPE); + if (ret == WOLFSSL_SUCCESS) { + Serial.print("Success: use certificate: "); + Serial.println(xstr(CTX_SERVER_CERT)); + } + else { + Serial.println(F("Error: wolfSSL_CTX_use_certificate_buffer failed: ")); + wc_ErrorString(ret, wc_error_message); + Serial.println(wc_error_message); + fail_wait(); + } + + /* Setup private client key */ + ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, + CTX_CLIENT_KEY, + CTX_CLIENT_KEY_SIZE, + CTX_CLIENT_KEY_TYPE); + if (ret == WOLFSSL_SUCCESS) { + Serial.print("Success: use private key buffer: "); + Serial.println(xstr(CTX_SERVER_KEY)); + } + else { + Serial.println(F("Error: wolfSSL_CTX_use_PrivateKey_buffer failed: ")); + wc_ErrorString(ret, wc_error_message); + Serial.println(wc_error_message); + fail_wait(); + } + + ret = wolfSSL_CTX_load_verify_buffer(ctx, + CTX_CA_CERT, + CTX_CA_CERT_SIZE, + CTX_CA_CERT_TYPE); + if (ret == WOLFSSL_SUCCESS) { + Serial.println(F("Success: load_verify CTX_CA_CERT")); + } + else { + Serial.println(F("Error: wolfSSL_CTX_load_verify_buffer failed: ")); + wc_ErrorString(ret, wc_error_message); + Serial.println(wc_error_message); + fail_wait(); + } + + return ret; +} /* Arduino setup */ + +/*****************************************************************************/ +/*****************************************************************************/ +/* Arduino setup() */ +/*****************************************************************************/ +/*****************************************************************************/ +void setup(void) { + int i = 0; + Serial.begin(SERIAL_BAUD); + while (!Serial && (i < 10)) { + /* wait for serial port to connect. Needed for native USB port only */ + delay(1000); + i++; + } + Serial.println(F("")); + Serial.println(F("")); + Serial.println(F("wolfSSL DTLS Client Example Startup.")); + + /* Optionally pre-allocate a large block of memory for testing */ +#if defined(MEMORY_STRESS_TEST) + Serial.println(F("WARNING: Memory Stress Test Active!")); + Serial.print(F("Allocating extra memory: ")); + Serial.print(MEMORY_STRESS_INITIAL); + Serial.println(F(" bytes...")); + memory_stress[mem_ctr] = (char*)malloc(MEMORY_STRESS_INITIAL); + show_memory(); +#endif + + setup_hardware(); + + setup_network(); + + setup_datetime(); + + setup_wolfssl(); + + setup_certificates(); + +#if defined THIS_USER_SETTINGS_VERSION + Serial.print(F("This user_settings.h version:")) + Serial.println(THIS_USER_SETTINGS_VERSION) +#endif + + Serial.println(F("Completed Arduino setup!")); + /* See companion wolfssl_server_dtls.ino code; server begins listening here + * https://github.com/wolfSSL/wolfssl-examples/tree/master/Arduino/sketches/wolfssl_server_dtls + * Any other DTLS server will work. See also: + * https://github.com/wolfSSL/wolfssl/tree/master/examples/client + */ + return; +} /* Arduino setup */ + +/*****************************************************************************/ +/* wolfSSL error_check() */ +/*****************************************************************************/ +int error_check(int this_ret, bool halt_on_error, + const __FlashStringHelper* message) { + int ret = 0; + if (this_ret == WOLFSSL_SUCCESS) { + Serial.print(F("Success: ")); + Serial.println(message); + } + else { + Serial.print(F("ERROR: return = ")); + Serial.print(this_ret); + Serial.print(F(": ")); + Serial.println(message); + Serial.println(wc_GetErrorString(this_ret)); + if (halt_on_error) { + fail_wait(); + } + } + show_memory(); + + return ret; +} /* error_check */ + +/*****************************************************************************/ +/* wolfSSL error_check_ssl */ +/* Parameters: */ +/* ssl is the current WOLFSSL object pointer */ +/* halt_on_error set to true to suspend operations for critical error */ +/* message is expected to be a memory-efficient F("") macro string */ +/*****************************************************************************/ +int error_check_ssl(WOLFSSL* ssl, int this_ret, bool halt_on_error, + const __FlashStringHelper* message) { + int err = 0; + + if (ssl == NULL) { + Serial.println(F("ssl is Null; Unable to allocate SSL object?")); +#ifndef DEBUG_WOLFSSL + Serial.println(F("Define DEBUG_WOLFSSL in user_settings.h for more.")); +#else + Serial.println(F("See wolfssl/wolfcrypt/error-crypt.h for codes.")); +#endif + Serial.print(F("ERROR: ")); + Serial.println(message); + show_memory(); + if (halt_on_error) { + fail_wait(); + } + } + else { + err = wolfSSL_get_error(ssl, this_ret); + if (err == WOLFSSL_SUCCESS) { + Serial.print(F("Success m: ")); + Serial.println(message); + } + else { + if (err < 0) { + wolfSSL_ERR_error_string(err, errBuf); + Serial.print(F("WOLFSSL Error: ")); + Serial.print(err); + Serial.print(F("; ")); + Serial.println(errBuf); + } + else { + Serial.println(F("Success: ssl object.")); + } + } + } + + return err; +} /* error_check_ssl */ + +/*****************************************************************************/ +/*****************************************************************************/ +/* Arduino loop() */ +/*****************************************************************************/ +/*****************************************************************************/ +void loop() +{ + /* standard variables used in a dtls client */ + char sendLine[MAXLINE] = "Hello DTLS wolfSSL!"; + char recvLine[MAXLINE - 1]; + struct sockaddr_in servAddr; + const char* cipherName; + int msg_ct = 0; + int n = 0; + int sockfd = INVALID_SOCKET; + int err; + int ret; + int exitVal = 1; + + /* Assign ssl variable */ + ssl = wolfSSL_new(ctx); + if (ssl == NULL) { + Serial.println(F("unable to get ssl object\n")); + goto cleanup; + } + + /* servAddr setup */ + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_port = htons(WOLFSSL_PORT); + if (inet_pton(AF_INET, WOLFSSL_DTLS_SERVER_HOST, &servAddr.sin_addr) < 1) { + perror("inet_pton()"); + goto cleanup; + } + + if (wolfSSL_dtls_set_peer(ssl, &servAddr, sizeof(servAddr)) + != WOLFSSL_SUCCESS) { + Serial.println(F("wolfSSL_dtls_set_peer failed\n")); + goto cleanup; + } + + if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + perror("socket()"); + goto cleanup; + } + + /* Set the file descriptor for ssl */ + if (wolfSSL_set_fd(ssl, sockfd) != WOLFSSL_SUCCESS) { + Serial.println(F("cannot set socket file descriptor\n")); + goto cleanup; + } + + Serial.print(F("Connecting to wolfSSL DTLS Secure Server...")); + do { + reconnect--; + err = 0; /* reset error */ + Serial.println(F("wolfSSL_connect ...")); + ret = wolfSSL_connect(ssl); + if ((ret != WOLFSSL_SUCCESS) && (ret != WC_PENDING_E)) { + Serial.println(F("Failed connection, checking error.")); + err = error_check_ssl(ssl, ret, true, + F("Create WOLFSSL object from ctx")); + Serial.print("err ="); + Serial.println(err); + } + else { + Serial.print(PROGRESS_DOT); + } + } while ((err == WC_PENDING_E) && (reconnect > 0)); + + Serial.println(); + Serial.println(F("Connected!")); + Serial.print(F("SSL version is ")); + Serial.println(wolfSSL_get_version(ssl)); + + cipherName = wolfSSL_get_cipher(ssl); + Serial.print(F("SSL cipher suite is ")); + Serial.println(cipherName); + +/*****************************************************************************/ +/* Code for sending datagram to server */ +/*****************************************************************************/ + Serial.println(F("Begin DTLS Loop...")); + msg_ct = 0; + while (msg_ct < DTLS_MESSAGE_CT || (DTLS_MESSAGE_CT == -1)) { + msg_ct++; + + /* Send sendLine to the server */ + Serial.print(F("Sending Message #")); + Serial.print(msg_ct); + Serial.print(F(": \"")); + Serial.print(F(sendLine)); + Serial.println(F("\" ... ")); + if (wolfSSL_write(ssl, sendLine, strlen(sendLine)) != strlen(sendLine)) { + err = error_check_ssl(ssl, ret, true, + F("Create WOLFSSL object from ctx")); + Serial.print("err ="); + Serial.println(err); + goto cleanup; + } + + /* n is the # of bytes received */ + Serial.println(F("Reading Message...")); + n = wolfSSL_read(ssl, recvLine, sizeof(recvLine)-1); + + if (n > 0) { + /* Add a terminating character to the generic server message */ + recvLine[n] = '\0'; + Serial.println(F("Got Message...")); + printf("%s\n", recvLine); + } + else { + err = error_check_ssl(ssl, ret, true, + F("Create WOLFSSL object from ctx")); + Serial.print("err ="); + Serial.println(err); + goto cleanup; + } + + } /* (msg_ct > DTLS_MESSAGE_CT || (DTLS_MESSAGE_CT == -1)) */ + + exitVal = 0; +cleanup: + if (ssl != NULL) { + /* Attempt a full shutdown */ + ret = wolfSSL_shutdown(ssl); + if (ret == WOLFSSL_SHUTDOWN_NOT_DONE) { + Serial.println("Not done... Try again wolfSSL_shutdown"); + ret = wolfSSL_shutdown(ssl); + } + + if (ret != WOLFSSL_SUCCESS) { + err = error_check_ssl(ssl, ret, true, + F("Create WOLFSSL object from ctx")); + Serial.print("err ="); + Serial.println(err); + Serial.println(F("wolfSSL_shutdown failed\n")); + } + wolfSSL_free(ssl); + } + if (sockfd != INVALID_SOCKET) { + close(sockfd); + } + if (ctx != NULL) { + wolfSSL_CTX_free(ctx); + } + wolfSSL_Cleanup(); + + Serial.print(F("Reset to start over.")); + Serial.print(F("Done!")); + + while (1) { + delay(1000); + } +} /* Arduino loop */ + diff --git a/examples/wolfssl_server/wolfssl_server.ino b/examples/wolfssl_server/wolfssl_server.ino index 1b9d4ed..7f75bcc 100644 --- a/examples/wolfssl_server/wolfssl_server.ino +++ b/examples/wolfssl_server/wolfssl_server.ino @@ -6,7 +6,7 @@ * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, @@ -39,6 +39,18 @@ Tested with: /* If you have a private include, define it here, otherwise edit WiFi params */ /* #define MY_PRIVATE_CONFIG "/workspace/my_private_config.h" */ +#if defined(ARDUINO) && defined(ESP8266) + #warning "This example is not yet supported on Arduino ESP8266" +#endif + +#if defined(DEBUG_WOLFSSL) + /* Optionally enabled verbose wolfSSL debugging */ + #define DEBUG_WOLFSSL_MESSAGES_ON +#else + /* DEBUG_WOLFSSL needs to be enabled */ + #undef DEBUG_WOLFSSL_MESSAGES_ON +#endif + /* set REPEAT_CONNECTION to a non-zero value to continually run the example. */ #define REPEAT_CONNECTION 1 @@ -68,12 +80,12 @@ Tested with: /* the /workspace directory may contain a private config * excluded from GitHub with items such as WiFi passwords */ #include MY_PRIVATE_CONFIG - static const char ssid[] PROGMEM = MY_ARDUINO_WIFI_SSID; - static const char password[] PROGMEM = MY_ARDUINO_WIFI_PASSWORD; + static const char ssid[] PROGMEM = MY_ARDUINO_WIFI_SSID; + static const char password[] PROGMEM = MY_ARDUINO_WIFI_PASSWORD; #else /* when using WiFi capable boards: */ - static const char ssid[] PROGMEM = "your_SSID"; - static const char password[] PROGMEM = "your_PASSWORD"; + static const char ssid[] PROGMEM = "your_SSID"; + static const char password[] PROGMEM = "your_PASSWORD"; #endif #define BROADCAST_ADDRESS "255.255.255.255" @@ -132,6 +144,10 @@ Tested with: #elif defined(ESP8266) #define USING_WIFI #include + /* Ensure the F() flash macro is defined */ + #ifndef F + #define F + #endif WiFiClient client; WiFiServer server(WOLFSSL_PORT); #elif defined(ARDUINO_SAM_DUE) @@ -140,7 +156,12 @@ Tested with: /* Needs "Ethernet by Various" library to be installed. Tested with V2.0.2 */ #include EthernetClient client; - EthernetClient server(WOLFSSL_PORT); + EthernetServer server(WOLFSSL_PORT); +#elif defined(ARDUINO_AVR_ETHERNET) || defined(ARDUINO_AVR_LEONARDO_ETH) + /* Boards such as arduino:avr:ethernet and arduino:avr:leonardoeth */ + #include + EthernetClient client; + EthernetServer server(WOLFSSL_PORT); #elif defined(ARDUINO_SAMD_NANO_33_IOT) #define USING_WIFI #include @@ -153,6 +174,36 @@ Tested with: #include WiFiClient client; WiFiServer server(WOLFSSL_PORT); +#elif defined(ARDUINO_SAMD_TIAN) + #include + #include + HttpClient client; + /* Arduino Tian does not support network shields like the standard Ethernet or Wi-Fi shields. */ + #error "HttpClient cannot be used for this example" +#elif defined(ARDUINO_PORTENTA_X8) + /* The Portenta is a Linux device. See wolfSSL examples: + * https://github.com/wolfSSL/wolfssl/tree/master/examples + * By default Serial is disabled and mapped to ErrorSerial */ + #include + + /* ----No - network placeholders(compile - only) ---- */ + #include + struct X8NoNetClient { + int write(const uint8_t*, size_t) { return -1; } + int available() { return 0; } + int read() { return -1; } + void stop() {} + bool connected() { return false; } + IPAddress remoteIP() { return IPAddress(0, 0, 0, 0); } + }; + struct X8NoNetServer { + explicit X8NoNetServer(uint16_t) {} + void begin() {} + X8NoNetClient available() { return X8NoNetClient(); } + }; + + X8NoNetClient client; + X8NoNetServer server(WOLFSSL_PORT); #elif defined(USING_WIFI) #define USING_WIFI #include @@ -206,7 +257,10 @@ static char errBuf[80]; static int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx); static int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx); static int reconnect = RECONNECT_ATTEMPTS; +#if 0 +/* optional showPeerEx, currently disabled */ static int lng_index PROGMEM = 0; /* 0 = English */ +#endif #if defined(__arm__) #include @@ -463,7 +517,8 @@ int setup_network(void) { /*****************************************************************************/ /* Arduino setup_wolfssl() */ /*****************************************************************************/ -int setup_wolfssl(void) { +int setup_wolfssl(void) +{ int ret = 0; WOLFSSL_METHOD* method; @@ -483,8 +538,14 @@ int setup_wolfssl(void) { #endif #if defined(DEBUG_WOLFSSL) - wolfSSL_Debugging_ON(); - Serial.println(F("wolfSSL Debugging is On!")); + Serial.println(F("wolfSSL Debugging is available! (DEBUG_WOLFSSL)")); + #if defined(DEBUG_WOLFSSL_MESSAGES_ON) + Serial.println(F("Enabling verbose messages wolfSSL_Debugging_ON")); + wolfSSL_Debugging_ON(); + #else + Serial.println(F("Enable verbose messages with wolfSSL_Debugging_ON")); + Serial.println(F("or define DEBUG_WOLFSSL_MESSAGES_ON")); + #endif #else Serial.println(F("wolfSSL Debugging is Off! (enable with DEBUG_WOLFSSL)")); #endif @@ -510,6 +571,7 @@ int setup_wolfssl(void) { * It is best on embedded devices to choose a TLS session cache size. */ #endif + /* Initialize wolfSSL before assigning ctx */ ret = wolfSSL_Init(); if (ret == WOLFSSL_SUCCESS) { Serial.println("Successfully called wolfSSL_Init"); @@ -544,7 +606,8 @@ int setup_wolfssl(void) { /*****************************************************************************/ /* Arduino setup_certificates() */ /*****************************************************************************/ -int setup_certificates(void) { +int setup_certificates(void) +{ int ret = 0; Serial.println(F("Initializing certificates...")); @@ -594,7 +657,8 @@ int setup_certificates(void) { /* Arduino setup() */ /*****************************************************************************/ /*****************************************************************************/ -void setup(void) { +void setup(void) +{ int i = 0; Serial.begin(SERIAL_BAUD); while (!Serial && (i < 10)) { @@ -725,7 +789,7 @@ int error_check_ssl(WOLFSSL* ssl, int this_ret, bool halt_on_error, } return err; -} +} /* error_check_ssl */ /*****************************************************************************/ /*****************************************************************************/ diff --git a/examples/wolfssl_server_dtls/README.md b/examples/wolfssl_server_dtls/README.md new file mode 100644 index 0000000..43deb7e --- /dev/null +++ b/examples/wolfssl_server_dtls/README.md @@ -0,0 +1,140 @@ +# Arduino Basic TLS Server + +Open the [wolfssl_server_dtls.ino](./wolfssl_server_dtls.ino) file in the Arduino IDE. + +If using WiFi, be sure to set `ssid` and `password` values. + +May need "Ethernet by Various" library to be installed. Tested with v2.0.2 and v2.8.1. + +See the `#define WOLFSSL_TLS_SERVER_HOST` to set your own server address. + +Other IDE products are also supported, such as: + +- [PlatformIO in VS Code](https://docs.platformio.org/en/latest/frameworks/arduino.html) +- [VisualGDB](https://visualgdb.com/tutorials/arduino/) +- [VisualMicro](https://www.visualmicro.com/) + +For examples on other platforms, see the [IDE directory](https://github.com/wolfssl/wolfssl/tree/master/IDE). +Additional examples can be found on [wolfSSL/wolfssl-examples](https://github.com/wolfSSL/wolfssl-examples/). + +## Connect with an Arduino Sketch + +See the companion [Arduino Sketch Client](../wolfssl_client/wolfssl_client_dtls.ino). + +## Connect with Linux Client + +See also the [wolfSSL Example TLS Client](https://github.com/wolfSSL/wolfssl/tree/master/examples/client) +and [wolfSSL Example TLS Server](https://github.com/wolfSSL/wolfssl/tree/master/examples/server). + +Assuming a listening [Arduino Sketch Server](./wolfssl_server.ino) at `192.168.1.38` on port `11111`, +connect with the `client` executable: + +``` +./examples/client/client -h 192.168.1.38 -p 11111 -v 3 +``` + +## wolfSSL Error -308 wolfSSL_connect error state on socket + +When using a wired Ethernet connection, and this error is encountered, simply +press the reset button or power cycle the Arduino before making a connection. + +Here's one possible script to test the server from a command-line client: + +```bash +#!/usr/bin/env bash +echo "client log " > client_log.txt +counter=1 +THIS_ERR=0 +while [ $THIS_ERR -eq 0 ]; do + ./examples/client/client -h 192.168.1.38 -p 11111 -v 3 >> client_log.txt + + THIS_ERR=$? + if [ $? -ne 0 ]; then + echo "Failed!" + exit 1 + fi + echo "Iteration $counter" + echo "Iteration $counter" >> client_log.txt + ((counter++)) +done +``` + +Output expected from the `client` command: + +``` +$ ./examples/client/client -h 192.168.1.38 -p 11111 -v 3 +Alternate cert chain used + issuer : /C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.wolfssl.com/emailAddress=info@wolfssl.com + subject: /C=US/ST=Montana/L=Bozeman/O=wolfSSL/OU=Support/CN=www.wolfssl.com/emailAddress=info@wolfssl.com + altname = example.com + altname = 127.0.0.1 + serial number:01 +SSL version is TLSv1.2 +SSL cipher suite is ECDHE-RSA-AES128-GCM-SHA256 +SSL curve name is SECP256R1 +--- +Server certificate +-----BEGIN CERTIFICATE----- +MIIE6DCCA9CgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBlDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNh +d3Rvb3RoMRMwEQYDVQQLDApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNz +bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjMxMjEz +MjIxOTI4WhcNMjYwOTA4MjIxOTI4WjCBkDELMAkGA1UEBhMCVVMxEDAOBgNVBAgM +B01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xEDAOBgNVBAoMB3dvbGZTU0wxEDAO +BgNVBAsMB1N1cHBvcnQxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG +SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMCVCOFXQfJxbbfSRUEnAWXGRa7yvCQwuJXOL07W9hyIvHyf+6hn +f/5cnFF194rKB+c1L4/hvXvAL3yrZKgX/Mpde7rgIeVyLm8uhtiVc9qsG1O5Xz/X +GQ0lT+FjY1GLC2Q/rUO4pRxcNLOuAKBjxfZ/C1loeHOmjBipAm2vwxkBLrgQ48bM +QLRpo0YzaYduxLsXpvPo3a1zvHsvIbX9ZlEMvVSz4W1fHLwjc9EJA4kU0hC5ZMMq +0KGWSrzh1Bpbx6DAwWN4D0Q3MDKWgDIjlaF3uhPSl3PiXSXJag3DOWCktLBpQkIJ +6dgIvDMgs1gip6rrxOHmYYPF0pbf2dBPrdcCAwEAAaOCAUUwggFBMB0GA1UdDgQW +BBSzETLJkpiE4sn40DtuA0LKHw6OPDCB1AYDVR0jBIHMMIHJgBQnjmcRdMMmHT/t +M2OzpNgdMOXo1aGBmqSBlzCBlDELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB01vbnRh +bmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNhd3Rvb3RoMRMwEQYDVQQL +DApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG +9w0BCQEWEGluZm9Ad29sZnNzbC5jb22CFDNEGqhsAez2YPJwUQpM0RT6vOlEMAwG +A1UdEwQFMAMBAf8wHAYDVR0RBBUwE4ILZXhhbXBsZS5jb22HBH8AAAEwHQYDVR0l +BBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBK/7nl +hZvaU2Z/ByK/thnqQuukEQdi/zlfMzc6hyZxPROyyrhkOHuKmUgOpaRrsZlu4EZR +vRlSrbymfip6fCOnzNteQ31rBMi33ZWt8JGAWcUZkSYnkbhIHOtVtqp9pDjxA7xs +i6qU1jwFepbFBvEmFC51+93lNbMBLLOtYlohmgi+Vvz5okKHhuWpxZnPrhS+4LkI +JA0dXNYU4UyfQLOp6S1Si0y/rEQxZ8GNBoXsD+SZ10t7IQZm1OT1nf+O8IY5WB2k +W+Jj73zJGIeoAiUQPoco+fXvR56lgAgRkGj+0aOoUbk3/9XKfId/a7wsEsjFhYv8 +DMa5hrjJBMNRN9JP +-----END CERTIFICATE----- +Session timeout set to 500 seconds +Client Random : 56A0BB9647B064D3F20947032B74B31FDB4C93DBAC9460BA8AEA213A2B2DD4A8 +SSL-Session: + Protocol : TLSv1.2 + Cipher : TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + Session-ID: 3255404E997FA9C27ECB4F1A20A70E722E4AA504B63A945FC175434D1907EC31 + Session-ID-ctx: + Master-Key: 67F22168BBADD678643BBA76B398277270C29788AC18FD05B57F6B715F49A7BCEEF75BEAF7FE266B0CC058534AF76C1F + TLS session ticket: NONE + Start Time: 1705533296 + Timeout : 500 (sec) + Extended master secret: no +I hear you fa shizzle! +``` + +### Troubleshooting + +When encountering odd errors such as `undefined reference to ``_impure_ptr'`, such as this: + +```text +c:/users/gojimmypi/appdata/local/arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/esp-2021r2-patch5-8.4.0/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: C:\Users\gojimmypi\AppData\Local\Temp\arduino\sketches\EAB8D79A02D1ECF107884802D893914E\libraries\wolfSSL\wolfcrypt\src\logging.c.o:(.literal.wolfssl_log+0x8): undefined reference to `_impure_ptr' +collect2.exe: error: ld returned 1 exit status + +exit status 1 + +Compilation error: exit status 1 +``` + +Try cleaning the Arduino cache directories. For Windows, that's typically in: + +```text +C:\Users\%USERNAME%\AppData\Local\Temp\arduino\sketches +``` + +Remove all other boards from other serial ports, leaving one the one being programmed. diff --git a/examples/wolfssl_server_dtls/wolfssl_server_dtls.ino b/examples/wolfssl_server_dtls/wolfssl_server_dtls.ino new file mode 100644 index 0000000..38e9148 --- /dev/null +++ b/examples/wolfssl_server_dtls/wolfssl_server_dtls.ino @@ -0,0 +1,984 @@ +/* server-dtls13.c + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + * + *============================================================================= + * + * Bare-bones example of a DTLS 1.3 server for instructional/learning purposes. + * This example can only accept one connection at a time. + * + * Define USE_DTLS12 to use DTLS 1.2 instead of DTLS 1.3 +/* +Tested with: + +1) Intel Galileo acting as the Client, with a laptop acting as a server using + the server example provided in examples/server. + Legacy Arduino v1.86 was used to compile and program the Galileo + +2) Espressif ESP32 WiFi + +3) Arduino Due, Nano33 IoT, Nano RP-2040 +*/ + +/* + * Note to code editors: the Arduino client and server examples are edited in + * parallel for side-by-side comparison between examples. + */ + +/* If you have a private include, define it here, otherwise edit WiFi params */ +/* #define MY_PRIVATE_CONFIG "/workspace/my_private_config.h" */ + +#if defined(ARDUINO) && defined(ESP8266) + #warning "This example is not yet supported on Arduino ESP8266" +#endif + +#if defined(DEBUG_WOLFSSL) + /* Optionally enabled verbose wolfSSL debugging */ + #define DEBUG_WOLFSSL_MESSAGES_ON +#else + /* DEBUG_WOLFSSL needs to be enabled */ + #undef DEBUG_WOLFSSL_MESSAGES_ON +#endif + +/* set REPEAT_CONNECTION to a non-zero value to continually run the example. */ +#define REPEAT_CONNECTION 0 + +/* Edit this with your other TLS host server address to connect to: */ +/* #define WOLFSSL_TLS_SERVER_HOST "192.168.1.39" */ + +/* wolfssl TLS examples communicate on port 11111 */ +#define WOLFSSL_PORT 11111 + +/* Choose a monitor serial baud rate: 9600, 14400, 19200, 57600, 74880, etc. */ +#define SERIAL_BAUD 115200 + +/* We'll wait up to 2000 milliseconds to properly shut down connection */ +#define SHUTDOWN_DELAY_MS 2000 + +/* Number of times to retry connection. */ +#define RECONNECT_ATTEMPTS 20 + +/* Assume bad socket until proven otherwise */ +#define INVALID_SOCKET -1 + +/* Maximum size in bytes of buffer to send and receive */ +#define MAXLINE 128 + +/* Optional stress test. Define to consume memory until exhausted: */ +/* #define MEMORY_STRESS_TEST */ + +/* Choose client or server example, not both. */ +/* #define WOLFSSL_CLIENT_EXAMPLE */ +#define WOLFSSL_SERVER_EXAMPLE + +#if defined(MY_PRIVATE_CONFIG) + /* the /workspace directory may contain a private config + * excluded from GitHub with items such as WiFi passwords */ + #include MY_PRIVATE_CONFIG + static const char ssid[] PROGMEM = MY_ARDUINO_WIFI_SSID; + static const char password[] PROGMEM = MY_ARDUINO_WIFI_PASSWORD; +#else + /* when using WiFi capable boards: */ + static const char ssid[] PROGMEM = "your_SSID"; + static const char password[] PROGMEM = "your_PASSWORD"; +#endif + +#define BROADCAST_ADDRESS "255.255.255.255" + +/* There's an optional 3rd party NTPClient library by Fabrice Weinberg. + * If it is installed, uncomment define USE_NTP_LIB here: */ +/* #define USE_NTP_LIB */ +#ifdef USE_NTP_LIB + #include +#endif + +/* wolfSSL user_settings.h must be included from settings.h + * Make all configurations changes in user_settings.h + * Do not edit wolfSSL `settings.h` or `config.h` files. + * Do not explicitly include user_settings.h in any source code. + * Each Arduino sketch that uses wolfSSL must have: #include "wolfssl.h" + * C/C++ source files can use: #include + * The wolfSSL "settings.h" must be included in each source file using wolfSSL. + * The wolfSSL "settings.h" must appear before any other wolfSSL include. + */ +#include +/* Important: make sure settings.h appears before any other wolfSSL headers */ +#include +/* Reminder: settings.h includes user_settings.h + * For ALL project wolfSSL settings, see: + * [your path]/Arduino\libraries\wolfSSL\src\user_settings.h */ +#include +#include +#include + +#ifndef WOLFSSL_DTLS + /* Support for DTLS by default was added after wolfSSL v5.8.2 release */ + #error "This example requires WOLFSSL_DTLS. See user_settings.h in the Arduino wolfssl library" +#endif + +/* Define DEBUG_WOLFSSL in user_settings.h for more verbose logging. */ +#if defined(DEBUG_WOLFSSL) + #define PROGRESS_DOT F("") +#else + #define PROGRESS_DOT F(".") +#endif + +/* Convert a macro to a string */ +#define xstr(x) str(x) +#define str(x) #x + +/* optional board-specific networking includes */ +#if defined(ESP32) + #define USING_WIFI + #include + #include + #ifdef USE_NTP_LIB + WiFiUDP ntpUDP; + #endif + /* Ensure the F() flash macro is defined */ + #ifndef F + #define F + #endif + WiFiClient client; + WiFiServer server(WOLFSSL_PORT); +#elif defined(ESP8266) + #define USING_WIFI + #include + /* Ensure the F() flash macro is defined */ + #ifndef F + #define F + #endif + WiFiClient client; + WiFiServer server(WOLFSSL_PORT); +#elif defined(ARDUINO_SAM_DUE) + #include + /* There's no WiFi/Ethernet on the Due. Requires Ethernet Shield. + /* Needs "Ethernet by Various" library to be installed. Tested with V2.0.2 */ + #include + EthernetClient client; + EthernetClient server(WOLFSSL_PORT); +#elif defined(ARDUINO_AVR_ETHERNET) || defined(ARDUINO_AVR_LEONARDO_ETH) + /* Boards such as arduino:avr:ethernet and arduino:avr:leonardoeth */ + #include + EthernetClient client; + + EthernetClient server(WOLFSSL_PORT); +#elif defined(ARDUINO_SAMD_NANO_33_IOT) + #define USING_WIFI + #include + #include /* Needs Arduino WiFiNINA library installed manually */ + WiFiClient client; + WiFiServer server(WOLFSSL_PORT); +#elif defined(ARDUINO_ARCH_RP2040) + #define USING_WIFI + #include + #include + WiFiClient client; + WiFiServer server(WOLFSSL_PORT); +#elif defined(ARDUINO_SAMD_TIAN) + #include + #include + HttpClient client; + /* Arduino Tian does not support network shields like the standard Ethernet or Wi-Fi shields. */ + #error "HttpClient cannot be used for this example" +#elif defined(ARDUINO_PORTENTA_X8) + /* The Portenta is a Linux device. See wolfSSL examples: + * https://github.com/wolfSSL/wolfssl/tree/master/examples + * By default Serial is disabled and mapped to ErrorSerial */ + #include + + /* ----No - network placeholders(compile - only) ---- */ + #include + struct X8NoNetClient { + int write(const uint8_t*, size_t) { return -1; } + int available() { return 0; } + int read() { return -1; } + void stop() {} + bool connected() { return false; } + IPAddress remoteIP() { return IPAddress(0, 0, 0, 0); } + }; + struct X8NoNetServer { + explicit X8NoNetServer(uint16_t) {} + void begin() {} + X8NoNetClient available() { return X8NoNetClient(); } + }; + + X8NoNetClient client; + X8NoNetServer server(WOLFSSL_PORT); +#elif defined(USING_WIFI) + #define USING_WIFI + #include + #include + #ifdef USE_NTP_LIB + WiFiUDP ntpUDP; + #endif + WiFiClient client; + WiFiServer server(WOLFSSL_PORT); +/* TODO +#elif defined(OTHER_BOARD) +*/ +#else + /* assume all other boards using WiFi library. Edit as needed: */ + #include + #define USING_WIFI + WiFiClient client; + WiFiServer server(WOLFSSL_PORT); +#endif + +/* Only for syntax highlighters to show interesting options enabled: */ +#if defined(HAVE_SNI) \ + || defined(HAVE_MAX_FRAGMENT) \ + || defined(HAVE_TRUSTED_CA) \ + || defined(HAVE_TRUNCATED_HMAC) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ + || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) \ + || defined(HAVE_SUPPORTED_CURVES) \ + || defined(HAVE_ALPN) \ + || defined(HAVE_SESSION_TICKET) \ + || defined(HAVE_SECURE_RENEGOTIATION) \ + || defined(HAVE_SERVER_RENEGOTIATION_INFO) +#endif + +static const int port PROGMEM = WOLFSSL_PORT; /* port on server to connect to */ + +static WOLFSSL_CTX* ctx = NULL; +static WOLFSSL* ssl = NULL; +static char* wc_error_message = (char*)malloc(80 + 1); +static char errBuf[80]; + +#if defined(MEMORY_STRESS_TEST) + #define MEMORY_STRESS_ITERATIONS 100 + #define MEMORY_STRESS_BLOCK_SIZE 1024 + #define MEMORY_STRESS_INITIAL (4*1024) + static char* memory_stress[MEMORY_STRESS_ITERATIONS]; /* typically 1K per item */ + static int mem_ctr = 0; +#endif + +static int EthernetSend(WOLFSSL* ssl, char* msg, int sz, void* ctx); +static int EthernetReceive(WOLFSSL* ssl, char* reply, int sz, void* ctx); +static int reconnect = RECONNECT_ATTEMPTS; +#if 0 +/* optional showPeerEx, currently disabled */ +static int lng_index PROGMEM = 0; /* 0 = English */ +#endif +static int listenfd = INVALID_SOCKET; /* Initialize our socket */ + +#if defined(__arm__) + #include + extern char _end; + extern "C" char *sbrk(int i); + static char *ramstart=(char *)0x20070000; + static char *ramend=(char *)0x20088000; +#endif + +/*****************************************************************************/ +/* fail_wait - in case of unrecoverable error */ +/*****************************************************************************/ +int fail_wait(void) { + show_memory(); + + Serial.println(F("Failed. Halt.")); + while (1) { + delay(1000); + } + return 0; +} + +/*****************************************************************************/ +/* show_memory() to optionally view during debugging. */ +/*****************************************************************************/ +int show_memory(void) +{ +#if defined(__arm__) + struct mallinfo mi = mallinfo(); + + char *heapend=sbrk(0); + register char * stack_ptr asm("sp"); + #if defined(DEBUG_WOLFSSL_VERBOSE) + Serial.print(" arena="); + Serial.println(mi.arena); + Serial.print(" ordblks="); + Serial.println(mi.ordblks); + Serial.print(" uordblks="); + Serial.println(mi.uordblks); + Serial.print(" fordblks="); + Serial.println(mi.fordblks); + Serial.print(" keepcost="); + Serial.println(mi.keepcost); + #endif + + #if defined(DEBUG_WOLFSSL) || defined(MEMORY_STRESS_TEST) + Serial.print("Estimated free memory: "); + Serial.print(stack_ptr - heapend + mi.fordblks); + Serial.println(F(" bytes")); + #endif + + #if (0) + /* Experimental: not supported on all devices: */ + Serial.print("RAM Start %lx\n", (unsigned long)ramstart); + Serial.print("Data/Bss end %lx\n", (unsigned long)&_end); + Serial.print("Heap End %lx\n", (unsigned long)heapend); + Serial.print("Stack Ptr %lx\n",(unsigned long)stack_ptr); + Serial.print("RAM End %lx\n", (unsigned long)ramend); + + Serial.print("Heap RAM Used: ",mi.uordblks); + Serial.print("Program RAM Used ",&_end - ramstart); + Serial.print("Stack RAM Used ",ramend - stack_ptr); + + Serial.print("Estimated Free RAM: %d\n\n",stack_ptr - heapend + mi.fordblks); + #endif +#else + Serial.println(F("show_memory() not implemented for this platform")); +#endif + return 0; +} + +/*****************************************************************************/ +/* Arduino setup_hardware() */ +/*****************************************************************************/ +int setup_hardware(void) { + int ret = 0; + +#if defined(ARDUINO_SAMD_NANO_33_IOT) + Serial.println(F("Detected known tested and working Arduino Nano 33 IoT")); +#elif defined(ARDUINO_ARCH_RP2040) + Serial.println(F("Detected known tested and working Arduino RP-2040")); +#elif defined(__arm__) && defined(ID_TRNG) && defined(TRNG) + /* need to manually turn on random number generator on Arduino Due, etc. */ + pmc_enable_periph_clk(ID_TRNG); + trng_enable(TRNG); + Serial.println(F("Enabled ARM TRNG")); +#endif + + show_memory(); + randomSeed(analogRead(0)); + return ret; +} + +/*****************************************************************************/ +/* Arduino setup_datetime() */ +/* The device needs to have a valid date within the valid range of certs. */ +/*****************************************************************************/ +int setup_datetime(void) { + int ret = 0; + int ntp_tries = 20; + + /* we need a date in the range of cert expiration */ +#ifdef USE_NTP_LIB + #if defined(ESP32) + NTPClient timeClient(ntpUDP, "pool.ntp.org"); + + timeClient.begin(); + timeClient.update(); + delay(1000); + while (!timeClient.isTimeSet() && (ntp_tries > 0)) { + timeClient.forceUpdate(); + Serial.println(F("Waiting for NTP update")); + delay(2000); + ntp_tries--; + } + if (ntp_tries <= 0) { + Serial.println(F("Warning: gave up waiting on NTP")); + } + Serial.println(timeClient.getFormattedTime()); + Serial.println(timeClient.getEpochTime()); + #endif +#endif + +#if defined(ESP32) + /* see esp32-hal-time.c */ + ntp_tries = 5; + /* Replace "pool.ntp.org" with your preferred NTP server */ + configTime(0, 0, "pool.ntp.org"); + + /* Wait for time to be set */ + while ((time(nullptr) <= 100000) && ntp_tries > 0) { + Serial.println(F("Waiting for time to be set...")); + delay(2000); + ntp_tries--; + } +#endif + + return ret; +} /* setup_datetime */ + +/*****************************************************************************/ +/* Arduino setup_network() */ +/*****************************************************************************/ +int setup_network(void) { + int ret = 0; + +#if defined(USING_WIFI) + int status = WL_IDLE_STATUS; + + /* The ESP8266 & ESP32 support both AP and STA. We'll use STA: */ + #if defined(ESP8266) || defined(ESP32) + WiFi.mode(WIFI_STA); + #else + String fv; + if (WiFi.status() == WL_NO_MODULE) { + Serial.println("Communication with WiFi module failed!"); + /* don't continue if no network */ + while (true) ; + } + + fv = WiFi.firmwareVersion(); + if (fv < WIFI_FIRMWARE_LATEST_VERSION) { + Serial.println("Please upgrade the firmware"); + } + #endif + + Serial.print(F("Connecting to WiFi ")); + Serial.print(ssid); + status = WiFi.begin(ssid, password); + while (status != WL_CONNECTED) { + delay(1000); + Serial.print(F(".")); + Serial.print(status); + status = WiFi.status(); + } + + Serial.println(F(" Connected!")); +#else + /* Newer Ethernet shields have a + * MAC address printed on a sticker on the shield */ + byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; + IPAddress ip(192, 168, 1, 42); + IPAddress myDns(192, 168, 1, 1); + Ethernet.init(10); /* Most Arduino shields */ + /* Ethernet.init(5); * MKR ETH Shield */ + /* Ethernet.init(0); * Teensy 2.0 */ + /* Ethernet.init(20); * Teensy++ 2.0 */ + /* Ethernet.init(15); * ESP8266 with Adafruit FeatherWing Ethernet */ + /* Ethernet.init(33); * ESP32 with Adafruit FeatherWing Ethernet */ + Serial.println(F("Initialize Ethernet with DHCP:")); + if (Ethernet.begin(mac) == 0) { + Serial.println(F("Failed to configure Ethernet using DHCP")); + /* Check for Ethernet hardware present */ + if (Ethernet.hardwareStatus() == EthernetNoHardware) { + Serial.println(F("Ethernet shield was not found.")); + while (true) { + delay(1); /* do nothing */ + } + } + if (Ethernet.linkStatus() == LinkOFF) { + Serial.println(F("Ethernet cable is not connected.")); + } + /* try to configure using IP address instead of DHCP : */ + Ethernet.begin(mac, ip, myDns); + } + else { + Serial.print(F(" DHCP assigned IP ")); + Serial.println(Ethernet.localIP()); + } + /* We'll assume the Ethernet connection is ready to go. */ +#endif + + Serial.println(F("********************************************************")); + Serial.print(F(" wolfSSL Example Server IP = ")); +#if defined(USING_WIFI) + Serial.println(WiFi.localIP()); +#else + Serial.println(Ethernet.localIP()); +#endif + /* In server mode, there's no host definition. */ + /* See companion example: wolfssl_client.ino */ + Serial.println(F("********************************************************")); + Serial.println(F("Setup network complete.")); + + return ret; +} + +/*****************************************************************************/ +/* Arduino setup_wolfssl() */ +/*****************************************************************************/ +int setup_wolfssl(void) +{ + int ret = 0; + WOLFSSL_METHOD* method; + + /* Show a revision of wolfssl user_settings.h file in use when available: */ +#if defined(WOLFSSL_USER_SETTINGS_ID) + Serial.print(F("WOLFSSL_USER_SETTINGS_ID: ")); + Serial.println(F(WOLFSSL_USER_SETTINGS_ID)); +#else + Serial.println(F("No WOLFSSL_USER_SETTINGS_ID found.")); +#endif + +#if defined(NO_WOLFSSL_SERVER) + Serial.println(F("wolfSSL server code disabled to save space.")); +#endif +#if defined(NO_WOLFSSL_CLIENT) + Serial.println(F("wolfSSL client code disabled to save space.")); +#endif + +#if defined(DEBUG_WOLFSSL) + Serial.println(F("wolfSSL Debugging is available! (DEBUG_WOLFSSL)")); + #if defined(DEBUG_WOLFSSL_MESSAGES_ON) + Serial.println(F("Enabling verbose messages wolfSSL_Debugging_ON")); + wolfSSL_Debugging_ON(); + #else + Serial.println(F("Enable verbose messages with wolfSSL_Debugging_ON")); + Serial.println(F("or define DEBUG_WOLFSSL_MESSAGES_ON")); + #endif +#else + Serial.println(F("wolfSSL Debugging is Off! (enable with DEBUG_WOLFSSL)")); +#endif + + /* See ssl.c for TLS cache settings. Larger cache = use more RAM. */ +#if defined(NO_SESSION_CACHE) + Serial.println(F("wolfSSL TLS NO_SESSION_CACHE")); +#elif defined(MICRO_SESSION_CACHEx) + Serial.println(F("wolfSSL TLS MICRO_SESSION_CACHE")); +#elif defined(SMALL_SESSION_CACHE) + Serial.println(F("wolfSSL TLS SMALL_SESSION_CACHE")); +#elif defined(MEDIUM_SESSION_CACHE) + Serial.println(F("wolfSSL TLS MEDIUM_SESSION_CACHE")); +#elif defined(BIG_SESSION_CACHE) + Serial.println(F("wolfSSL TLS BIG_SESSION_CACHE")); +#elif defined(HUGE_SESSION_CACHE) + Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE")); +#elif defined(HUGE_SESSION_CACHE) + Serial.println(F("wolfSSL TLS HUGE_SESSION_CACHE")); +#else + Serial.println(F("WARNING: Unknown or no TLS session cache setting.")); + /* See wolfssl/src/ssl.c for amount of memory used. + * It is best on embedded devices to choose a TLS session cache size. */ +#endif + + /* Initialize wolfSSL before assigning ctx */ + ret = wolfSSL_Init(); + if (ret == WOLFSSL_SUCCESS) { + Serial.println("Successfully called wolfSSL_Init"); + } + else { + Serial.println("ERROR: wolfSSL_Init failed"); + } + + /* See companion server example with wolfSSLv23_server_method here. + * method = wolfSSLv23_client_method()); SSL 3.0 - TLS 1.3. + * method = wolfTLSv1_2_client_method(); only TLS 1.2 + * method = wolfTLSv1_3_client_method(); only TLS 1.3 + * + * see Arduino\libraries\wolfssl\src\user_settings.h */ + + Serial.println("Here we go!"); + +#ifdef WOLFSSL_DTLS13 + Serial.println(F("Setting wolfDTLSv1_3_client_method")); + method = wolfDTLSv1_3_server_method(); +#else + Serial.println(F("Setting wolfDTLSv1_2_client_method")); + method = wolfDTLSv1_2_servert_method(); +#endif + ctx = wolfSSL_CTX_new(method); + if (ctx == NULL) { + fail_wait(); + } + + if (method == NULL) { + Serial.println(F("Unable to get wolfssl client method")); + fail_wait(); + } + + ctx = wolfSSL_CTX_new(method); + if (ctx == NULL) { + Serial.println(F("unable to get ctx")); + fail_wait(); + } + + return ret; +} + +/*****************************************************************************/ +/* Arduino setup_certificates() */ +/*****************************************************************************/ +int setup_certificates(void) +{ + int ret = 0; + +/* See user_settings.h that should have included wolfssl/certs_test.h */ + +Serial.println(F("Initializing certificates...")); +show_memory(); + + /* Load CA certificates */ + if (ret == WOLFSSL_SUCCESS) { + /* caCertLoc[] = "../certs/ca-cert.pem"; */ + ret = wolfSSL_CTX_load_verify_buffer(ctx, + CTX_CA_CERT, + CTX_CA_CERT_SIZE, + CTX_SERVER_CERT_TYPE); + } + + /* If successful, Load server certificates */ + Serial.println("Initializing certificates..."); + ret = wolfSSL_CTX_use_certificate_buffer(ctx, + CTX_SERVER_CERT, + CTX_SERVER_CERT_SIZE, + CTX_CA_CERT_TYPE); + + if (ret == WOLFSSL_SUCCESS) { + Serial.print("Success: use certificate: "); + Serial.println(xstr(CTX_SERVER_CERT)); + } + else { + Serial.print("Error: wolfSSL_CTX_use_certificate_buffer failed: "); + wc_ErrorString(ret, wc_error_message); + Serial.println(wc_error_message); + fail_wait(); + } + + /* Setup private server key */ + ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, + CTX_SERVER_KEY, + CTX_SERVER_KEY_SIZE, + CTX_SERVER_KEY_TYPE); + if (ret == WOLFSSL_SUCCESS) { + Serial.print("Success: use private key buffer: "); + Serial.println(xstr(CTX_SERVER_KEY)); + } + else { + Serial.print("Error: wolfSSL_CTX_use_PrivateKey_buffer failed: "); + wc_ErrorString(ret, wc_error_message); + Serial.println(wc_error_message); + fail_wait(); + } + + /* Setup private server key */ + ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, + CTX_SERVER_KEY, + CTX_SERVER_KEY_SIZE, + CTX_SERVER_KEY_TYPE); + + if (ret == WOLFSSL_SUCCESS) { + Serial.print("Success: use private key buffer: "); + Serial.println(xstr(CTX_SERVER_KEY)); + } + else { + Serial.print("Error: wolfSSL_CTX_use_PrivateKey_buffer failed: "); + wc_ErrorString(ret, wc_error_message); + Serial.println(wc_error_message); + fail_wait(); + } + + return ret; +} /* Arduino setup */ + +/*****************************************************************************/ +/*****************************************************************************/ +/* Arduino setup() */ +/*****************************************************************************/ +/*****************************************************************************/ +void setup(void) +{ + int i = 0; + Serial.begin(SERIAL_BAUD); + while (!Serial && (i < 10)) { + /* wait for serial port to connect. Needed for native USB port only */ + delay(1000); + i++; + } + + Serial.println(F("")); + Serial.println(F("")); + Serial.println(F("wolfSSL DTLS Server Example Startup.")); + + /* Optionally pre-allocate a large block of memory for testing */ +#if defined(MEMORY_STRESS_TEST) + Serial.println(F("WARNING: Memory Stress Test Active!")); + Serial.print(F("Allocating extra memory: ")); + Serial.print(MEMORY_STRESS_INITIAL); + Serial.println(F(" bytes...")); + memory_stress[mem_ctr] = (char*)malloc(MEMORY_STRESS_INITIAL); + show_memory(); +#endif + + setup_hardware(); + + setup_network(); + + setup_datetime(); + + setup_wolfssl(); + + setup_certificates(); + +#if defined THIS_USER_SETTINGS_VERSION + Serial.print(F("This user_settings.h version:")) + Serial.println(THIS_USER_SETTINGS_VERSION) +#endif + + /* Start the server + * See https://www.arduino.cc/reference/en/libraries/ethernet/server.begin/ + */ + + Serial.println(F("Completed Arduino setup()")); + + server.begin(); + Serial.println("Begin Server... (waiting for remote client to connect)"); + + /* See companion wolfssl_client.ino code */ + return; +} /* Arduino setup */ + +/*****************************************************************************/ +/* wolfSSL error_check() */ +/*****************************************************************************/ +int error_check(int this_ret, bool halt_on_error, + const __FlashStringHelper* message) { + int ret = 0; + if (this_ret == WOLFSSL_SUCCESS) { + Serial.print(F("Success: ")); + Serial.println(message); + } + else { + Serial.print(F("ERROR: return = ")); + Serial.print(this_ret); + Serial.print(F(": ")); + Serial.println(message); + Serial.println(wc_GetErrorString(this_ret)); + if (halt_on_error) { + fail_wait(); + } + } + show_memory(); + + return ret; +} /* error_check */ + +/*****************************************************************************/ +/* wolfSSL error_check_ssl */ +/* Parameters: */ +/* ssl is the current WOLFSSL object pointer */ +/* halt_on_error set to true to suspend operations for critical error */ +/* message is expected to be a memory-efficient F("") macro string */ +/*****************************************************************************/ +int error_check_ssl(WOLFSSL* ssl, int this_ret, bool halt_on_error, + const __FlashStringHelper* message) { + int err = 0; + + if (ssl == NULL) { + Serial.println(F("ssl is Null; Unable to allocate SSL object?")); +#ifndef DEBUG_WOLFSSL + Serial.println(F("Define DEBUG_WOLFSSL in user_settings.h for more.")); +#else + Serial.println(F("See wolfssl/wolfcrypt/error-crypt.h for codes.")); +#endif + Serial.print(F("ERROR: ")); + Serial.println(message); + show_memory(); + if (halt_on_error) { + fail_wait(); + } + } + else { + err = wolfSSL_get_error(ssl, this_ret); + if (err == WOLFSSL_SUCCESS) { + Serial.print(F("Success m: ")); + Serial.println(message); + } + else { + if (err < 0) { + wolfSSL_ERR_error_string(err, errBuf); + Serial.print(F("WOLFSSL Error: ")); + Serial.print(err); + Serial.print(F("; ")); + Serial.println(errBuf); + } + else { + Serial.println(F("Success: ssl object.")); + } + } + } + + return err; +} /* error_check_ssl */ + +static void sig_handler(const int sig); +static void free_resources(void); + +/*****************************************************************************/ +/*****************************************************************************/ +/* Arduino loop() */ +/*****************************************************************************/ +/*****************************************************************************/ +void loop() +{ + int exitVal = 1; + struct sockaddr_in servAddr; /* our server's address */ + struct sockaddr_in cliaddr; /* the client's address */ + int ret; + int err; + int recvLen = 0; /* length of message */ + socklen_t cliLen; + char buff[MAXLINE]; /* the incoming message */ + char ack[] = "I hear you fashizzle!\n"; + + /* Initialize wolfSSL before assigning ctx */ + if (wolfSSL_Init() != WOLFSSL_SUCCESS) { + fprintf(stderr, "wolfSSL_Init error.\n"); + fail_wait(); + } + + /* No-op when debugging is not compiled in */ + wolfSSL_Debugging_ON(); + + + /* Create a UDP/IP socket */ + if ((listenfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { + perror("socket()"); + goto cleanup; + } + printf("Socket allocated\n"); + memset((char *)&servAddr, 0, sizeof(servAddr)); + /* host-to-network-long conversion (htonl) */ + /* host-to-network-short conversion (htons) */ + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = htonl(INADDR_ANY); + servAddr.sin_port = htons(WOLFSSL_PORT); + + /* Bind Socket */ + if (bind(listenfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) < 0) { + perror("bind()"); + goto cleanup; + } + + // signal(SIGINT, sig_handler); + + while (1) { + printf("Awaiting client connection on port %d\n", WOLFSSL_PORT); + + cliLen = sizeof(cliaddr); + ret = (int)recvfrom(listenfd, (char *)&buff, sizeof(buff), MSG_PEEK, + (struct sockaddr*)&cliaddr, &cliLen); + + if (ret < 0) { + perror("recvfrom()"); + goto cleanup; + } + else if (ret == 0) { + fprintf(stderr, "recvfrom zero return\n"); + goto cleanup; + } + + /* Create the WOLFSSL Object */ + if ((ssl = wolfSSL_new(ctx)) == NULL) { + fprintf(stderr, "wolfSSL_new error.\n"); + goto cleanup; + } + + if (wolfSSL_dtls_set_peer(ssl, &cliaddr, cliLen) != WOLFSSL_SUCCESS) { + fprintf(stderr, "wolfSSL_dtls_set_peer error.\n"); + goto cleanup; + } + + if (wolfSSL_set_fd(ssl, listenfd) != WOLFSSL_SUCCESS) { + fprintf(stderr, "wolfSSL_set_fd error.\n"); + break; + } + + if (wolfSSL_accept(ssl) != WOLFSSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); + fprintf(stderr, "error = %d, %s\n", err, + wolfSSL_ERR_reason_error_string(err)); + fprintf(stderr, "SSL_accept failed.\n"); + goto cleanup; + } + + while (1) { + if ((recvLen = wolfSSL_read(ssl, buff, sizeof(buff)-1)) > 0) { + printf("heard %d bytes\n", recvLen); + + buff[recvLen] = '\0'; + printf("I heard this: \"%s\"\n", buff); + } + else if (recvLen <= 0) { + err = wolfSSL_get_error(ssl, 0); + if (err == WOLFSSL_ERROR_ZERO_RETURN) /* Received shutdown */ + break; + fprintf(stderr, "error = %d, %s\n", err, + wolfSSL_ERR_reason_error_string(err)); + fprintf(stderr, "SSL_read failed.\n"); + goto cleanup; + } + printf("Sending reply.\n"); + if (wolfSSL_write(ssl, ack, sizeof(ack)) < 0) { + err = wolfSSL_get_error(ssl, 0); + fprintf(stderr, "error = %d, %s\n", err, + wolfSSL_ERR_reason_error_string(err)); + fprintf(stderr, "wolfSSL_write failed.\n"); + goto cleanup; + } + } + + printf("reply sent \"%s\"\n", ack); + + /* Attempt a full shutdown */ + ret = wolfSSL_shutdown(ssl); + if (ret == WOLFSSL_SHUTDOWN_NOT_DONE) + ret = wolfSSL_shutdown(ssl); + if (ret != WOLFSSL_SUCCESS) { + err = wolfSSL_get_error(ssl, 0); + fprintf(stderr, "err = %d, %s\n", err, + wolfSSL_ERR_reason_error_string(err)); + fprintf(stderr, "wolfSSL_shutdown failed\n"); + } + wolfSSL_free(ssl); + ssl = NULL; + + printf("Awaiting new connection\n"); + } + + exitVal = 0; +cleanup: + free_resources(); + wolfSSL_Cleanup(); + + Serial.println(F("Done!")); + while (1) { + delay(1000); + } +} + + +static void sig_handler(const int sig) +{ + (void)sig; + free_resources(); + wolfSSL_Cleanup(); +} + +static void free_resources(void) +{ + if (ssl != NULL) { + wolfSSL_shutdown(ssl); + wolfSSL_free(ssl); + ssl = NULL; + } + if (ctx != NULL) { + wolfSSL_CTX_free(ctx); + ctx = NULL; + } + if (listenfd != INVALID_SOCKET) { + close(listenfd); + listenfd = INVALID_SOCKET; + } +} + diff --git a/examples/wolfssl_version/wolfssl_version.ino b/examples/wolfssl_version/wolfssl_version.ino index 12be948..ac34124 100644 --- a/examples/wolfssl_version/wolfssl_version.ino +++ b/examples/wolfssl_version/wolfssl_version.ino @@ -6,7 +6,7 @@ * * wolfSSL is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * wolfSSL is distributed in the hope that it will be useful, @@ -21,6 +21,13 @@ #include +#if defined(ARDUINO_PORTENTA_X8) + /* The Portenta is a Linux device. See wolfSSL examples: + * https://github.com/wolfSSL/wolfssl/tree/master/examples + * By default Serial is disabled and mapped to ErrorSerial */ + #include +#endif + /* wolfSSL user_settings.h must be included from settings.h * Make all configurations changes in user_settings.h * Do not edit wolfSSL `settings.h` or `config.h` files. diff --git a/library.properties b/library.properties index bb59f54..05d11ef 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=wolfssl -version=5.8.2 +version=5.8.4 author=wolfSSL Inc. maintainer=wolfSSL inc sentence=A lightweight SSL/TLS library written in ANSI C and targeted for embedded, RTOS, and resource-constrained environments. diff --git a/src/src/bio.c b/src/src/bio.c index ce74983..8321dab 100644 --- a/src/src/bio.c +++ b/src/src/bio.c @@ -1404,7 +1404,7 @@ long wolfSSL_BIO_get_mem_ptr(WOLFSSL_BIO *bio, WOLFSSL_BUF_MEM **ptr) } #endif -WOLFSSL_API long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int iarg) +long wolfSSL_BIO_int_ctrl(WOLFSSL_BIO *bp, int cmd, long larg, int iarg) { (void) bp; (void) cmd; @@ -2440,9 +2440,21 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) { WOLFSSL_BIO *bio; WOLFSSL_ENTER("wolfSSL_BIO_new_accept"); + + if (port == NULL) { + return NULL; + } + bio = wolfSSL_BIO_new(wolfSSL_BIO_s_socket()); if (bio) { - bio->port = (word16)XATOI(port); + const char* portStr = port; +#ifdef WOLFSSL_IPV6 + const char* ipv6End = XSTRSTR(port, "]"); + if (ipv6End) { + portStr = XSTRSTR(ipv6End, ":"); + } +#endif + bio->port = (word16)XATOI(portStr); bio->type = WOLFSSL_BIO_SOCKET; } return bio; @@ -3327,7 +3339,7 @@ int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args) /* In Visual Studio versions prior to Visual Studio 2013, the va_* symbols aren't defined. If using Visual Studio 2013 or later, define HAVE_VA_COPY. */ - #if !defined(_WIN32) || defined(HAVE_VA_COPY) + #if defined(XVSNPRINTF) && (!defined(_WIN32) || defined(HAVE_VA_COPY)) case WOLFSSL_BIO_SSL: { int count; @@ -3358,7 +3370,7 @@ int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args) va_end(copy); } break; - #endif /* !_WIN32 || HAVE_VA_COPY */ + #endif /* XVSNPRINTF && (!_WIN32 || HAVE_VA_COPY) */ default: WOLFSSL_MSG("Unsupported WOLFSSL_BIO type for wolfSSL_BIO_printf"); diff --git a/src/src/crl.c b/src/src/crl.c index 4e4700f..9056bd1 100644 --- a/src/src/crl.c +++ b/src/src/crl.c @@ -39,8 +39,9 @@ CRL Options: #include #include +#include -#ifndef WOLFSSL_LINUXKM +#ifndef NO_STRING_H #include #endif @@ -209,20 +210,23 @@ static CRL_Entry* CRL_Entry_new(void* heap) /* Free all CRL Entry resources */ static void CRL_Entry_free(CRL_Entry* crle, void* heap) { -#ifdef CRL_STATIC_REVOKED_LIST - if (crle != NULL) { - XMEMSET(crle->certs, 0, CRL_MAX_REVOKED_CERTS*sizeof(RevokedCert)); + WOLFSSL_ENTER("CRL_Entry_free"); + if (crle == NULL) { + WOLFSSL_MSG("CRL Entry is null"); + return; } +#ifdef CRL_STATIC_REVOKED_LIST + XMEMSET(crle->certs, 0, CRL_MAX_REVOKED_CERTS*sizeof(RevokedCert)); #else - RevokedCert* tmp = crle->certs; - RevokedCert* next; + { + RevokedCert* tmp; + RevokedCert* next; - WOLFSSL_ENTER("FreeCRL_Entry"); + for (tmp = crle->certs; tmp != NULL; tmp = next) { + next = tmp->next; + XFREE(tmp, heap, DYNAMIC_TYPE_REVOKED); + } - while (tmp != NULL) { - next = tmp->next; - XFREE(tmp, heap, DYNAMIC_TYPE_REVOKED); - tmp = next; } #endif XFREE(crle->signature, heap, DYNAMIC_TYPE_CRL_ENTRY); @@ -753,11 +757,7 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type, int ret = WOLFSSL_SUCCESS; const byte* myBuffer = buff; /* if DER ok, otherwise switch */ DerBuffer* der = NULL; -#ifdef WOLFSSL_SMALL_STACK - DecodedCRL* dcrl; -#else - DecodedCRL dcrl[1]; -#endif + WC_DECLARE_VAR(dcrl, DecodedCRL, 1, 0); WOLFSSL_ENTER("BufferLoadCRL"); @@ -791,10 +791,8 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type, crl->currentEntry = CRL_Entry_new(crl->heap); if (crl->currentEntry == NULL) { - WOLFSSL_MSG("alloc CRL Entry failed"); - #ifdef WOLFSSL_SMALL_STACK - XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif + WOLFSSL_MSG_CERT_LOG("alloc CRL Entry failed"); + WC_FREE_VAR_EX(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER); FreeDer(&der); return MEMORY_E; } @@ -802,9 +800,11 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type, InitDecodedCRL(dcrl, crl->heap); ret = ParseCRL(crl->currentEntry->certs, dcrl, myBuffer, (word32)sz, verify, crl->cm); + if (ret != 0 && !(ret == WC_NO_ERR_TRACE(ASN_CRL_NO_SIGNER_E) && verify == NO_VERIFY)) { - WOLFSSL_MSG("ParseCRL error"); + WOLFSSL_MSG_CERT_LOG("ParseCRL error"); + WOLFSSL_MSG_CERT_EX("ParseCRL verify = %d, ret = %d", verify, ret); CRL_Entry_free(crl->currentEntry, crl->heap); crl->currentEntry = NULL; } @@ -812,16 +812,14 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type, ret = AddCRL(crl, dcrl, myBuffer, ret != WC_NO_ERR_TRACE(ASN_CRL_NO_SIGNER_E)); if (ret != 0) { - WOLFSSL_MSG("AddCRL error"); + WOLFSSL_MSG_CERT_LOG("AddCRL error"); crl->currentEntry = NULL; } } FreeDecodedCRL(dcrl); -#ifdef WOLFSSL_SMALL_STACK - XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + WC_FREE_VAR_EX(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER); FreeDer(&der); @@ -837,11 +835,7 @@ int GetCRLInfo(WOLFSSL_CRL* crl, CrlInfo* info, const byte* buff, const byte* myBuffer = buff; /* if DER ok, otherwise switch */ DerBuffer* der = NULL; CRL_Entry* crle = NULL; -#ifdef WOLFSSL_SMALL_STACK - DecodedCRL* dcrl; -#else - DecodedCRL dcrl[1]; -#endif + WC_DECLARE_VAR(dcrl, DecodedCRL, 1, 0); WOLFSSL_ENTER("GetCRLInfo"); @@ -877,9 +871,7 @@ int GetCRLInfo(WOLFSSL_CRL* crl, CrlInfo* info, const byte* buff, crle = CRL_Entry_new(crl->heap); if (crle == NULL) { WOLFSSL_MSG("alloc CRL Entry failed"); - #ifdef WOLFSSL_SMALL_STACK - XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif + WC_FREE_VAR_EX(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER); FreeDer(&der); return MEMORY_E; } @@ -898,9 +890,7 @@ int GetCRLInfo(WOLFSSL_CRL* crl, CrlInfo* info, const byte* buff, FreeDecodedCRL(dcrl); -#ifdef WOLFSSL_SMALL_STACK - XFREE(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + WC_FREE_VAR_EX(dcrl, NULL, DYNAMIC_TYPE_TMP_BUFFER); FreeDer(&der); CRL_Entry_free(crle, crl->heap); @@ -1248,23 +1238,14 @@ static int SwapLists(WOLFSSL_CRL* crl) { int ret; CRL_Entry* newList; -#ifdef WOLFSSL_SMALL_STACK - WOLFSSL_CRL* tmp; -#else - WOLFSSL_CRL tmp[1]; -#endif + WC_DECLARE_VAR(tmp, WOLFSSL_CRL, 1, 0); -#ifdef WOLFSSL_SMALL_STACK - tmp = (WOLFSSL_CRL*)XMALLOC(sizeof(WOLFSSL_CRL), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (tmp == NULL) - return MEMORY_E; -#endif + WC_ALLOC_VAR_EX(tmp, WOLFSSL_CRL, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER, + return MEMORY_E); if (InitCRL(tmp, crl->cm) < 0) { WOLFSSL_MSG("Init tmp CRL failed"); -#ifdef WOLFSSL_SMALL_STACK - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); return WOLFSSL_FATAL_ERROR; } @@ -1273,9 +1254,7 @@ static int SwapLists(WOLFSSL_CRL* crl) if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("PEM LoadCRL on dir change failed"); FreeCRL(tmp, 0); -#ifdef WOLFSSL_SMALL_STACK - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); return WOLFSSL_FATAL_ERROR; } } @@ -1285,9 +1264,7 @@ static int SwapLists(WOLFSSL_CRL* crl) if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("DER LoadCRL on dir change failed"); FreeCRL(tmp, 0); -#ifdef WOLFSSL_SMALL_STACK - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); return WOLFSSL_FATAL_ERROR; } } @@ -1295,9 +1272,7 @@ static int SwapLists(WOLFSSL_CRL* crl) if (wc_LockRwLock_Wr(&crl->crlLock) != 0) { WOLFSSL_MSG("wc_LockRwLock_Wr failed"); FreeCRL(tmp, 0); -#ifdef WOLFSSL_SMALL_STACK - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); return WOLFSSL_FATAL_ERROR; } @@ -1311,9 +1286,7 @@ static int SwapLists(WOLFSSL_CRL* crl) FreeCRL(tmp, 0); -#ifdef WOLFSSL_SMALL_STACK - XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + WC_FREE_VAR_EX(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); return 0; } @@ -1499,11 +1472,7 @@ static THREAD_RETURN WOLFSSL_THREAD DoMonitor(void* arg) int notifyFd; int wd = -1; WOLFSSL_CRL* crl = (WOLFSSL_CRL*)arg; -#ifdef WOLFSSL_SMALL_STACK - char* buff; -#else - char buff[8192]; -#endif + WC_DECLARE_VAR(buff, char, 8192, 0); WOLFSSL_ENTER("DoMonitor"); @@ -1608,9 +1577,7 @@ static THREAD_RETURN WOLFSSL_THREAD DoMonitor(void* arg) } } -#ifdef WOLFSSL_SMALL_STACK - XFREE(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + WC_FREE_VAR_EX(buff, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (wd > 0) { if (inotify_rm_watch(notifyFd, wd) < 0) @@ -1636,7 +1603,7 @@ static int StopMonitor(wolfSSL_CRL_mfd_t mfd) #ifdef DEBUG_WOLFSSL #define SHOW_WINDOWS_ERROR() do { \ - LPVOID lpMsgBuf; \ + LPVOID lpMsgBuf = NULL; \ DWORD dw = GetLastError(); \ FormatMessageA( \ FORMAT_MESSAGE_ALLOCATE_BUFFER | \ @@ -1820,22 +1787,14 @@ int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor) { int ret = WOLFSSL_SUCCESS; char* name = NULL; -#ifdef WOLFSSL_SMALL_STACK - ReadDirCtx* readCtx = NULL; -#else - ReadDirCtx readCtx[1]; -#endif + WC_DECLARE_VAR(readCtx, ReadDirCtx, 1, 0); WOLFSSL_ENTER("LoadCRL"); if (crl == NULL) return BAD_FUNC_ARG; -#ifdef WOLFSSL_SMALL_STACK - readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), crl->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (readCtx == NULL) - return MEMORY_E; -#endif + WC_ALLOC_VAR_EX(readCtx, ReadDirCtx, 1, crl->heap, + DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E); /* try to load each regular file in path */ ret = wc_ReadDirFirst(readCtx, path, &name); @@ -1867,9 +1826,7 @@ int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor) if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("CRL file load failed"); wc_ReadDirClose(readCtx); - #ifdef WOLFSSL_SMALL_STACK - XFREE(readCtx, crl->heap, DYNAMIC_TYPE_TMP_BUFFER); - #endif + WC_FREE_VAR_EX(readCtx, crl->heap, DYNAMIC_TYPE_TMP_BUFFER); return ret; } } @@ -1882,9 +1839,7 @@ int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor) /* load failures not reported, for backwards compat */ ret = WOLFSSL_SUCCESS; -#ifdef WOLFSSL_SMALL_STACK - XFREE(readCtx, crl->heap, DYNAMIC_TYPE_TMP_BUFFER); -#endif + WC_FREE_VAR_EX(readCtx, crl->heap, DYNAMIC_TYPE_TMP_BUFFER); if (monitor & WOLFSSL_CRL_MONITOR) { #ifdef HAVE_CRL_MONITOR diff --git a/src/src/dtls.c b/src/src/dtls.c index d25f66b..dff1ffa 100644 --- a/src/src/dtls.c +++ b/src/src/dtls.c @@ -732,8 +732,13 @@ static int SendStatelessReplyDtls13(const WOLFSSL* ssl, WolfSSL_CH* ch) /* Ask the user for the ciphersuite matching this identity */ if (TLSX_PreSharedKey_Parse_ClientHello(&parsedExts, - tlsx.elements, (word16)tlsx.size, ssl->heap) == 0) + tlsx.elements, (word16)tlsx.size, ssl->heap) == 0) { + /* suites only needs to be refined when searching for a PSK. + * MatchSuite_ex handles refining internally. */ + refineSuites(WOLFSSL_SUITES(ssl), &suites, &suites, + ssl->options.useClientOrder); FindPskSuiteFromExt(ssl, parsedExts, &pskInfo, &suites); + } /* Revert to full handshake if PSK parsing failed */ if (pskInfo.isValid) { @@ -753,8 +758,9 @@ static int SendStatelessReplyDtls13(const WOLFSSL* ssl, WolfSSL_CH* ch) ERROR_OUT(PSK_KEY_ERROR, dtls13_cleanup); doKE = 1; } - else if ((modes & (1 << PSK_KE)) == 0) { - ERROR_OUT(PSK_KEY_ERROR, dtls13_cleanup); + else if ((modes & (1 << PSK_KE)) == 0 || + ssl->options.onlyPskDheKe) { + ERROR_OUT(PSK_KEY_ERROR, dtls13_cleanup); } usePSK = 1; } diff --git a/src/src/dtls13.c b/src/src/dtls13.c index c4e2b61..9c729fa 100644 --- a/src/src/dtls13.c +++ b/src/src/dtls13.c @@ -255,7 +255,7 @@ static int Dtls13GetRnMask(WOLFSSL* ssl, const byte* ciphertext, byte* mask, return BAD_STATE_E; #if !defined(HAVE_SELFTEST) && \ (!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)) \ - || defined(WOLFSSL_LINUXKM)) + || defined(WOLFSSL_KERNEL_MODE)) return wc_AesEncryptDirect(c->aes, mask, ciphertext); #else wc_AesEncryptDirect(c->aes, mask, ciphertext); @@ -1898,11 +1898,11 @@ static int _Dtls13HandshakeRecv(WOLFSSL* ssl, byte* input, word32 size, ret = DoTls13HandShakeMsgType(ssl, input, &idx, handshakeType, messageLength, size); + *processedSize = idx; if (ret != 0) return ret; Dtls13MsgWasProcessed(ssl, (enum HandShakeType)handshakeType); - *processedSize = idx; /* check if we have buffered some message */ if (Dtls13NextMessageComplete(ssl)) diff --git a/src/src/internal.c b/src/src/internal.c index c74bcf3..30c27fb 100644 --- a/src/src/internal.c +++ b/src/src/internal.c @@ -293,12 +293,32 @@ int wolfssl_priv_der_blind(WC_RNG* rng, DerBuffer* key, DerBuffer** mask) return ret; } -void wolfssl_priv_der_unblind(DerBuffer* key, DerBuffer* mask) +void wolfssl_priv_der_blind_toggle(DerBuffer* key, const DerBuffer* mask) { - if (key != NULL) { + if ((key != NULL) && (mask != NULL)) { xorbuf(key->buffer, mask->buffer, mask->length); } } + +DerBuffer *wolfssl_priv_der_unblind(const DerBuffer* key, const DerBuffer* mask) +{ + DerBuffer *ret; + if ((key == NULL) || (mask == NULL)) + return NULL; + if (mask->length > key->length) + return NULL; + if (AllocDer(&ret, key->length, key->type, key->heap) != 0) + return NULL; + xorbufout(ret->buffer, key->buffer, mask->buffer, mask->length); + return ret; +} + +void wolfssl_priv_der_unblind_free(DerBuffer* key) +{ + if (key != NULL) + FreeDer(&key); +} + #endif /* !NO_CERT && WOLFSSL_BLIND_PRIVATE_KEY */ @@ -315,69 +335,47 @@ void wolfssl_priv_der_unblind(DerBuffer* key, DerBuffer* mask) const unsigned char* secret, int secretSz, void* ctx); #endif - - /* Label string for client random. */ - #define SSC_CR "CLIENT_RANDOM" - /* * This function builds up string for key-logging then call user's - * key-log-callback to pass the string for TLS1.2 and older. + * key-log-callback to pass the string. * The user's key-logging callback has been set via * wolfSSL_CTX_set_keylog_callback function. The logging string format is: - * "CLIENT_RANDOM " + * "