diff --git a/ChangeLog.md b/ChangeLog.md index 0b32346..a9cdff9 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,3 +1,213 @@ +# wolfSSL Release 5.8.0 (Apr 24, 2025) + +Release 5.8.0 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 + +PR stands for Pull Request, and PR references a GitHub pull request + number where the code change was added. + + +## New Feature Additions +* Algorithm registration in the Linux kernel module for all supported FIPS AES, + SHA, HMAC, ECDSA, ECDH, and RSA modes, key sizes, and digest sizes. +* Implemented various fixes to support building for Open Watcom including OS/2 + support and Open Watcom 1.9 compatibility (PR 8505, 8484) +* Added support for STM32H7S (tested on NUCLEO-H7S3L8) (PR 8488) +* Added support for STM32WBA (PR 8550) +* Added Extended Master Secret Generation Callback to the --enable-pkcallbacks + build (PR 8303) +* Implement AES-CTS (configure flag --enable-aescts) in wolfCrypt (PR 8594) +* Added support for libimobiledevice commit 860ffb (PR 8373) +* Initial ASCON hash256 and AEAD128 support based on NIST SP 800-232 IPD + (PR 8307) +* Added blinding option when using a Curve25519 private key by defining the + macro WOLFSSL_CURVE25519_BLINDING (PR 8392) + + +## Linux Kernel Module +* Production-ready LKCAPI registration for cbc(aes), cfb(aes), gcm(aes), + rfc4106 (gcm(aes)), ctr(aes), ofb(aes), and ecb(aes), ECDSA with P192, P256, + P384, and P521 curves, ECDH with P192, P256, and P384 curves, and RSA with + bare and PKCS1 padding +* Various fixes for LKCAPI wrapper for AES-CBC and AES-CFB (PR 8534, 8552) +* Adds support for the legacy one-shot AES-GCM back end (PR 8614, 8567) for + compatibility with FIPS 140-3 Cert #4718. +* On kernel >=6.8, for CONFIG_FORTIFY_SOURCE, use 5-arg fortify_panic() override + macro (PR 8654) +* Update calls to scatterwalk_map() and scatterwalk_unmap() for linux commit + 7450ebd29c (merged for Linux 6.15) (PR 8667) +* Inhibit LINUXKM_LKCAPI_REGISTER_ECDH on kernel <5.13 (PR 8673) +* Fix for uninitialized build error with fedora (PR 8569) +* Register ecdsa, ecdh, and rsa for use with linux kernel crypto (PR 8637, 8663, + 8646) +* Added force zero shared secret buffer, and clear of old key with ecdh + (PR 8685) +* Update fips-check.sh script to pickup XTS streaming support on aarch64 and + disable XTS-384 as an allowed use in FIPS mode (PR 8509, 8546) + + +## Enhancements and Optimizations + +### Security & Cryptography +* Add constant-time implementation improvements for encoding functions. We thank + Zhiyuan and Gilles for sharing a new constant-time analysis tool (CT-LLVM) and + reporting several non-constant-time implementations. (PR 8396, 8617) +* Additional support for PKCS7 verify and decode with indefinite lengths + (PR 8520, 834, 8645) +* Add more PQC hybrid key exchange algorithms such as support for combinations + with X25519 and X448 enabling compatibility with the PQC key exchange support + in Chromium browsers and Mozilla Firefox (PR 7821) +* Add short-circuit comparisons to DH key validation for RFC 7919 parameters + (PR 8335) +* Improve FIPS compatibility with various build configurations for more resource + constrained builds (PR 8370) +* Added option to disable ECC public key order checking (PR 8581) +* Allow critical alt and basic constraints extensions (PR 8542) +* New codepoint for MLDSA to help with interoperability (PR 8393) +* Add support for parsing trusted PEM certs having the header + “BEGIN_TRUSTED_CERT” (PR 8400) +* Add support for parsing only of DoD certificate policy and Comodo Ltd PKI OIDs + (PR 8599, 8686) +* Update ssl code in `src/*.c` to be consistent with wolfcrypt/src/asn.c + handling of ML_DSA vs Dilithium and add dual alg. test (PR 8360, 8425) + +### Build System, Configuration, CI & Protocols +* Internal refactor for include of config.h and when building with + BUILDING_WOLFSSL macro. This refactor will give a warning of “deprecated + function” when trying to improperly use an internal API of wolfSSL in an + external application. (PR 8640, 8647, 8660, 8662, 8664) +* Add WOLFSSL_CLU option to CMakeLists.txt (PR 8548) +* Add CMake and Zephyr support for XMSS and LMS (PR 8494) +* Added GitHub CI for CMake builds (PR 8439) +* Added necessary macros when building wolfTPM Zephyr with wolfSSL (PR 8382) +* Add MSYS2 build continuous integration test (PR 8504) +* Update DevKitPro doc to list calico dependency with build commands (PR 8607) +* Conversion compiler warning fixes and additional continuous integration test + added (PR 8538) +* Enable DTLS 1.3 by default in --enable-jni builds (PR 8481) +* Enabled TLS 1.3 middlebox compatibility by default for --enable-jni builds + (PR 8526) + +### Performance Improvements +* Performance improvements AES-GCM and HMAC (in/out hash copy) (PR 8429) +* LMS fixes and improvements adding API to get Key ID from raw private key, + change to identifiers to match standard, and fix for when + WOLFSSL_LMS_MAX_LEVELS is 1 (PR 8390, 8684, 8613, 8623) +* ML-KEM/Kyber improvements and fixes; no malloc builds, small memory usage, + performance improvement, fix for big-endian (PR 8397, 8412, 8436, 8467, 8619, + 8622, 8588) +* Performance improvements for AES-GCM and when doing multiple HMAC operations + (PR 8445) + +### Assembly and Platform-Specific Enhancements +* Poly1305 arm assembly changes adding ARM32 NEON implementation and fix for + Aarch64 use (PR 8344, 8561, 8671) +* Aarch64 assembly enhancement to use more CPU features, fix for FreeBSD/OpenBSD + (PR 8325, 8348) +* Only perform ARM assembly CPUID checks if support was enabled at build time + (PR 8566) +* Optimizations for ARM32 assembly instructions on platforms less than ARMv7 + (PR 8395) +* Improve MSVC feature detection for static assert macros (PR 8440) +* Improve Espressif make and CMake for ESP8266 and ESP32 series (PR 8402) +* Espressif updates for Kconfig, ESP32P4 and adding a sample user_settings.h + (PR 8422, PR 8641) + +### OpenSSL Compatibility Layer +* Modification to the push/pop to/from in OpenSSL compatibility layer. This is + a pretty major API change in the OpenSSL compatibility stack functions. + Previously the API would push/pop from the beginning of the list but now they + operate on the tail of the list. This matters when using the sk_value with + index values. (PR 8616) +* OpenSSL Compat Layer: OCSP response improvements (PR 8408, 8498) +* Expand the OpenSSL compatibility layer to include an implementation of + BN_CTX_get (PR 8388) + +### API Additions and Modifications +* Refactor Hpke to allow multiple uses of a context instead of just one shot + mode (PR 6805) +* Add support for PSK client callback with Ada and use with Alire (thanks + @mgrojo, PR 8332, 8606) +* Change wolfSSL_CTX_GenerateEchConfig to generate multiple configs and add + functions wolfSSL_CTX_SetEchConfigs and wolfSSL_CTX_SetEchConfigsBase64 to + rotate the server's echConfigs (PR 8556) +* Added the public API wc_PkcsPad to do PKCS padding (PR 8502) +* Add NULL_CIPHER_TYPE support to wolfSSL_EVP_CipherUpdate (PR 8518) +* Update Kyber APIs to ML-KEM APIs (PR 8536) +* Add option to disallow automatic use of "default" devId using the macro + WC_NO_DEFAULT_DEVID (PR 8555) +* Detect unknown key format on ProcessBufferTryDecode() and handle RSA-PSSk + format (PR 8630) + +### Porting and Language Support +* Update Python port to support version 3.12.6 (PR 8345) +* New additions for MAXQ with wolfPKCS11 (PR 8343) +* Port to ntp 4.2.8p17 additions (PR 8324) +* Add version 0.9.14 to tested libvncserver builds (PR 8337) + +### General Improvements and Cleanups +* Cleanups for STM32 AES GCM (PR 8584) +* Improvements to isascii() and the CMake key log option (PR 8596) +* Arduino documentation updates, comments and spelling corrections (PR 8381, + 8384, 8514) +* Expanding builds with WOLFSSL_NO_REALLOC for use with --enable-opensslall and + --enable-all builds (PR 8369, 8371) + + +## Fixes +* Fix a use after free caused by an early free on error in the X509 store + (PR 8449) +* Fix to account for existing PKCS8 header with + wolfSSL_PEM_write_PKCS8PrivateKey (PR 8612) +* Fixed failing CMake build issue when standard threads support is not found in + the system (PR 8485) +* Fix segmentation fault in SHA-512 implementation for AVX512 targets built with + gcc -march=native -O2 (PR 8329) +* Fix Windows socket API compatibility warning with mingw32 build (PR 8424) +* Fix potential null pointer increments in cipher list parsing (PR 8420) +* Fix for possible stack buffer overflow read with wolfSSL_SMIME_write_PKCS7. + Thanks to the team at Code Intelligence for the report. (PR 8466) +* Fix AES ECB implementation for Aarch64 ARM assembly (PR 8379) +* Fixed building with VS2008 and .NET 3.5 (PR 8621) +* Fixed possible error case memory leaks in CRL and EVP_Sign_Final (PR 8447) +* Fixed SSL_set_mtu compatibility function return code (PR 8330) +* Fixed Renesas RX TSIP (PR 8595) +* Fixed ECC non-blocking tests (PR 8533) +* Fixed CMake on MINGW and MSYS (PR 8377) +* Fixed Watcom compiler and added new CI test (PR 8391) +* Fixed STM32 PKA ECC 521-bit support (PR 8450) +* Fixed STM32 PKA with P521 and shared secret (PR 8601) +* Fixed crypto callback macro guards with `DEBUG_CRYPTOCB` (PR 8602) +* Fix outlen return for RSA private decrypt with WOLF_CRYPTO_CB_RSA_PAD + (PR 8575) +* Additional sanity check on r and s lengths in DecodeECC_DSA_Sig_Bin (PR 8350) +* Fix compat. layer ASN1_TIME_diff to accept NULL output params (PR 8407) +* Fix CMake lean_tls build (PR 8460) +* Fix for QUIC callback failure (PR 8475) +* Fix missing alert types in AlertTypeToString for print out with debugging + enabled (PR 8572) +* Fixes for MSVS build issues with PQC configure (PR 8568) +* Fix for SE050 port and minor improvements (PR 8431, 8437) +* Fix for missing rewind function in zephyr and add missing files for compiling + with assembly optimizations (PR 8531, 8541) +* Fix for quic_record_append to return the correct code (PR 8340, 8358) +* Fixes for Bind 9.18.28 port (PR 8331) +* Fix to adhere more closely with RFC8446 Appendix D and set haveEMS when + negotiating TLS 1.3 (PR 8487) +* Fix to properly check for signature_algorithms from the client in a TLS 1.3 + server (PR 8356) +* Fix for when BIO data is less than seq buffer size. Thanks to the team at Code + Intelligence for the report (PR 8426) +* ARM32/Thumb2 fixes for WOLFSSL_NO_VAR_ASSIGN_REG and td4 variable declarations + (PR 8590, 8635) +* Fix for Intel AVX1/SSE2 assembly to not use vzeroupper instructions unless ymm + or zmm registers are used (PR 8479) +* Entropy MemUse fix for when block size less than update bits (PR 8675) + + # wolfSSL Release 5.7.6 (Dec 31, 2024) Release 5.7.6 has been developed according to wolfSSL's development and QA diff --git a/README b/README index 47579ee..582977d 100644 --- a/README +++ b/README @@ -70,130 +70,214 @@ should be used for the enum name. *** end Notes *** -# wolfSSL Release 5.7.6 (Dec 31, 2024) +# wolfSSL Release 5.8.0 (Apr 24, 2025) -Release 5.7.6 has been developed according to wolfSSL's development and QA +Release 5.8.0 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. - * In this release, the default cipher suite preference is updated to prioritize - TLS_AES_256_GCM_SHA384 over TLS_AES_128_GCM_SHA256 when enabled. - * This release adds a sanity check for including wolfssl/options.h or - user_settings.h. - +NOTE: * --enable-heapmath is deprecated PR stands for Pull Request, and PR references a GitHub pull request number where the code change was added. -## Vulnerabilities -* [Med] An OCSP (non stapling) issue was introduced in wolfSSL version 5.7.4 - when performing OCSP requests for intermediate certificates in a certificate - chain. This affects only TLS 1.3 connections on the server side. It would not - impact other TLS protocol versions or connections that are not using the - traditional OCSP implementation. (Fix in pull request 8115) - - ## New Feature Additions -* Add support for RP2350 and improve RP2040 support, both with RNG optimizations - (PR 8153) -* Add support for STM32MP135F, including STM32CubeIDE support and HAL support - for SHA2/SHA3/AES/RNG/ECC optimizations. (PR 8223, 8231, 8241) -* Implement Renesas TSIP RSA Public Enc/Private support (PR 8122) -* Add support for Fedora/RedHat system-wide crypto-policies (PR 8205) -* Curve25519 generic keyparsing API added with wc_Curve25519KeyToDer and - wc_Curve25519KeyDecode (PR 8129) -* CRL improvements and update callback, added the functions - wolfSSL_CertManagerGetCRLInfo and wolfSSL_CertManagerSetCRLUpdate_Cb (PR 8006) -* For DTLS, add server-side stateless and CID quality-of-life API. (PR 8224) +* Algorithm registration in the Linux kernel module for all supported FIPS AES, + SHA, HMAC, ECDSA, ECDH, and RSA modes, key sizes, and digest sizes. +* Implemented various fixes to support building for Open Watcom including OS/2 + support and Open Watcom 1.9 compatibility (PR 8505, 8484) +* Added support for STM32H7S (tested on NUCLEO-H7S3L8) (PR 8488) +* Added support for STM32WBA (PR 8550) +* Added Extended Master Secret Generation Callback to the --enable-pkcallbacks + build (PR 8303) +* Implement AES-CTS (configure flag --enable-aescts) in wolfCrypt (PR 8594) +* Added support for libimobiledevice commit 860ffb (PR 8373) +* Initial ASCON hash256 and AEAD128 support based on NIST SP 800-232 IPD + (PR 8307) +* Added blinding option when using a Curve25519 private key by defining the + macro WOLFSSL_CURVE25519_BLINDING (PR 8392) + + +## Linux Kernel Module +* Production-ready LKCAPI registration for cbc(aes), cfb(aes), gcm(aes), + rfc4106 (gcm(aes)), ctr(aes), ofb(aes), and ecb(aes), ECDSA with P192, P256, + P384, and P521 curves, ECDH with P192, P256, and P384 curves, and RSA with + bare and PKCS1 padding +* Various fixes for LKCAPI wrapper for AES-CBC and AES-CFB (PR 8534, 8552) +* Adds support for the legacy one-shot AES-GCM back end (PR 8614, 8567) for + compatibility with FIPS 140-3 Cert #4718. +* On kernel >=6.8, for CONFIG_FORTIFY_SOURCE, use 5-arg fortify_panic() override + macro (PR 8654) +* Update calls to scatterwalk_map() and scatterwalk_unmap() for linux commit + 7450ebd29c (merged for Linux 6.15) (PR 8667) +* Inhibit LINUXKM_LKCAPI_REGISTER_ECDH on kernel <5.13 (PR 8673) +* Fix for uninitialized build error with fedora (PR 8569) +* Register ecdsa, ecdh, and rsa for use with linux kernel crypto (PR 8637, 8663, + 8646) +* Added force zero shared secret buffer, and clear of old key with ecdh + (PR 8685) +* Update fips-check.sh script to pickup XTS streaming support on aarch64 and + disable XTS-384 as an allowed use in FIPS mode (PR 8509, 8546) ## Enhancements and Optimizations -* Add a CMake dependency check for pthreads when required. (PR 8162) -* Update OS_Seed declarations for legacy compilers and FIPS modules (boundary - not affected). (PR 8170) -* Enable WOLFSSL_ALWAYS_KEEP_SNI by default when using --enable-jni. (PR 8283) -* Change the default cipher suite preference, prioritizing - TLS_AES_256_GCM_SHA384 over TLS_AES_128_GCM_SHA256. (PR 7771) -* Add SRTP-KDF (FIPS module v6.0.0) to checkout script for release bundling - (PR 8215) -* Make library build when no hardware crypto available for Aarch64 (PR 8293) -* Update assembly code to avoid `uint*_t` types for better compatibility with - older C standards. (PR 8133) -* Add initial documentation for writing ASN template code to decode BER/DER. - (PR 8120) -* Perform full reduction in sc_muladd for EdDSA with Curve448 (PR 8276) -* Allow SHA-3 hardware cryptography instructions to be explicitly not used in - MacOS builds (PR 8282) -* Make Kyber and ML-KEM available individually and together. (PR 8143) -* Update configuration options to include Kyber/ML-KEM and fix defines used in - wolfSSL_get_curve_name. (PR 8183) -* Make GetShortInt available with WOLFSSL_ASN_EXTRA (PR 8149) -* Improved test coverage and minor improvements of X509 (PR 8176) -* Add sanity checks for configuration methods, ensuring the inclusion of - wolfssl/options.h or user_settings.h. (PR 8262) -* Enable support for building without TLS (NO_TLS). Provides reduced code size - option for non-TLS users who want features like the certificate manager or - compatibility layer. (PR 8273) -* Exposed get_verify functions with OPENSSL_EXTRA. (PR 8258) -* ML-DSA/Dilithium: obtain security level from DER when decoding (PR 8177) -* Implementation for using PKCS11 to retrieve certificate for SSL CTX (PR 8267) -* Add support for the RFC822 Mailbox attribute (PR 8280) -* Initialize variables and adjust types resolve warnings with Visual Studio in - Windows builds. (PR 8181) -* Refactors and expansion of opensslcoexist build (PR 8132, 8216, 8230) -* Add DTLS 1.3 interoperability, libspdm and DTLS CID interoperability tests - (PR 8261, 8255, 8245) -* Remove trailing error exit code in wolfSSL install setup script (PR 8189) -* Update Arduino files for wolfssl 5.7.4 (PR 8219) -* Improve Espressif SHA HW/SW mutex messages (PR 8225) -* Apply post-5.7.4 release updates for Espressif Managed Component examples - (PR 8251) -* Expansion of c89 conformance (PR 8164) -* Added configure option for additional sanity checks with --enable-faultharden - (PR 8289) -* Aarch64 ASM additions to check CPU features before hardware crypto instruction - use (PR 8314) + +### Security & Cryptography +* Add constant-time implementation improvements for encoding functions. We thank + Zhiyuan and Gilles for sharing a new constant-time analysis tool (CT-LLVM) and + reporting several non-constant-time implementations. (PR 8396, 8617) +* Additional support for PKCS7 verify and decode with indefinite lengths + (PR 8520, 834, 8645) +* Add more PQC hybrid key exchange algorithms such as support for combinations + with X25519 and X448 enabling compatibility with the PQC key exchange support + in Chromium browsers and Mozilla Firefox (PR 7821) +* Add short-circuit comparisons to DH key validation for RFC 7919 parameters + (PR 8335) +* Improve FIPS compatibility with various build configurations for more resource + constrained builds (PR 8370) +* Added option to disable ECC public key order checking (PR 8581) +* Allow critical alt and basic constraints extensions (PR 8542) +* New codepoint for MLDSA to help with interoperability (PR 8393) +* Add support for parsing trusted PEM certs having the header + “BEGIN_TRUSTED_CERT” (PR 8400) +* Add support for parsing only of DoD certificate policy and Comodo Ltd PKI OIDs + (PR 8599, 8686) +* Update ssl code in `src/*.c` to be consistent with wolfcrypt/src/asn.c + handling of ML_DSA vs Dilithium and add dual alg. test (PR 8360, 8425) + +### Build System, Configuration, CI & Protocols +* Internal refactor for include of config.h and when building with + BUILDING_WOLFSSL macro. This refactor will give a warning of “deprecated + function” when trying to improperly use an internal API of wolfSSL in an + external application. (PR 8640, 8647, 8660, 8662, 8664) +* Add WOLFSSL_CLU option to CMakeLists.txt (PR 8548) +* Add CMake and Zephyr support for XMSS and LMS (PR 8494) +* Added GitHub CI for CMake builds (PR 8439) +* Added necessary macros when building wolfTPM Zephyr with wolfSSL (PR 8382) +* Add MSYS2 build continuous integration test (PR 8504) +* Update DevKitPro doc to list calico dependency with build commands (PR 8607) +* Conversion compiler warning fixes and additional continuous integration test + added (PR 8538) +* Enable DTLS 1.3 by default in --enable-jni builds (PR 8481) +* Enabled TLS 1.3 middlebox compatibility by default for --enable-jni builds + (PR 8526) + +### Performance Improvements +* Performance improvements AES-GCM and HMAC (in/out hash copy) (PR 8429) +* LMS fixes and improvements adding API to get Key ID from raw private key, + change to identifiers to match standard, and fix for when + WOLFSSL_LMS_MAX_LEVELS is 1 (PR 8390, 8684, 8613, 8623) +* ML-KEM/Kyber improvements and fixes; no malloc builds, small memory usage, + performance improvement, fix for big-endian (PR 8397, 8412, 8436, 8467, 8619, + 8622, 8588) +* Performance improvements for AES-GCM and when doing multiple HMAC operations + (PR 8445) + +### Assembly and Platform-Specific Enhancements +* Poly1305 arm assembly changes adding ARM32 NEON implementation and fix for + Aarch64 use (PR 8344, 8561, 8671) +* Aarch64 assembly enhancement to use more CPU features, fix for FreeBSD/OpenBSD + (PR 8325, 8348) +* Only perform ARM assembly CPUID checks if support was enabled at build time + (PR 8566) +* Optimizations for ARM32 assembly instructions on platforms less than ARMv7 + (PR 8395) +* Improve MSVC feature detection for static assert macros (PR 8440) +* Improve Espressif make and CMake for ESP8266 and ESP32 series (PR 8402) +* Espressif updates for Kconfig, ESP32P4 and adding a sample user_settings.h + (PR 8422, PR 8641) + +### OpenSSL Compatibility Layer +* Modification to the push/pop to/from in OpenSSL compatibility layer. This is + a pretty major API change in the OpenSSL compatibility stack functions. + Previously the API would push/pop from the beginning of the list but now they + operate on the tail of the list. This matters when using the sk_value with + index values. (PR 8616) +* OpenSSL Compat Layer: OCSP response improvements (PR 8408, 8498) +* Expand the OpenSSL compatibility layer to include an implementation of + BN_CTX_get (PR 8388) + +### API Additions and Modifications +* Refactor Hpke to allow multiple uses of a context instead of just one shot + mode (PR 6805) +* Add support for PSK client callback with Ada and use with Alire (thanks + @mgrojo, PR 8332, 8606) +* Change wolfSSL_CTX_GenerateEchConfig to generate multiple configs and add + functions wolfSSL_CTX_SetEchConfigs and wolfSSL_CTX_SetEchConfigsBase64 to + rotate the server's echConfigs (PR 8556) +* Added the public API wc_PkcsPad to do PKCS padding (PR 8502) +* Add NULL_CIPHER_TYPE support to wolfSSL_EVP_CipherUpdate (PR 8518) +* Update Kyber APIs to ML-KEM APIs (PR 8536) +* Add option to disallow automatic use of "default" devId using the macro + WC_NO_DEFAULT_DEVID (PR 8555) +* Detect unknown key format on ProcessBufferTryDecode() and handle RSA-PSSk + format (PR 8630) + +### Porting and Language Support +* Update Python port to support version 3.12.6 (PR 8345) +* New additions for MAXQ with wolfPKCS11 (PR 8343) +* Port to ntp 4.2.8p17 additions (PR 8324) +* Add version 0.9.14 to tested libvncserver builds (PR 8337) + +### General Improvements and Cleanups +* Cleanups for STM32 AES GCM (PR 8584) +* Improvements to isascii() and the CMake key log option (PR 8596) +* Arduino documentation updates, comments and spelling corrections (PR 8381, + 8384, 8514) +* Expanding builds with WOLFSSL_NO_REALLOC for use with --enable-opensslall and + --enable-all builds (PR 8369, 8371) ## Fixes -* Fix a memory issue when using the compatibility layer with - WOLFSSL_GENERAL_NAME and handling registered ID types. (PR 8155) -* Fix a build issue with signature fault hardening when using public key - callbacks (HAVE_PK_CALLBACKS). (PR 8287) -* Fix for handling heap hint pointer properly when managing multiple WOLFSSL_CTX - objects and free’ing one of them (PR 8180) -* Fix potential memory leak in error case with Aria. (PR 8268) -* Fix Set_Verify flag behaviour on Ada wrapper. (PR 8256) -* Fix a compilation error with the NO_WOLFSSL_DIR flag. (PR 8294) -* Resolve a corner case for Poly1305 assembly code on Aarch64. (PR 8275) -* Fix incorrect version setting in CSRs. (PR 8136) -* Correct debugging output for cryptodev. (PR 8202) -* Fix for benchmark application use with /dev/crypto GMAC auth error due to size - of AAD (PR 8210) -* Add missing checks for the initialization of sp_int/mp_int with DSA to free - memory properly in error cases. (PR 8209) -* Fix return value of wolfSSL_CTX_set_tlsext_use_srtp (8252) -* Check Root CA by Renesas TSIP before adding it to ca-table (PR 8101) -* Prevent adding a certificate to the CA cache for Renesas builds if it does not - set CA:TRUE in basic constraints. (PR 8060) -* Fix attribute certificate holder entityName parsing. (PR 8166) -* Resolve build issues for configurations without any wolfSSL/openssl - compatibility layer headers. (PR 8182) -* Fix for building SP RSA small and RSA public only (PR 8235) -* Fix for Renesas RX TSIP RSA Sign/Verify with wolfCrypt only (PR 8206) -* Fix to ensure all files have settings.h included (like wc_lms.c) and guards - for building all `*.c` files (PR 8257 and PR 8140) -* Fix x86 target build issues in Visual Studio for non-Windows operating - systems. (PR 8098) -* Fix wolfSSL_X509_STORE_get0_objects to handle no CA (PR 8226) -* Properly handle reference counting when adding to the X509 store. (PR 8233) -* Fix for various typos and improper size used with FreeRTOS_bind in the Renesas - example. Thanks to Hongbo for the report on example issues. (PR 7537) -* Fix for potential heap use after free with wolfSSL_PEM_read_bio_PrivateKey. - Thanks to Peter for the issue reported. (PR 8139) +* Fix a use after free caused by an early free on error in the X509 store + (PR 8449) +* Fix to account for existing PKCS8 header with + wolfSSL_PEM_write_PKCS8PrivateKey (PR 8612) +* Fixed failing CMake build issue when standard threads support is not found in + the system (PR 8485) +* Fix segmentation fault in SHA-512 implementation for AVX512 targets built with + gcc -march=native -O2 (PR 8329) +* Fix Windows socket API compatibility warning with mingw32 build (PR 8424) +* Fix potential null pointer increments in cipher list parsing (PR 8420) +* Fix for possible stack buffer overflow read with wolfSSL_SMIME_write_PKCS7. + Thanks to the team at Code Intelligence for the report. (PR 8466) +* Fix AES ECB implementation for Aarch64 ARM assembly (PR 8379) +* Fixed building with VS2008 and .NET 3.5 (PR 8621) +* Fixed possible error case memory leaks in CRL and EVP_Sign_Final (PR 8447) +* Fixed SSL_set_mtu compatibility function return code (PR 8330) +* Fixed Renesas RX TSIP (PR 8595) +* Fixed ECC non-blocking tests (PR 8533) +* Fixed CMake on MINGW and MSYS (PR 8377) +* Fixed Watcom compiler and added new CI test (PR 8391) +* Fixed STM32 PKA ECC 521-bit support (PR 8450) +* Fixed STM32 PKA with P521 and shared secret (PR 8601) +* Fixed crypto callback macro guards with `DEBUG_CRYPTOCB` (PR 8602) +* Fix outlen return for RSA private decrypt with WOLF_CRYPTO_CB_RSA_PAD + (PR 8575) +* Additional sanity check on r and s lengths in DecodeECC_DSA_Sig_Bin (PR 8350) +* Fix compat. layer ASN1_TIME_diff to accept NULL output params (PR 8407) +* Fix CMake lean_tls build (PR 8460) +* Fix for QUIC callback failure (PR 8475) +* Fix missing alert types in AlertTypeToString for print out with debugging + enabled (PR 8572) +* Fixes for MSVS build issues with PQC configure (PR 8568) +* Fix for SE050 port and minor improvements (PR 8431, 8437) +* Fix for missing rewind function in zephyr and add missing files for compiling + with assembly optimizations (PR 8531, 8541) +* Fix for quic_record_append to return the correct code (PR 8340, 8358) +* Fixes for Bind 9.18.28 port (PR 8331) +* Fix to adhere more closely with RFC8446 Appendix D and set haveEMS when + negotiating TLS 1.3 (PR 8487) +* Fix to properly check for signature_algorithms from the client in a TLS 1.3 + server (PR 8356) +* Fix for when BIO data is less than seq buffer size. Thanks to the team at Code + Intelligence for the report (PR 8426) +* ARM32/Thumb2 fixes for WOLFSSL_NO_VAR_ASSIGN_REG and td4 variable declarations + (PR 8590, 8635) +* Fix for Intel AVX1/SSE2 assembly to not use vzeroupper instructions unless ymm + or zmm registers are used (PR 8479) +* Entropy MemUse fix for when block size less than update bits (PR 8675) For additional vulnerability information visit the vulnerability page at: diff --git a/README.md b/README.md index b75d0d5..7c0fd06 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.7.6 for the Arduino platform. +This library is restructured from [wolfSSL](https://github.com/wolfSSL/wolfssl/) Release 5.8.0 for the Arduino platform. The Official wolfSSL Arduino Library is found in [The Library Manager index](http://downloads.arduino.cc/libraries/library_index.json). @@ -63,7 +63,7 @@ OpenSSL. wolfSSL is powered by the wolfCrypt cryptography library. Two versions of wolfCrypt have been FIPS 140-2 validated (Certificate #2425 and -certificate #3389). FIPS 140-3 validation is in progress. For additional +certificate #3389). FIPS 140-3 validated (Certificate #4718). For additional information, visit the [wolfCrypt FIPS FAQ](https://www.wolfssl.com/license/fips/) or contact fips@wolfssl.com. @@ -124,131 +124,214 @@ 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.7.6 (Dec 31, 2024) +# wolfSSL Release 5.8.0 (Apr 24, 2025) -Release 5.7.6 has been developed according to wolfSSL's development and QA +Release 5.8.0 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. - * In this release, the default cipher suite preference is updated to prioritize - TLS_AES_256_GCM_SHA384 over TLS_AES_128_GCM_SHA256 when enabled. - * This release adds a sanity check for including wolfssl/options.h or - user_settings.h. - +NOTE: * --enable-heapmath is deprecated PR stands for Pull Request, and PR references a GitHub pull request number where the code change was added. -## Vulnerabilities -* [Med] An OCSP (non stapling) issue was introduced in wolfSSL version 5.7.4 - when performing OCSP requests for intermediate certificates in a certificate - chain. This affects only TLS 1.3 connections on the server side. It would not - impact other TLS protocol versions or connections that are not using the - traditional OCSP implementation. (Fix in pull request 8115) - - ## New Feature Additions -* Add support for RP2350 and improve RP2040 support, both with RNG optimizations - (PR 8153) -* Add support for STM32MP135F, including STM32CubeIDE support and HAL support - for SHA2/SHA3/AES/RNG/ECC optimizations. (PR 8223, 8231, 8241) -* Implement Renesas TSIP RSA Public Enc/Private support (PR 8122) -* Add support for Fedora/RedHat system-wide crypto-policies (PR 8205) -* Curve25519 generic keyparsing API added with wc_Curve25519KeyToDer and - wc_Curve25519KeyDecode (PR 8129) -* CRL improvements and update callback, added the functions - wolfSSL_CertManagerGetCRLInfo and wolfSSL_CertManagerSetCRLUpdate_Cb (PR 8006) -* For DTLS, add server-side stateless and CID quality-of-life API. (PR 8224) +* Algorithm registration in the Linux kernel module for all supported FIPS AES, + SHA, HMAC, ECDSA, ECDH, and RSA modes, key sizes, and digest sizes. +* Implemented various fixes to support building for Open Watcom including OS/2 + support and Open Watcom 1.9 compatibility (PR 8505, 8484) +* Added support for STM32H7S (tested on NUCLEO-H7S3L8) (PR 8488) +* Added support for STM32WBA (PR 8550) +* Added Extended Master Secret Generation Callback to the --enable-pkcallbacks + build (PR 8303) +* Implement AES-CTS (configure flag --enable-aescts) in wolfCrypt (PR 8594) +* Added support for libimobiledevice commit 860ffb (PR 8373) +* Initial ASCON hash256 and AEAD128 support based on NIST SP 800-232 IPD + (PR 8307) +* Added blinding option when using a Curve25519 private key by defining the + macro WOLFSSL_CURVE25519_BLINDING (PR 8392) + + +## Linux Kernel Module +* Production-ready LKCAPI registration for cbc(aes), cfb(aes), gcm(aes), + rfc4106 (gcm(aes)), ctr(aes), ofb(aes), and ecb(aes), ECDSA with P192, P256, + P384, and P521 curves, ECDH with P192, P256, and P384 curves, and RSA with + bare and PKCS1 padding +* Various fixes for LKCAPI wrapper for AES-CBC and AES-CFB (PR 8534, 8552) +* Adds support for the legacy one-shot AES-GCM back end (PR 8614, 8567) for + compatibility with FIPS 140-3 Cert #4718. +* On kernel >=6.8, for CONFIG_FORTIFY_SOURCE, use 5-arg fortify_panic() override + macro (PR 8654) +* Update calls to scatterwalk_map() and scatterwalk_unmap() for linux commit + 7450ebd29c (merged for Linux 6.15) (PR 8667) +* Inhibit LINUXKM_LKCAPI_REGISTER_ECDH on kernel <5.13 (PR 8673) +* Fix for uninitialized build error with fedora (PR 8569) +* Register ecdsa, ecdh, and rsa for use with linux kernel crypto (PR 8637, 8663, + 8646) +* Added force zero shared secret buffer, and clear of old key with ecdh + (PR 8685) +* Update fips-check.sh script to pickup XTS streaming support on aarch64 and + disable XTS-384 as an allowed use in FIPS mode (PR 8509, 8546) ## Enhancements and Optimizations -* Add a CMake dependency check for pthreads when required. (PR 8162) -* Update OS_Seed declarations for legacy compilers and FIPS modules (boundary - not affected). (PR 8170) -* Enable WOLFSSL_ALWAYS_KEEP_SNI by default when using --enable-jni. (PR 8283) -* Change the default cipher suite preference, prioritizing - TLS_AES_256_GCM_SHA384 over TLS_AES_128_GCM_SHA256. (PR 7771) -* Add SRTP-KDF (FIPS module v6.0.0) to checkout script for release bundling - (PR 8215) -* Make library build when no hardware crypto available for Aarch64 (PR 8293) -* Update assembly code to avoid `uint*_t` types for better compatibility with - older C standards. (PR 8133) -* Add initial documentation for writing ASN template code to decode BER/DER. - (PR 8120) -* Perform full reduction in sc_muladd for EdDSA with Curve448 (PR 8276) -* Allow SHA-3 hardware cryptography instructions to be explicitly not used in - MacOS builds (PR 8282) -* Make Kyber and ML-KEM available individually and together. (PR 8143) -* Update configuration options to include Kyber/ML-KEM and fix defines used in - wolfSSL_get_curve_name. (PR 8183) -* Make GetShortInt available with WOLFSSL_ASN_EXTRA (PR 8149) -* Improved test coverage and minor improvements of X509 (PR 8176) -* Add sanity checks for configuration methods, ensuring the inclusion of - wolfssl/options.h or user_settings.h. (PR 8262) -* Enable support for building without TLS (NO_TLS). Provides reduced code size - option for non-TLS users who want features like the certificate manager or - compatibility layer. (PR 8273) -* Exposed get_verify functions with OPENSSL_EXTRA. (PR 8258) -* ML-DSA/Dilithium: obtain security level from DER when decoding (PR 8177) -* Implementation for using PKCS11 to retrieve certificate for SSL CTX (PR 8267) -* Add support for the RFC822 Mailbox attribute (PR 8280) -* Initialize variables and adjust types resolve warnings with Visual Studio in - Windows builds. (PR 8181) -* Refactors and expansion of opensslcoexist build (PR 8132, 8216, 8230) -* Add DTLS 1.3 interoperability, libspdm and DTLS CID interoperability tests - (PR 8261, 8255, 8245) -* Remove trailing error exit code in wolfSSL install setup script (PR 8189) -* Update Arduino files for wolfssl 5.7.4 (PR 8219) -* Improve Espressif SHA HW/SW mutex messages (PR 8225) -* Apply post-5.7.4 release updates for Espressif Managed Component examples - (PR 8251) -* Expansion of c89 conformance (PR 8164) -* Added configure option for additional sanity checks with --enable-faultharden - (PR 8289) -* Aarch64 ASM additions to check CPU features before hardware crypto instruction - use (PR 8314) +### Security & Cryptography +* Add constant-time implementation improvements for encoding functions. We thank + Zhiyuan and Gilles for sharing a new constant-time analysis tool (CT-LLVM) and + reporting several non-constant-time implementations. (PR 8396, 8617) +* Additional support for PKCS7 verify and decode with indefinite lengths + (PR 8520, 834, 8645) +* Add more PQC hybrid key exchange algorithms such as support for combinations + with X25519 and X448 enabling compatibility with the PQC key exchange support + in Chromium browsers and Mozilla Firefox (PR 7821) +* Add short-circuit comparisons to DH key validation for RFC 7919 parameters + (PR 8335) +* Improve FIPS compatibility with various build configurations for more resource + constrained builds (PR 8370) +* Added option to disable ECC public key order checking (PR 8581) +* Allow critical alt and basic constraints extensions (PR 8542) +* New codepoint for MLDSA to help with interoperability (PR 8393) +* Add support for parsing trusted PEM certs having the header + “BEGIN_TRUSTED_CERT” (PR 8400) +* Add support for parsing only of DoD certificate policy and Comodo Ltd PKI OIDs + (PR 8599, 8686) +* Update ssl code in `src/*.c` to be consistent with wolfcrypt/src/asn.c + handling of ML_DSA vs Dilithium and add dual alg. test (PR 8360, 8425) + +### Build System, Configuration, CI & Protocols +* Internal refactor for include of config.h and when building with + BUILDING_WOLFSSL macro. This refactor will give a warning of “deprecated + function” when trying to improperly use an internal API of wolfSSL in an + external application. (PR 8640, 8647, 8660, 8662, 8664) +* Add WOLFSSL_CLU option to CMakeLists.txt (PR 8548) +* Add CMake and Zephyr support for XMSS and LMS (PR 8494) +* Added GitHub CI for CMake builds (PR 8439) +* Added necessary macros when building wolfTPM Zephyr with wolfSSL (PR 8382) +* Add MSYS2 build continuous integration test (PR 8504) +* Update DevKitPro doc to list calico dependency with build commands (PR 8607) +* Conversion compiler warning fixes and additional continuous integration test + added (PR 8538) +* Enable DTLS 1.3 by default in --enable-jni builds (PR 8481) +* Enabled TLS 1.3 middlebox compatibility by default for --enable-jni builds + (PR 8526) + +### Performance Improvements +* Performance improvements AES-GCM and HMAC (in/out hash copy) (PR 8429) +* LMS fixes and improvements adding API to get Key ID from raw private key, + change to identifiers to match standard, and fix for when + WOLFSSL_LMS_MAX_LEVELS is 1 (PR 8390, 8684, 8613, 8623) +* ML-KEM/Kyber improvements and fixes; no malloc builds, small memory usage, + performance improvement, fix for big-endian (PR 8397, 8412, 8436, 8467, 8619, + 8622, 8588) +* Performance improvements for AES-GCM and when doing multiple HMAC operations + (PR 8445) + +### Assembly and Platform-Specific Enhancements +* Poly1305 arm assembly changes adding ARM32 NEON implementation and fix for + Aarch64 use (PR 8344, 8561, 8671) +* Aarch64 assembly enhancement to use more CPU features, fix for FreeBSD/OpenBSD + (PR 8325, 8348) +* Only perform ARM assembly CPUID checks if support was enabled at build time + (PR 8566) +* Optimizations for ARM32 assembly instructions on platforms less than ARMv7 + (PR 8395) +* Improve MSVC feature detection for static assert macros (PR 8440) +* Improve Espressif make and CMake for ESP8266 and ESP32 series (PR 8402) +* Espressif updates for Kconfig, ESP32P4 and adding a sample user_settings.h + (PR 8422, PR 8641) + +### OpenSSL Compatibility Layer +* Modification to the push/pop to/from in OpenSSL compatibility layer. This is + a pretty major API change in the OpenSSL compatibility stack functions. + Previously the API would push/pop from the beginning of the list but now they + operate on the tail of the list. This matters when using the sk_value with + index values. (PR 8616) +* OpenSSL Compat Layer: OCSP response improvements (PR 8408, 8498) +* Expand the OpenSSL compatibility layer to include an implementation of + BN_CTX_get (PR 8388) + +### API Additions and Modifications +* Refactor Hpke to allow multiple uses of a context instead of just one shot + mode (PR 6805) +* Add support for PSK client callback with Ada and use with Alire (thanks + @mgrojo, PR 8332, 8606) +* Change wolfSSL_CTX_GenerateEchConfig to generate multiple configs and add + functions wolfSSL_CTX_SetEchConfigs and wolfSSL_CTX_SetEchConfigsBase64 to + rotate the server's echConfigs (PR 8556) +* Added the public API wc_PkcsPad to do PKCS padding (PR 8502) +* Add NULL_CIPHER_TYPE support to wolfSSL_EVP_CipherUpdate (PR 8518) +* Update Kyber APIs to ML-KEM APIs (PR 8536) +* Add option to disallow automatic use of "default" devId using the macro + WC_NO_DEFAULT_DEVID (PR 8555) +* Detect unknown key format on ProcessBufferTryDecode() and handle RSA-PSSk + format (PR 8630) + +### Porting and Language Support +* Update Python port to support version 3.12.6 (PR 8345) +* New additions for MAXQ with wolfPKCS11 (PR 8343) +* Port to ntp 4.2.8p17 additions (PR 8324) +* Add version 0.9.14 to tested libvncserver builds (PR 8337) + +### General Improvements and Cleanups +* Cleanups for STM32 AES GCM (PR 8584) +* Improvements to isascii() and the CMake key log option (PR 8596) +* Arduino documentation updates, comments and spelling corrections (PR 8381, + 8384, 8514) +* Expanding builds with WOLFSSL_NO_REALLOC for use with --enable-opensslall and + --enable-all builds (PR 8369, 8371) -## Fixes -* Fix a memory issue when using the compatibility layer with - WOLFSSL_GENERAL_NAME and handling registered ID types. (PR 8155) -* Fix a build issue with signature fault hardening when using public key - callbacks (HAVE_PK_CALLBACKS). (PR 8287) -* Fix for handling heap hint pointer properly when managing multiple WOLFSSL_CTX - objects and free’ing one of them (PR 8180) -* Fix potential memory leak in error case with Aria. (PR 8268) -* Fix Set_Verify flag behaviour on Ada wrapper. (PR 8256) -* Fix a compilation error with the NO_WOLFSSL_DIR flag. (PR 8294) -* Resolve a corner case for Poly1305 assembly code on Aarch64. (PR 8275) -* Fix incorrect version setting in CSRs. (PR 8136) -* Correct debugging output for cryptodev. (PR 8202) -* Fix for benchmark application use with /dev/crypto GMAC auth error due to size - of AAD (PR 8210) -* Add missing checks for the initialization of sp_int/mp_int with DSA to free - memory properly in error cases. (PR 8209) -* Fix return value of wolfSSL_CTX_set_tlsext_use_srtp (8252) -* Check Root CA by Renesas TSIP before adding it to ca-table (PR 8101) -* Prevent adding a certificate to the CA cache for Renesas builds if it does not - set CA:TRUE in basic constraints. (PR 8060) -* Fix attribute certificate holder entityName parsing. (PR 8166) -* Resolve build issues for configurations without any wolfSSL/openssl - compatibility layer headers. (PR 8182) -* Fix for building SP RSA small and RSA public only (PR 8235) -* Fix for Renesas RX TSIP RSA Sign/Verify with wolfCrypt only (PR 8206) -* Fix to ensure all files have settings.h included (like wc_lms.c) and guards - for building all `*.c` files (PR 8257 and PR 8140) -* Fix x86 target build issues in Visual Studio for non-Windows operating - systems. (PR 8098) -* Fix wolfSSL_X509_STORE_get0_objects to handle no CA (PR 8226) -* Properly handle reference counting when adding to the X509 store. (PR 8233) -* Fix for various typos and improper size used with FreeRTOS_bind in the Renesas - example. Thanks to Hongbo for the report on example issues. (PR 7537) -* Fix for potential heap use after free with wolfSSL_PEM_read_bio_PrivateKey. - Thanks to Peter for the issue reported. (PR 8139) +## Fixes +* Fix a use after free caused by an early free on error in the X509 store + (PR 8449) +* Fix to account for existing PKCS8 header with + wolfSSL_PEM_write_PKCS8PrivateKey (PR 8612) +* Fixed failing CMake build issue when standard threads support is not found in + the system (PR 8485) +* Fix segmentation fault in SHA-512 implementation for AVX512 targets built with + gcc -march=native -O2 (PR 8329) +* Fix Windows socket API compatibility warning with mingw32 build (PR 8424) +* Fix potential null pointer increments in cipher list parsing (PR 8420) +* Fix for possible stack buffer overflow read with wolfSSL_SMIME_write_PKCS7. + Thanks to the team at Code Intelligence for the report. (PR 8466) +* Fix AES ECB implementation for Aarch64 ARM assembly (PR 8379) +* Fixed building with VS2008 and .NET 3.5 (PR 8621) +* Fixed possible error case memory leaks in CRL and EVP_Sign_Final (PR 8447) +* Fixed SSL_set_mtu compatibility function return code (PR 8330) +* Fixed Renesas RX TSIP (PR 8595) +* Fixed ECC non-blocking tests (PR 8533) +* Fixed CMake on MINGW and MSYS (PR 8377) +* Fixed Watcom compiler and added new CI test (PR 8391) +* Fixed STM32 PKA ECC 521-bit support (PR 8450) +* Fixed STM32 PKA with P521 and shared secret (PR 8601) +* Fixed crypto callback macro guards with `DEBUG_CRYPTOCB` (PR 8602) +* Fix outlen return for RSA private decrypt with WOLF_CRYPTO_CB_RSA_PAD + (PR 8575) +* Additional sanity check on r and s lengths in DecodeECC_DSA_Sig_Bin (PR 8350) +* Fix compat. layer ASN1_TIME_diff to accept NULL output params (PR 8407) +* Fix CMake lean_tls build (PR 8460) +* Fix for QUIC callback failure (PR 8475) +* Fix missing alert types in AlertTypeToString for print out with debugging + enabled (PR 8572) +* Fixes for MSVS build issues with PQC configure (PR 8568) +* Fix for SE050 port and minor improvements (PR 8431, 8437) +* Fix for missing rewind function in zephyr and add missing files for compiling + with assembly optimizations (PR 8531, 8541) +* Fix for quic_record_append to return the correct code (PR 8340, 8358) +* Fixes for Bind 9.18.28 port (PR 8331) +* Fix to adhere more closely with RFC8446 Appendix D and set haveEMS when + negotiating TLS 1.3 (PR 8487) +* Fix to properly check for signature_algorithms from the client in a TLS 1.3 + server (PR 8356) +* Fix for when BIO data is less than seq buffer size. Thanks to the team at Code + Intelligence for the report (PR 8426) +* ARM32/Thumb2 fixes for WOLFSSL_NO_VAR_ASSIGN_REG and td4 variable declarations + (PR 8590, 8635) +* Fix for Intel AVX1/SSE2 assembly to not use vzeroupper instructions unless ymm + or zmm registers are used (PR 8479) +* Entropy MemUse fix for when block size less than update bits (PR 8675) For additional vulnerability information visit the vulnerability page at: https://www.wolfssl.com/docs/security-vulnerabilities/ diff --git a/examples/template/README.md b/examples/template/README.md new file mode 100644 index 0000000..5ce0cbf --- /dev/null +++ b/examples/template/README.md @@ -0,0 +1,34 @@ +# Template Example + +Open the [template.ino](./template.ino) file in the Arduino IDE. + +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'`, 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/template/template.ino b/examples/template/template.ino new file mode 100644 index 0000000..8998976 --- /dev/null +++ b/examples/template/template.ino @@ -0,0 +1,143 @@ +/* template.ino + * + * 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 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include + +/* 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. + */ + +/* This is Arduino reference sketch example 2 of 2: multiple file .ino */ +/* See also template.ino project example using a single file project. */ + +/* Do not insert attempts at appending wolfssl user_settings.h here. + * All wolfssl settings needed by wolfSSL must be in the user_settings.h */ +#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 a simple wolfSSL header to this example: */ +#include + +/* There's a wolfSSL_Arduino_Serial_Print() for logging messages in wolfssl. */ +#include + +/* Include files (.c, .cpp, .h) typically in the same directory as the sketch; + * The wolfssl_helper is an example of this: */ +#include "wolfssl_helper.h" + +/* Arduino library header files are typically not in an `include` directory; + * The wolfssl_library is an example of a library directory: */ +#include "wolfssl_library/wolfssl_library.h" +#include "wolfssl_library/src/wolfssl_library.cpp" /* Force compilation */ + +/* Choose a monitor serial baud rate: 9600, 14400, 19200, 57600, 74880, etc. */ +#define SERIAL_BAUD 115200 + +/*****************************************************************************/ +/*****************************************************************************/ +/* Arduino setup() */ +/*****************************************************************************/ +/*****************************************************************************/ +void setup() { + Serial.begin(SERIAL_BAUD); + while (!Serial) { + /* wait for serial port to connect. Needed for native USB port only */ + delay(10); + } + /* See https://github.com/wolfSSL/wolfssl/blob/master/examples/configs/user_settings_arduino.h */ + /* Various historical versions have differing features enabled. */ +#ifdef WOLFSSL_USER_SETTINGS_ID + /* Print the release version at runtime for reference. */ + Serial.println(WOLFSSL_USER_SETTINGS_ID); +#else + /* Introduced after v5.7.6, or otherwise missing from user_settings.h */ + Serial.println("A WOLFSSL_USER_SETTINGS_ID not found."); +#endif + + Serial.println(F("wolfSSL setup complete!!")); + Serial.println(F("")); + Serial.println(F("")); +} + +/*****************************************************************************/ +/*****************************************************************************/ +/* Arduino loop() */ +/*****************************************************************************/ +/*****************************************************************************/ +void loop() { + int ret; + Serial.println("\nLOOP!\n\n"); + + Serial.print("wolfSSL Version: "); + Serial.println(LIBWOLFSSL_VERSION_STRING); + + /* A project-level include. + * These files typically WILL be visible automatically in the Arduino IDE */ + ret = wolfssl_helper_sample(); + Serial.print("- wolfssl_helper_sample ret = "); + Serial.println(ret); + + /* A local library directory. + * These files typically WILL NOT be visible in the Arduino IDE */ + ret = wolfssl_library_sample(); + Serial.print("- wolfssl_library_sample ret = "); + Serial.println(ret); + + /* This next section demonstrates wolfSSL logging. Logging is toggled + * on or off for each Arduino loop() iteration. WOLFSSL_MSG() only + * prints messages when debugging is turned on. */ + + /* Internal wolfssl_log() uses wolfSSL_Arduino_Serial_Print() */ + Serial.println(""); + Serial.println("Example wolfSSL_Arduino_Serial_Print():"); + wolfSSL_Arduino_Serial_Print("Hello from wolfSSL_Arduino_Serial_Print"); + + /* WOLFSSL_MSG uses wolfssl_log() for conditional messages. */ + Serial.println("The next line is conditional depending on debug state:"); + WOLFSSL_MSG("Hello from wolfssl_log"); + Serial.println(""); + + ret = WOLFSSL_IS_DEBUG_ON(); + if (ret == 0) { + Serial.println(""); /* nothing would have printed in WOLFSSL_MSG */ + Serial.println("WOLFSSL_IS_DEBUG_ON is not set (debugging off)"); + + Serial.println("Calling wolfSSL_Debugging_ON()"); + wolfSSL_Debugging_ON(); + } + else { + Serial.println("WOLFSSL_IS_DEBUG_ON is set (debugging on)"); + + Serial.println("Calling wolfSSL_Debugging_OFF()"); + wolfSSL_Debugging_OFF(); + } + + delay(60000); +} diff --git a/examples/template/wolfssl_helper.c b/examples/template/wolfssl_helper.c new file mode 100644 index 0000000..f4eeb57 --- /dev/null +++ b/examples/template/wolfssl_helper.c @@ -0,0 +1,52 @@ +/* my_library.cpp + * + * 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 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* This is a sample include directory library using wolfSSL. + * + * Do not explicitly include wolfSSL user_settings.h here. + * + * 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 + +#include "wolfssl_helper.h" + +int wolfssl_helper_sample() +{ + /* We cannot use Serial.print in a "c" file */ + /* Serial.print("Hello world!"); */ + int ret; + printf("Hello wolfssl_helper_sample!\r\n"); + + printf("- Calling wolfSSL_Init()\r\n"); + ret = wolfSSL_Init(); + if (ret == WOLFSSL_SUCCESS) { + printf("- Success wolfssl_helper!\r\n"); + } + else { + printf("- Error initializing wolfSSL!\r\n"); + } + return ret; +} diff --git a/examples/template/wolfssl_helper.h b/examples/template/wolfssl_helper.h new file mode 100644 index 0000000..844f022 --- /dev/null +++ b/examples/template/wolfssl_helper.h @@ -0,0 +1,37 @@ +/* wolfssl_helper.h + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +#ifndef _WOLFSSL_HELPER_H_ +#define _WOLFSSL_HELPER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Sample source code is C, but Arduino is compiling with C++ */ +int wolfssl_helper_sample(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/template/wolfssl_library/src/wolfssl_library.cpp b/examples/template/wolfssl_library/src/wolfssl_library.cpp new file mode 100644 index 0000000..e4d9685 --- /dev/null +++ b/examples/template/wolfssl_library/src/wolfssl_library.cpp @@ -0,0 +1,42 @@ +/* wolfssl_library.cpp + * + * 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 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ +#include +#include +#include + +/* Arduino source is typically in a `src` directory, with header in parent: */ +#include "../wolfssl_library.h" + +int wolfssl_library_sample() +{ + int ret = 0; + Serial.println("\nHello wolfssl_library!"); + + printf("- Calling wolfSSL_Init()\r\n"); + ret = wolfSSL_Init(); + if (ret == WOLFSSL_SUCCESS) { + printf("- Success wolfssl_library!\r\n"); + } + else { + printf("- Error initializing wolfSSL!\r\n"); + } + return ret; +} diff --git a/examples/template/wolfssl_library/wolfssl_library.h b/examples/template/wolfssl_library/wolfssl_library.h new file mode 100644 index 0000000..98f5dfd --- /dev/null +++ b/examples/template/wolfssl_library/wolfssl_library.h @@ -0,0 +1,46 @@ +/* wolfssl_library.h + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + + +/* This is a sample include directory library using wolfSSL. + * + * Do not explicitly include wolfSSL user_settings.h here. + * + * Be sure to include these files in all libraries that reference + * wolfssl in this order: */ + +#include +#include "wolfssl.h" + + #ifndef _WOLFSSL_LIBRARY_H_ + #define _WOLFSSL_LIBRARY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int wolfssl_library_sample(); + +#ifdef __cplusplus +} +#endif + +#endif /* _WOLFSSL_LIBRARY_H_ */ diff --git a/examples/wolfssl_AES_CTR/README.md b/examples/wolfssl_AES_CTR/README.md new file mode 100644 index 0000000..c9b26d6 --- /dev/null +++ b/examples/wolfssl_AES_CTR/README.md @@ -0,0 +1,34 @@ +# Arduino AES CTR Example + +Open the [wolfssl_AES_CTR.ino](./wolfssl_AES_CTR.ino) file in the Arduino IDE. + +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'`, 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_AES_CTR/wolfssl_AES_CTR.ino b/examples/wolfssl_AES_CTR/wolfssl_AES_CTR.ino new file mode 100644 index 0000000..31ef797 --- /dev/null +++ b/examples/wolfssl_AES_CTR/wolfssl_AES_CTR.ino @@ -0,0 +1,268 @@ +/* wolfssl_AES_CTR.ino + * + * 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 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* +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. + +AES Counter mode (AES-CTR) is a "Block Cipher Mode of Operation" that +turns a block cipher into a stream cipher, as explained here: +https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_(CTR) + +The wolfSSL AES algorithms in this sketch (e.g wc_AesCtrEncrypt) are just some of +many algorithms in the wolfSSL library. All are documented in the wolfSSL Manual at +https://www.wolfssl.com/documentation/manuals/wolfssl/group__AES.html + +This sketch example demonstrates AES-CTR usage by first encrypting the input +data producing the cipher, then decrypt the cipher to reveal the original data. + +Required user inputs +-------------------- +1) Encryption Key +2) Initialization Vector ("iv") +3) The input data to be encrypted + +Tested on +--------- +Arduino UNO R4 WiFi (Renesas ARM Cortex M4) +Sparkfun MicroMod WiFi Function Board (ESP32-WROOM-32E) +Wemos D1 R32 Development Board (ESP32-WROOM-32) +Teensy 4.1 (ARM Cortex M7) + +*/ + +#define WOLFSSL_AES_CTR_EXAMPLE +#include +#include + +#if defined(NO_AES) or !defined(WOLFSSL_AES_COUNTER) or !defined(WOLFSSL_AES_128) + /* edit user_settings.h in ~\Arduino\libraries\wolfssl\src + * e.g. for Windows: + * C:\Users\%USERNAME%\Documents\Arduino\libraries\wolfssl\src + */ + #error "Missing AES, WOLFSSL_AES_COUNTER or WOLFSSL_AES_128" +#endif + +/* macro to check for expected results */ +#define ExpectIntEQ(p1, p2) if (p1 == p2) { \ + Serial.println(F("OK")); \ + } \ + else { \ + Serial.println(F("FAIL")); \ + } + + +/* USER INPUTS: + * The Encryption Key (encKey) is confidential and must only be shared with + * the intended recipient of the data. Length must be 16, 24, 32 or larger + * multiples of AES_BLOCK_SIZE + * + * The initialization Vector (iv) is a nonce/counter (or 'salt') that is + * incremented between each encryption to ensures no two ciphers are identical, + * even if the input data is unchanged. Can be any length. + * + * The input data ("input") provides the bytes to be encrypted. + * Must be 16, 24, 32 bytes, or larger multiples of AES_BLOCK_SIZE + */ + +/* Choose one of these data sets, or provide your own. */ +/* Example data set 1 */ +byte encKey[] = {0x33,0x9a,0x28,0x9d,0x08,0x61,0xe8,0x34, + 0x16,0xe5,0x8d,0xb7,0x58,0x33,0xdc,0x0a}; /* 16 bytes */ +byte iv[] = {0x43,0x05, 0, 0, 0, 0, 0, 0, /* Padded to */ + 0, 0, 0, 0, 0, 0, 0, 0}; /* 16 bytes */ +byte input[] = {0x05,0x00,0x8c,0x0a,0x21,0x00,0x6a,0x00, + 0x5c,0x00,0xff,0xff,0xc1,0xfc,0x25,0xc4}; /* 16 bytes */ + +/* + * Example data set 2 +byte encKey[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x38,0x39,0x61,0x62,0x63,0x64,0x65,0x66, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, + 0x38,0x39,0x61,0x62,0x63,0x64,0x65,0x66}; // 32 bytes + +byte iv[] = "1234567890abcdef"; + +byte input[] = { // Now is the time for all w/o trailing 0 + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20}; // 24 bytes +*/ + +/* create aes objects for encryption & decryption */ +Aes aesEnc; +Aes aesDec; + +/* Print out the data as HEX bytes with breaks every 8 bytes */ +void reportData(byte * data, int sz) { + int i; + for (i = 0; i < sz; i++) { + if (data[i] < 0x10) { + Serial.print(F("0")); + } + Serial.print(data[i], HEX); + if (i < sz - 1) { + if (((i + 1) % 8) == 0) { + Serial.print(F(" | ")); + } + else { + Serial.print(F(" ")); + } + } + } + Serial.println(); +} + +/*****************************************************************************/ +/*****************************************************************************/ +/* Arduino setup() */ +/*****************************************************************************/ +/*****************************************************************************/ +void setup() { + Serial.begin(115200); + while (!Serial && millis() < 1000) ; /* wait for serial, up to 1 sec */ + + Serial.println(); + Serial.println(); + Serial.println(F("===== wolfSSL example: AES Counter mode =====")); + Serial.print(F("wolfSSL library version: ")); + Serial.println(LIBWOLFSSL_VERSION_STRING); + Serial.println(); +} + + +/*****************************************************************************/ +/*****************************************************************************/ +/* Arduino loop() */ +/*****************************************************************************/ +/*****************************************************************************/ +void loop() { + memset(&aesEnc, 0, sizeof(Aes)); /* fill aesEnc with zeros */ + memset(&aesDec, 0, sizeof(Aes)); /* ditto aesDec */ + + /* --------------------------------------------------------------------- */ + /* Choose blkSize of be 16, 24, 32 or larger multiples of 8, based */ + /* on sizeof(input) data. Uncomment the relevant lines from following: */ + + Serial.print(F("data set 1 [")); + uint32_t blkSize = AES_BLOCK_SIZE * 1; /* 16 bytes (for data set 1) */ + + /* Serial.print(F("data set 2 - ")); */ + /* uint32_t blkSize = AES_BLOCK_SIZE * 1.5; // 24 bytes (for data set 2) */ + + /* Serial.print(F("my data set - ")); */ + /* uint32_t blkSize = AES_BLOCK_SIZE * n; // choose an appropriate n */ + + Serial.print(F("blkSize: ")); + Serial.print(blkSize); + Serial.println(F(" bytes]")); + Serial.println(); + /* ----------------------------------------------------------------------*/ + + byte cipher[blkSize]; /* for the encrypted data (or "cipher") */ + byte output[blkSize]; /* for the deciphered data */ + memset(cipher, 0, blkSize); /* fill with zeros */ + memset(output, 0, blkSize); /* fill with zeros */ + + /* initialize structures for encryption and decryption. */ + Serial.println(F("--- Encryption ...")); + Serial.print(F("init aes (enc) : ")); + + /* init aesEnc structure, with NULL heap hint, dev id not used. */ + ExpectIntEQ(wc_AesInit(&aesEnc, NULL, INVALID_DEVID), 0); + + /* set up the key + salt in the AES encryption structure. */ + Serial.print(F("load key (enc) : ")); + ExpectIntEQ(wc_AesSetKey(&aesEnc, encKey, blkSize, iv, AES_ENCRYPTION), 0); + + /* encrypt */ + Serial.print(F("encryption done: ")); + ExpectIntEQ(wc_AesCtrEncrypt(&aesEnc, cipher, + input, sizeof(input) / sizeof(byte) ), 0); + + Serial.println(); + Serial.println(F("--- Decryption ...")); + /* set up the key + salt in the AES decryption structure. */ + Serial.print(F("init aes (dec) : ")); + + /* init aesDec structure, with NULL heap hint, dev id not used. */ + ExpectIntEQ(wc_AesInit(&aesDec, NULL, INVALID_DEVID), 0); + + /* set up the key + salt in an AES decryption structure. */ + Serial.print(F("load key (dec) : ")); + ExpectIntEQ(wc_AesSetKey(&aesDec, encKey, blkSize, iv, AES_ENCRYPTION), 0); + + /* decrypt */ + Serial.print(F("decryption done: ")); + ExpectIntEQ(wc_AesCtrEncrypt(&aesDec, output, + cipher, sizeof(cipher) / sizeof(byte)), 0); + Serial.println(); + + /* Test for bad args */ + Serial.println(F("--- Check for bad arguments ...")); + Serial.print(F("Bad arguments 1: ")); + ExpectIntEQ(wc_AesCtrEncrypt(NULL, output, + cipher, sizeof(cipher) / sizeof(byte)), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + + Serial.print(F("Bad arguments 2: ")); + ExpectIntEQ(wc_AesCtrEncrypt(&aesDec, NULL, + cipher, sizeof(cipher) / sizeof(byte)), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + + Serial.print(F("Bad arguments 3: ")); + ExpectIntEQ(wc_AesCtrEncrypt(&aesDec, output, + NULL, sizeof(cipher) / sizeof(byte)), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + + /* Display data and results. */ + Serial.println(); + Serial.println(F("--- Inputs ...")); + Serial.print(F("key : ")); reportData(encKey, sizeof(encKey)); + Serial.print(F("salt/iv : ")); reportData(iv, sizeof(iv)); + Serial.print(F("data in : ")); reportData(input, sizeof(input)); + + Serial.println(); + Serial.println(F("--- Outputs ...")); + Serial.print(F("cipher : ")); + reportData(cipher, sizeof(cipher)); + Serial.print(F("decipher: ")); + reportData(output, sizeof(output)); + Serial.println(); + + if (memcmp(input, output, sizeof(input)) == 0) { + Serial.println(F("** SUCCESS ** deciphered data matches input data.")); + } + else { + Serial.print(F("*** FAILED *** deciphered & input data DO NOT MATCH.")); + } + Serial.println(); + + /* Free up resources associated with the aes structures. */ + wc_AesFree(&aesEnc); + wc_AesFree(&aesDec); + + Serial.println(F("===== end =====")); + + while (1) { + /* nothing */ + } +} diff --git a/examples/wolfssl_client/README.md b/examples/wolfssl_client/README.md index caf83c5..3068931 100644 --- a/examples/wolfssl_client/README.md +++ b/examples/wolfssl_client/README.md @@ -2,6 +2,12 @@ Open the [wolfssl_client.ino](./wolfssl_client.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) diff --git a/examples/wolfssl_client/wolfssl_client.ino b/examples/wolfssl_client/wolfssl_client.ino index d6ef702..8af1eaf 100644 --- a/examples/wolfssl_client/wolfssl_client.ino +++ b/examples/wolfssl_client/wolfssl_client.ino @@ -37,7 +37,7 @@ Tested with: */ /* If you have a private include, define it here, otherwise edit WiFi params */ -#define MY_PRIVATE_CONFIG "/workspace/my_private_config.h" +/* #define MY_PRIVATE_CONFIG "/workspace/my_private_config.h" */ /* set REPEAT_CONNECTION to a non-zero value to continually run the example. */ #define REPEAT_CONNECTION 0 @@ -68,12 +68,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" @@ -166,9 +166,10 @@ Tested with: #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: */ diff --git a/examples/wolfssl_server/README.md b/examples/wolfssl_server/README.md index a707357..e961d71 100644 --- a/examples/wolfssl_server/README.md +++ b/examples/wolfssl_server/README.md @@ -2,6 +2,12 @@ Open the [wolfssl_server.ino](./wolfssl_server.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) diff --git a/examples/wolfssl_server/wolfssl_server.ino b/examples/wolfssl_server/wolfssl_server.ino index c3820df..1b9d4ed 100644 --- a/examples/wolfssl_server/wolfssl_server.ino +++ b/examples/wolfssl_server/wolfssl_server.ino @@ -1,6 +1,6 @@ /* wolfssl_server.ino * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -37,7 +37,7 @@ Tested with: */ /* If you have a private include, define it here, otherwise edit WiFi params */ -#define MY_PRIVATE_CONFIG "/workspace/my_private_config.h" +/* #define MY_PRIVATE_CONFIG "/workspace/my_private_config.h" */ /* set REPEAT_CONNECTION to a non-zero value to continually run the example. */ #define REPEAT_CONNECTION 1 @@ -68,12 +68,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" @@ -166,6 +166,8 @@ Tested with: #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); diff --git a/examples/wolfssl_version/wolfssl_version.ino b/examples/wolfssl_version/wolfssl_version.ino index a2f13fe..12be948 100644 --- a/examples/wolfssl_version/wolfssl_version.ino +++ b/examples/wolfssl_version/wolfssl_version.ino @@ -30,13 +30,21 @@ * The wolfSSL "settings.h" must be included in each source file using wolfSSL. * The wolfSSL "settings.h" must appear before any other wolfSSL include. */ + +/* This is Arduino sketch example 1 of 2: single file .ino compile. */ +/* See also template.ino project example using multiple files. */ + #include #include /* Choose a monitor serial baud rate: 9600, 14400, 19200, 57600, 74880, etc. */ #define SERIAL_BAUD 115200 -/* Arduino setup */ +/*****************************************************************************/ +/*****************************************************************************/ +/* Arduino setup() */ +/*****************************************************************************/ +/*****************************************************************************/ void setup() { Serial.begin(SERIAL_BAUD); while (!Serial) { @@ -45,9 +53,20 @@ void setup() { Serial.println(F("")); Serial.println(F("")); Serial.println(F("wolfSSL setup complete!")); + + /* See https://github.com/wolfSSL/wolfssl/blob/master/examples/configs/user_settings_arduino.h */ + /* Various historical versions have differing features enabled. */ +#ifdef WOLFSSL_USER_SETTINGS_ID + /* Print the release version at runtime for reference. */ + Serial.println(WOLFSSL_USER_SETTINGS_ID); +#endif } -/* Arduino main application loop. */ +/*****************************************************************************/ +/*****************************************************************************/ +/* Arduino loop() */ +/*****************************************************************************/ +/*****************************************************************************/ void loop() { Serial.print("wolfSSL Version: "); Serial.println(LIBWOLFSSL_VERSION_STRING); diff --git a/library.properties b/library.properties index 1f9456b..16c905a 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=wolfssl -version=5.7.6 +version=5.8.0 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 b265456..0b52a6c 100644 --- a/src/src/bio.c +++ b/src/src/bio.c @@ -1,6 +1,6 @@ /* bio.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif +#include -#include #if defined(OPENSSL_EXTRA) && !defined(_WIN32) && !defined(_GNU_SOURCE) /* turn on GNU extensions for XVASPRINTF with wolfSSL_BIO_printf */ #define _GNU_SOURCE 1 @@ -142,7 +139,7 @@ static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len) return WOLFSSL_BIO_ERROR; } - XMEMCPY(buf, bio->mem_buf->data + bio->rdIdx, sz); + XMEMCPY(buf, bio->mem_buf->data + bio->rdIdx, (size_t)sz); bio->rdIdx += sz; if (bio->rdIdx >= bio->wrSz) { @@ -167,14 +164,14 @@ static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len) /* Resize the memory so we are not taking up more than necessary. * memmove reverts internally to memcpy if areas don't overlap */ XMEMMOVE(bio->mem_buf->data, bio->mem_buf->data + bio->rdIdx, - bio->wrSz - bio->rdIdx); + (long unsigned int)bio->wrSz - (size_t)bio->rdIdx); bio->wrSz -= bio->rdIdx; bio->rdIdx = 0; /* Resize down to WOLFSSL_BIO_RESIZE_THRESHOLD for fewer * allocations. */ if (wolfSSL_BUF_MEM_resize(bio->mem_buf, - bio->wrSz > WOLFSSL_BIO_RESIZE_THRESHOLD ? bio->wrSz : - WOLFSSL_BIO_RESIZE_THRESHOLD) == 0) { + bio->wrSz > WOLFSSL_BIO_RESIZE_THRESHOLD ? + (size_t)bio->wrSz : WOLFSSL_BIO_RESIZE_THRESHOLD) == 0) { WOLFSSL_MSG("wolfSSL_BUF_MEM_resize error"); return WOLFSSL_BIO_ERROR; } @@ -389,6 +386,10 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) #endif break; + case WOLFSSL_BIO_NULL: + ret = 0; + break; + } /* switch */ } @@ -564,7 +565,7 @@ static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data, WOLFSSL_MSG("Error in wolfSSL_BIO_nwrite"); return sz1; } - XMEMCPY(buf, data, sz1); + XMEMCPY(buf, data, (size_t)sz1); data = (char*)data + sz1; len -= sz1; @@ -572,7 +573,7 @@ static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data, /* try again to see if maybe we wrapped around the ring buffer */ sz2 = wolfSSL_BIO_nwrite(bio, &buf, len); if (sz2 > 0) { - XMEMCPY(buf, data, sz2); + XMEMCPY(buf, data, (size_t)sz2); sz1 += sz2; if (len > sz2) bio->flags |= WOLFSSL_BIO_FLAG_WRITE|WOLFSSL_BIO_FLAG_RETRY; @@ -610,8 +611,8 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data, if (len == 0) return WOLFSSL_SUCCESS; /* Return early to make logic simpler */ - if (wolfSSL_BUF_MEM_grow_ex(bio->mem_buf, bio->wrSz + len, 0) - == 0) { + if (wolfSSL_BUF_MEM_grow_ex(bio->mem_buf, ((size_t)bio->wrSz) + + ((size_t)len), 0) == 0) { WOLFSSL_MSG("Error growing memory area"); return WOLFSSL_FAILURE; } @@ -621,7 +622,7 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data, return WOLFSSL_FAILURE; } - XMEMCPY(bio->mem_buf->data + bio->wrSz, data, len); + XMEMCPY(bio->mem_buf->data + bio->wrSz, data, (size_t)len); bio->ptr.mem_buf_data = (byte *)bio->mem_buf->data; bio->num.length = bio->mem_buf->max; bio->wrSz += len; @@ -813,6 +814,10 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) #endif break; + case WOLFSSL_BIO_NULL: + ret = len; + break; + } /* switch */ } @@ -1138,7 +1143,7 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz) ret = wolfSSL_BIO_nread(bio, &c, cSz); if (ret > 0 && ret < sz) { - XMEMCPY(buf, c, ret); + XMEMCPY(buf, c, (size_t)ret); } break; } @@ -1161,6 +1166,10 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz) break; #endif /* WOLFCRYPT_ONLY */ + case WOLFSSL_BIO_NULL: + ret = 0; + break; + default: WOLFSSL_MSG("BIO type not supported yet with wolfSSL_BIO_gets"); } @@ -1256,13 +1265,13 @@ size_t wolfSSL_BIO_wpending(const WOLFSSL_BIO *bio) return 0; if (bio->type == WOLFSSL_BIO_MEMORY) { - return bio->wrSz; + return (size_t)bio->wrSz; } /* type BIO_BIO then check paired buffer */ if (bio->type == WOLFSSL_BIO_BIO && bio->pair != NULL) { WOLFSSL_BIO* pair = bio->pair; - return pair->wrIdx; + return (size_t)pair->wrIdx; } return 0; @@ -1308,12 +1317,12 @@ size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio) #ifndef WOLFCRYPT_ONLY if (bio->type == WOLFSSL_BIO_SSL && bio->ptr.ssl != NULL) { - return (long)wolfSSL_pending(bio->ptr.ssl); + return (size_t)wolfSSL_pending(bio->ptr.ssl); } #endif if (bio->type == WOLFSSL_BIO_MEMORY) { - return bio->wrSz - bio->rdIdx; + return (size_t)(bio->wrSz - bio->rdIdx); } /* type BIO_BIO then check paired buffer */ @@ -1322,11 +1331,12 @@ size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio) if (pair->wrIdx > 0 && pair->wrIdx <= pair->rdIdx) { /* in wrap around state where beginning of buffer is being * overwritten */ - return pair->wrSz - pair->rdIdx + pair->wrIdx; + return ((size_t)pair->wrSz) - ((size_t)pair->rdIdx) + + ((size_t)pair->wrIdx); } else { /* simple case where has not wrapped around */ - return pair->wrIdx - pair->rdIdx; + return (size_t)(pair->wrIdx - pair->rdIdx); } } return 0; @@ -1423,7 +1433,7 @@ int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size) XFREE(bio->ptr.mem_buf_data, bio->heap, DYNAMIC_TYPE_OPENSSL); } - bio->ptr.mem_buf_data = (byte*)XMALLOC(size, bio->heap, + bio->ptr.mem_buf_data = (byte*)XMALLOC((size_t)size, bio->heap, DYNAMIC_TYPE_OPENSSL); if (bio->ptr.mem_buf_data == NULL) { WOLFSSL_MSG("Memory allocation error"); @@ -1439,7 +1449,7 @@ int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size) return WOLFSSL_FAILURE; } bio->wrSz = (int)size; - bio->num.length = size; + bio->num.length = (size_t)size; bio->wrIdx = 0; bio->rdIdx = 0; if (bio->mem_buf != NULL) { @@ -1908,7 +1918,7 @@ long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v) int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio) { - int len; + int len = 0; #ifndef NO_FILESYSTEM long memSz = 0; XFILE file; @@ -2309,6 +2319,15 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) return &meth; } + WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_null(void) + { + static WOLFSSL_BIO_METHOD meth = + WOLFSSL_BIO_METHOD_INIT(WOLFSSL_BIO_NULL); + + WOLFSSL_ENTER("wolfSSL_BIO_s_null"); + + return &meth; + } WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void) { @@ -2353,7 +2372,6 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) WOLFSSL_ENTER("wolfSSL_BIO_new_dgram"); if (bio) { - bio->type = WOLFSSL_BIO_DGRAM; bio->shutdown = (byte)closeF; bio->num.fd = (SOCKET_T)fd; } @@ -2381,10 +2399,11 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) else port = str + XSTRLEN(str); /* point to null terminator */ - bio->ip = (char*)XMALLOC((port - str) + 1, /* +1 for null char */ + bio->ip = (char*)XMALLOC( + (size_t)(port - str) + 1, /* +1 for null char */ bio->heap, DYNAMIC_TYPE_OPENSSL); if (bio->ip != NULL) { - XMEMCPY(bio->ip, str, port - str); + XMEMCPY(bio->ip, str, (size_t)(port - str)); bio->ip[port - str] = '\0'; bio->type = WOLFSSL_BIO_SOCKET; } @@ -2770,9 +2789,23 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) } else { size_t currLen = XSTRLEN(b->ip); + #ifdef WOLFSSL_NO_REALLOC + char* tmp = NULL; + #endif + if (currLen != newLen) { + #ifdef WOLFSSL_NO_REALLOC + tmp = b->ip; + b->ip = (char*)XMALLOC(newLen+1, b->heap, DYNAMIC_TYPE_OPENSSL); + if (b->ip != NULL && tmp != NULL) { + XMEMCPY(b->ip, tmp, newLen); + XFREE(tmp, b->heap, DYNAMIC_TYPE_OPENSSL); + tmp = NULL; + } + #else b->ip = (char*)XREALLOC(b->ip, newLen + 1, b->heap, DYNAMIC_TYPE_OPENSSL); + #endif if (b->ip == NULL) { WOLFSSL_MSG("Hostname realloc failed."); return WOLFSSL_FAILURE; @@ -2926,7 +2959,7 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) bio->wrSz = len; bio->ptr.mem_buf_data = (byte *)bio->mem_buf->data; if (len > 0 && bio->ptr.mem_buf_data != NULL) { - XMEMCPY(bio->ptr.mem_buf_data, buf, len); + XMEMCPY(bio->ptr.mem_buf_data, buf, (size_t)len); bio->flags |= WOLFSSL_BIO_FLAG_MEM_RDONLY; bio->wrSzReset = bio->wrSz; } @@ -3295,11 +3328,11 @@ int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args) count = XVSNPRINTF(NULL, 0, format, args); if (count >= 0) { - pt = (char*)XMALLOC(count + 1, bio->heap, + pt = (char*)XMALLOC((size_t)count + 1, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); if (pt != NULL) { - count = XVSNPRINTF(pt, count + 1, format, copy); + count = XVSNPRINTF(pt, (size_t)count + 1, format, copy); if (count >= 0) { ret = wolfSSL_BIO_write(bio, pt, count); @@ -3369,18 +3402,20 @@ int wolfSSL_BIO_dump(WOLFSSL_BIO *bio, const char *buf, int length) o = 7; for (i = 0; i < BIO_DUMP_LINE_LEN; i++) { if (i < length) - (void)XSNPRINTF(line + o, (int)sizeof(line) - o, + (void)XSNPRINTF(line + o, (size_t)((int)sizeof(line) - o), "%02x ", (unsigned char)buf[i]); else - (void)XSNPRINTF(line + o, (int)sizeof(line) - o, " "); + (void)XSNPRINTF(line + o, (size_t)((int)sizeof(line) - o), + " "); if (i == 7) - (void)XSNPRINTF(line + o + 2, (int)sizeof(line) - (o + 2), "-"); + (void)XSNPRINTF(line + o + 2, (size_t)((int)sizeof(line) - + (o + 2)), "-"); o += 3; } - (void)XSNPRINTF(line + o, (int)sizeof(line) - o, " "); + (void)XSNPRINTF(line + o, (size_t)((int)sizeof(line) - o), " "); o += 2; for (i = 0; (i < BIO_DUMP_LINE_LEN) && (i < length); i++) { - (void)XSNPRINTF(line + o, (int)sizeof(line) - o, "%c", + (void)XSNPRINTF(line + o, (size_t)((int)sizeof(line) - o), "%c", ((31 < buf[i]) && (buf[i] < 127)) ? buf[i] : '.'); o++; } diff --git a/src/src/conf.c b/src/src/conf.c index b614148..a30be38 100644 --- a/src/src/conf.c +++ b/src/src/conf.c @@ -1,6 +1,6 @@ /* conf.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if !defined(WOLFSSL_CONF_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN @@ -773,8 +768,18 @@ static char* expandValue(WOLFSSL_CONF *conf, const char* section, /* This will allocate slightly more memory than necessary * but better be safe */ strLen += valueLen; + #ifdef WOLFSSL_NO_REALLOC + newRet = (char*)XMALLOC(strLen + 1, NULL, + DYNAMIC_TYPE_OPENSSL); + if (newRet != NULL && ret != NULL) { + XMEMCPY(newRet, ret, (strLen - valueLen) + 1); + XFREE(ret, NULL, DYNAMIC_TYPE_OPENSSL); + ret = NULL; + } + #else newRet = (char*)XREALLOC(ret, strLen + 1, NULL, DYNAMIC_TYPE_OPENSSL); + #endif if (!newRet) { WOLFSSL_MSG("realloc error"); goto expand_cleanup; @@ -979,8 +984,6 @@ void wolfSSL_NCONF_free(WOLFSSL_CONF *conf) void wolfSSL_X509V3_conf_free(WOLFSSL_CONF_VALUE *val) { - WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *sk = NULL; - if (val) { if (val->name) { /* Not a section. Don't free section as it is a shared pointer. */ @@ -992,12 +995,7 @@ void wolfSSL_X509V3_conf_free(WOLFSSL_CONF_VALUE *val) XFREE(val->section, NULL, DYNAMIC_TYPE_OPENSSL); /* Only free the stack structures. The contained conf values * will be freed in wolfSSL_NCONF_free */ - sk = (WOLF_STACK_OF(WOLFSSL_CONF_VALUE)*)val->value; - while (sk) { - WOLF_STACK_OF(WOLFSSL_CONF_VALUE) *tmp = sk->next; - XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); - sk = tmp; - } + wolfSSL_sk_free((WOLF_STACK_OF(WOLFSSL_CONF_VALUE)*)val->value); } XFREE(val, NULL, DYNAMIC_TYPE_OPENSSL); } @@ -1023,19 +1021,9 @@ WOLFSSL_STACK *wolfSSL_sk_CONF_VALUE_new( */ void wolfSSL_sk_CONF_VALUE_free(WOLF_STACK_OF(WOLFSSL_CONF_VALUE)* sk) { - WOLFSSL_STACK* tmp; WOLFSSL_ENTER("wolfSSL_sk_CONF_VALUE_free"); - if (sk == NULL) - return; - - /* parse through stack freeing each node */ - while (sk) { - tmp = sk->next; - wolfSSL_X509V3_conf_free(sk->data.conf); - XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); - sk = tmp; - } + wolfSSL_sk_pop_free(sk, NULL); } int wolfSSL_sk_CONF_VALUE_num(const WOLFSSL_STACK *sk) diff --git a/src/src/crl.c b/src/src/crl.c index b78002c..437342c 100644 --- a/src/src/crl.c +++ b/src/src/crl.c @@ -1,6 +1,6 @@ /* crl.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include /* CRL Options: @@ -32,11 +33,6 @@ CRL Options: * Return any errors encountered during loading CRL * from a directory. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include #ifndef WOLFCRYPT_ONLY #ifdef HAVE_CRL @@ -87,6 +83,13 @@ int InitCRL(WOLFSSL_CRL* crl, WOLFSSL_CERT_MANAGER* cm) WOLFSSL_MSG("Init Mutex failed"); return BAD_MUTEX_E; } +#ifdef OPENSSL_ALL + { + int ret; + wolfSSL_RefInit(&crl->ref, &ret); + (void)ret; + } +#endif return 0; } @@ -213,7 +216,7 @@ static void CRL_Entry_free(CRL_Entry* crle, void* heap) WOLFSSL_ENTER("FreeCRL_Entry"); - while (tmp) { + while (tmp != NULL) { next = tmp->next; XFREE(tmp, heap, DYNAMIC_TYPE_REVOKED); tmp = next; @@ -241,11 +244,24 @@ void FreeCRL(WOLFSSL_CRL* crl, int dynamic) { CRL_Entry* tmp; + WOLFSSL_ENTER("FreeCRL"); + if (crl == NULL) return; +#ifdef OPENSSL_ALL + { + int ret; + int doFree = 0; + wolfSSL_RefDec(&crl->ref, &doFree, &ret); + if (ret != 0) + WOLFSSL_MSG("Couldn't lock x509 mutex"); + if (!doFree) + return; + } +#endif + tmp = crl->crlList; - WOLFSSL_ENTER("FreeCRL"); #ifdef HAVE_CRL_MONITOR if (crl->monitors[0].path) XFREE(crl->monitors[0].path, crl->heap, DYNAMIC_TYPE_CRL_MONITOR); @@ -898,7 +914,7 @@ static RevokedCert *DupRevokedCertList(RevokedCert* in, void* heap) static CRL_Entry* DupCRL_Entry(const CRL_Entry* ent, void* heap) { CRL_Entry *dupl; - const size_t copyOffset = OFFSETOF(CRL_Entry, verifyMutex) + + const size_t copyOffset = WC_OFFSETOF(CRL_Entry, verifyMutex) + sizeof(ent->verifyMutex); #ifdef CRL_STATIC_REVOKED_LIST if (ent->totalCerts > CRL_MAX_REVOKED_CERTS) { @@ -916,9 +932,17 @@ static CRL_Entry* DupCRL_Entry(const CRL_Entry* ent, void* heap) #ifndef CRL_STATIC_REVOKED_LIST dupl->certs = DupRevokedCertList(ent->certs, heap); + if (ent->certs != NULL && dupl->certs == NULL) { + CRL_Entry_free(dupl, heap); + return NULL; + } #endif #ifdef OPENSSL_EXTRA dupl->issuer = wolfSSL_X509_NAME_dup(ent->issuer); + if (ent->issuer != NULL && dupl->issuer == NULL) { + CRL_Entry_free(dupl, heap); + return NULL; + } #endif if (!ent->verified) { @@ -1027,6 +1051,7 @@ static int DupX509_CRL(WOLFSSL_X509_CRL *dupl, const WOLFSSL_X509_CRL* crl) if (dupl->monitors[0].path != NULL) { XFREE(dupl->monitors[0].path, dupl->heap, DYNAMIC_TYPE_CRL_MONITOR); + dupl->monitors[0].path = NULL; } return MEMORY_E; } @@ -1034,6 +1059,8 @@ static int DupX509_CRL(WOLFSSL_X509_CRL *dupl, const WOLFSSL_X509_CRL* crl) #endif dupl->crlList = DupCRL_list(crl->crlList, dupl->heap); + if (dupl->crlList == NULL) + return MEMORY_E; #ifdef HAVE_CRL_IO dupl->crlIOCb = crl->crlIOCb; #endif @@ -1775,6 +1802,10 @@ int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor) ret = ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl, VERIFY); 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 return ret; } } diff --git a/src/src/dtls.c b/src/src/dtls.c index ae27804..2d3c38b 100644 --- a/src/src/dtls.c +++ b/src/src/dtls.c @@ -1,6 +1,6 @@ /* dtls.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include + /* * WOLFSSL_DTLS_NO_HVR_ON_RESUME * WOLFSSL_DTLS13_NO_HRR_ON_RESUME @@ -46,12 +48,6 @@ * to explicitly enable this during runtime. */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - #ifndef WOLFCRYPT_ONLY #include @@ -365,7 +361,8 @@ static int FindExtByType(WolfSSL_ConstVector* ret, word16 extType, ato16(exts.elements + idx, &type); idx += OPAQUE16_LEN; idx += ReadVector16(exts.elements + idx, &ext); - if (idx > exts.size) + if (idx > exts.size || + ext.elements + ext.size > exts.elements + exts.size) return BUFFER_ERROR; if (type == extType) { XMEMCPY(ret, &ext, sizeof(ext)); @@ -498,7 +495,7 @@ static int TlsCheckSupportedVersion(const WOLFSSL* ssl, ch->extension, &tlsxFound); if (ret != 0) return ret; - if (!tlsxFound) { + if (!tlsxFound || tlsxSupportedVersions.elements == NULL) { *isTls13 = 0; return 0; } @@ -847,8 +844,6 @@ static int SendStatelessReplyDtls13(const WOLFSSL* ssl, WolfSSL_CH* ch) WOLFSSL* nonConstSSL = (WOLFSSL*)ssl; TLSX* sslExts = nonConstSSL->extensions; - if (ret != 0) - goto dtls13_cleanup; nonConstSSL->options.tls = 1; nonConstSSL->options.tls1_1 = 1; nonConstSSL->options.tls1_3 = 1; @@ -1221,7 +1216,7 @@ int TLSX_ConnectionID_Use(WOLFSSL* ssl) info = (CIDInfo*)XMALLOC(sizeof(CIDInfo), ssl->heap, DYNAMIC_TYPE_TLSX); if (info == NULL) return MEMORY_ERROR; - ext = (WOLFSSL**)XMALLOC(sizeof(WOLFSSL**), ssl->heap, DYNAMIC_TYPE_TLSX); + ext = (WOLFSSL**)XMALLOC(sizeof(WOLFSSL*), ssl->heap, DYNAMIC_TYPE_TLSX); if (ext == NULL) { XFREE(info, ssl->heap, DYNAMIC_TYPE_TLSX); return MEMORY_ERROR; diff --git a/src/src/dtls13.c b/src/src/dtls13.c index 161ce4f..5a9b6dc 100644 --- a/src/src/dtls13.c +++ b/src/src/dtls13.c @@ -1,6 +1,6 @@ /* dtls13.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H -#include -#endif - -#include +#include #ifdef WOLFSSL_DTLS13 @@ -31,10 +27,7 @@ #include #include #include -#include #include -#include -#include #ifdef NO_INLINE #include @@ -185,7 +178,8 @@ int Dtls13RlAddPlaintextHeader(WOLFSSL* ssl, byte* out, /* seq[0] combines the epoch and 16 MSB of sequence number. We write on the epoch field and will overflow to the first two bytes of the sequence number */ - c32toa(seq[0], hdr->epoch); + c16toa((word16)(seq[0] >> 16), hdr->epoch); + c16toa((word16)seq[0], hdr->sequenceNumber); c32toa(seq[1], &hdr->sequenceNumber[2]); c16toa(length, hdr->length); @@ -724,7 +718,7 @@ static Dtls13RecordNumber* Dtls13NewRecordNumber(w64wrapper epoch, return rn; } -static int Dtls13RtxAddAck(WOLFSSL* ssl, w64wrapper epoch, w64wrapper seq) +int Dtls13RtxAddAck(WOLFSSL* ssl, w64wrapper epoch, w64wrapper seq) { Dtls13RecordNumber* rn; @@ -734,12 +728,28 @@ static int Dtls13RtxAddAck(WOLFSSL* ssl, w64wrapper epoch, w64wrapper seq) if (wc_LockMutex(&ssl->dtls13Rtx.mutex) == 0) #endif { + /* Find location to insert new record */ + Dtls13RecordNumber** prevNext = &ssl->dtls13Rtx.seenRecords; + Dtls13RecordNumber* cur = ssl->dtls13Rtx.seenRecords; + + for (; cur != NULL; prevNext = &cur->next, cur = cur->next) { + if (w64Equal(cur->epoch, epoch) && w64Equal(cur->seq, seq)) { + /* already in list. no duplicates. */ + return 0; + } + else if (w64LT(epoch, cur->epoch) + || (w64Equal(epoch, cur->epoch) + && w64LT(seq, cur->seq))) { + break; + } + } + rn = Dtls13NewRecordNumber(epoch, seq, ssl->heap); if (rn == NULL) return MEMORY_E; - rn->next = ssl->dtls13Rtx.seenRecords; - ssl->dtls13Rtx.seenRecords = rn; + *prevNext = rn; + rn->next = cur; #ifdef WOLFSSL_RW_THREADED wc_UnLockMutex(&ssl->dtls13Rtx.mutex); #endif @@ -1551,11 +1561,14 @@ static int Dtls13RtxSendBuffered(WOLFSSL* ssl) byte* output; int isLast; int sendSz; +#ifndef NO_ASN_TIME word32 now; +#endif int ret; WOLFSSL_ENTER("Dtls13RtxSendBuffered"); +#ifndef NO_ASN_TIME now = LowResTimer(); if (now - ssl->dtls13Rtx.lastRtx < DTLS13_MIN_RTX_INTERVAL) { #ifdef WOLFSSL_DEBUG_TLS @@ -1565,6 +1578,7 @@ static int Dtls13RtxSendBuffered(WOLFSSL* ssl) } ssl->dtls13Rtx.lastRtx = now; +#endif r = ssl->dtls13Rtx.rtxRecords; prevNext = &ssl->dtls13Rtx.rtxRecords; @@ -1639,6 +1653,102 @@ static int Dtls13AcceptFragmented(WOLFSSL *ssl, enum HandShakeType type) #endif return 0; } + +int Dtls13CheckEpoch(WOLFSSL* ssl, enum HandShakeType type) +{ + w64wrapper plainEpoch = w64From32(0x0, 0x0); + w64wrapper hsEpoch = w64From32(0x0, DTLS13_EPOCH_HANDSHAKE); + w64wrapper t0Epoch = w64From32(0x0, DTLS13_EPOCH_TRAFFIC0); + + if (IsAtLeastTLSv1_3(ssl->version)) { + switch (type) { + case client_hello: + case server_hello: + case hello_verify_request: + case hello_retry_request: + case hello_request: + if (!w64Equal(ssl->keys.curEpoch64, plainEpoch)) { + WOLFSSL_MSG("Msg should be epoch 0"); + WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E); + return SANITY_MSG_E; + } + break; + case encrypted_extensions: + case server_key_exchange: + case server_hello_done: + case client_key_exchange: + if (!w64Equal(ssl->keys.curEpoch64, hsEpoch)) { + if (ssl->options.side == WOLFSSL_CLIENT_END && + ssl->options.serverState < SERVER_HELLO_COMPLETE) { + /* before processing SH we don't know which version + * will be negotiated. */ + if (!w64Equal(ssl->keys.curEpoch64, plainEpoch)) { + WOLFSSL_MSG("Msg should be epoch 2 or 0"); + WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E); + return SANITY_MSG_E; + } + } + else { + WOLFSSL_MSG("Msg should be epoch 2"); + WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E); + return SANITY_MSG_E; + } + } + break; + case certificate_request: + case certificate: + case certificate_verify: + case finished: + if (!ssl->options.handShakeDone) { + if (!w64Equal(ssl->keys.curEpoch64, hsEpoch)) { + if (ssl->options.side == WOLFSSL_CLIENT_END && + ssl->options.serverState < SERVER_HELLO_COMPLETE) { + /* before processing SH we don't know which version + * will be negotiated. */ + if (!w64Equal(ssl->keys.curEpoch64, plainEpoch)) { + WOLFSSL_MSG("Msg should be epoch 2 or 0"); + WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E); + return SANITY_MSG_E; + } + } + else { + WOLFSSL_MSG("Msg should be epoch 2"); + WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E); + return SANITY_MSG_E; + } + } + } + else { + /* Allow epoch 2 in case of rtx */ + if (!w64GTE(ssl->keys.curEpoch64, hsEpoch)) { + WOLFSSL_MSG("Msg should be epoch 2+"); + WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E); + return SANITY_MSG_E; + } + } + break; + case certificate_status: + case change_cipher_hs: + case key_update: + case session_ticket: + if (!w64GTE(ssl->keys.curEpoch64, t0Epoch)) { + WOLFSSL_MSG("Msg should be epoch 3+"); + WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E); + return SANITY_MSG_E; + } + break; + case end_of_early_data: + case message_hash: + case no_shake: + default: + WOLFSSL_MSG("Unknown message type"); + WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E); + return SANITY_MSG_E; + } + } + return 0; +} + /** * Dtls13HandshakeRecv() - process an handshake message. Deal with fragmentation if needed @@ -1674,6 +1784,12 @@ static int _Dtls13HandshakeRecv(WOLFSSL* ssl, byte* input, word32 size, return ret; } + ret = Dtls13CheckEpoch(ssl, (enum HandShakeType)handshakeType); + if (ret != 0) { + WOLFSSL_ERROR(ret); + return ret; + } + if (ssl->options.side == WOLFSSL_SERVER_END && ssl->options.acceptState < TLS13_ACCEPT_FIRST_REPLY_DONE) { if (handshakeType != client_hello) { @@ -1961,6 +2077,9 @@ int Dtls13DeriveSnKeys(WOLFSSL* ssl, int provision) end: ForceZero(key_dig, MAX_PRF_DIG); +#ifdef WOLFSSL_CHECK_MEM_ZERO + wc_MemZero_Check(key_dig, sizeof(key_dig)); +#endif return ret; } @@ -2419,7 +2538,7 @@ static int Dtls13GetAckListLength(Dtls13RecordNumber* list, word16* length) return 0; } -static int Dtls13WriteAckMessage(WOLFSSL* ssl, +int Dtls13WriteAckMessage(WOLFSSL* ssl, Dtls13RecordNumber* recordNumberList, word32* length) { word16 msgSz, headerLength; diff --git a/src/src/internal.c b/src/src/internal.c index 666de86..eb2f16d 100644 --- a/src/src/internal.c +++ b/src/src/internal.c @@ -1,6 +1,6 @@ /* internal.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include /* * WOLFSSL_SMALL_CERT_VERIFY: @@ -157,7 +153,7 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS #error Cannot use both secure-renegotiation and renegotiation-indication #endif -#ifndef WOLFSSL_NO_TLS12 +#if !defined(NO_TLS) && !defined(WOLFSSL_NO_TLS12) #ifndef NO_WOLFSSL_CLIENT static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, @@ -170,7 +166,7 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size); #endif -#endif +#endif /* !NO_WOLFSSL_CLIENT */ #ifndef NO_WOLFSSL_SERVER @@ -183,7 +179,7 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS #endif #endif /* !NO_WOLFSSL_SERVER */ -#endif /* !WOLFSSL_NO_TLS12 */ +#endif /* !NO_TLS && !WOLFSSL_NO_TLS12 */ #if !defined(NO_WOLFSSL_SERVER) && defined(HAVE_SESSION_TICKET) #if defined(WOLFSSL_HAPROXY) @@ -202,7 +198,7 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS int enc, byte* ticket, int inLen, int* outLen, void* userCtx); #endif -#endif +#endif /* !NO_WOLFSSL_SERVER && HAVE_SESSION_TICKET */ int writeAeadAuthData(WOLFSSL* ssl, word16 sz, byte type, byte* additional, byte dec, byte** seq, int verifyOrder); @@ -240,13 +236,14 @@ enum processReply { }; -#ifndef WOLFSSL_NO_TLS12 +#if !defined(NO_TLS) && !defined(WOLFSSL_NO_TLS12) #if !defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT) /* Server random bytes for TLS v1.3 described downgrade protection mechanism. */ static const byte tls13Downgrade[7] = { 0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44 }; + #define TLS13_DOWNGRADE_SZ sizeof(tls13Downgrade) #endif /* !NO_WOLFSSL_SERVER || !NO_WOLFSSL_CLIENT */ @@ -257,7 +254,7 @@ static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, #endif -#endif /* !WOLFSSL_NO_TLS12 */ +#endif /* !NO_TLS && !WOLFSSL_NO_TLS12 */ #if !defined(NO_CERT) && defined(WOLFSSL_BLIND_PRIVATE_KEY) @@ -300,7 +297,7 @@ void wolfssl_priv_der_unblind(DerBuffer* key, DerBuffer* mask) xorbuf(key->buffer, mask->buffer, mask->length); } } -#endif +#endif /* !NO_CERT && WOLFSSL_BLIND_PRIVATE_KEY */ #if defined(WOLFSSL_RENESAS_FSPSM_TLS) || defined(WOLFSSL_RENESAS_TSIP_TLS) @@ -605,24 +602,24 @@ int IsAtLeastTLSv1_3(const ProtocolVersion pv) int IsEncryptionOn(const WOLFSSL* ssl, int isSend) { - #ifdef WOLFSSL_DTLS +#ifdef WOLFSSL_DTLS /* For DTLS, epoch 0 is always not encrypted. */ if (ssl->options.dtls && !isSend) { if (!IsAtLeastTLSv1_3(ssl->version) && ssl->keys.curEpoch == 0) return 0; -#ifdef WOLFSSL_DTLS13 + #ifdef WOLFSSL_DTLS13 else if (IsAtLeastTLSv1_3(ssl->version) && w64IsZero(ssl->keys.curEpoch64)) return 0; -#endif /* WOLFSSL_DTLS13 */ + #endif /* WOLFSSL_DTLS13 */ } - #endif /* WOLFSSL_DTLS */ - #ifdef WOLFSSL_QUIC +#endif /* WOLFSSL_DTLS */ +#ifdef WOLFSSL_QUIC if (WOLFSSL_IS_QUIC(ssl) && IsAtLeastTLSv1_3(ssl->version)) { return 0; } - #endif +#endif /* WOLFSSL_QUIC */ return ssl->keys.encryptionOn && (isSend ? ssl->encrypt.setup : ssl->decrypt.setup); } @@ -2262,7 +2259,8 @@ int InitSSL_Side(WOLFSSL* ssl, word16 side) return InitSSL_Suites(ssl); } -#endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */ +#endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE || + * WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */ #if defined(WOLFSSL_SYS_CRYPTO_POLICY) /* Check the wolfssl method meets minimum requirements for @@ -2812,7 +2810,7 @@ void FreeEchConfigs(WOLFSSL_EchConfig* configs, void* heap) (void)heap; } -#endif +#endif /* WOLFSSL_TLS13 && HAVE_ECH */ /* In case contexts are held in array and don't want to free actual ctx. */ @@ -3023,7 +3021,16 @@ void FreeSSL_Ctx(WOLFSSL_CTX* ctx) if (isZero) { WOLFSSL_MSG("CTX ref count down to 0, doing full free"); - +#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) && \ + !defined(NO_SHA256) && !defined(WC_NO_RNG) + if (ctx->srp != NULL) { + XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP); + ctx->srp_password = NULL; + wc_SrpTerm(ctx->srp); + XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP); + ctx->srp = NULL; + } +#endif SSL_CtxResourceFree(ctx); #if defined(HAVE_SESSION_TICKET) && !defined(NO_WOLFSSL_SERVER) && \ !defined(WOLFSSL_NO_DEF_TICKET_ENC_CB) && !defined(NO_TLS) @@ -3469,7 +3476,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, (void) tls; tls1_2 = pv.minor <= DTLSv1_2_MINOR; } -#endif +#endif /* WOLFSSL_DTLS */ (void)tls; /* shut up compiler */ (void)tls1_2; @@ -3539,6 +3546,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = TLS_SM4_GCM_SM3; } #endif + #ifdef BUILD_TLS_SM4_CCM_SM3 if (tls1_3) { suites->suites[idx++] = CIPHER_BYTE; @@ -3769,7 +3777,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA; } #endif -#endif +#endif /* WOLFSSL_MYSQL_COMPATIBLE */ #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 #ifdef OPENSSL_EXTRA @@ -4006,7 +4014,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256; } -#endif +#endif /* BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */ #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4018,7 +4026,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256; } -#endif +#endif /* BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */ /* Place as higher priority for MYSQL testing */ #if !defined(WOLFSSL_MYSQL_COMPATIBLE) @@ -4028,7 +4036,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA; } #endif -#endif +#endif /* !WOLFSSL_MYSQL_COMPATIBLE */ #ifdef BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA if (tls && haveDH && haveRSA && haveAES128 && haveSHA1) { @@ -4110,7 +4118,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CHACHA_BYTE; suites->suites[idx++] = TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256; } -#endif +#endif /* BUILD_TLS_DHE_RSA_WITH_CHACHA20_OLD_POLY1305_SHA256 */ #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA if (tls && haveECC && haveNull && haveSHA1) { @@ -4143,7 +4151,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_RSA_WITH_NULL_SHA256; } -#endif +#endif /* BUILD_TLS_RSA_WITH_NULL_SHA256 */ #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA if (tls && havePSK && haveSHA1) { @@ -4162,7 +4170,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA384; } -#endif +#endif /* BUILD_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 */ #ifdef BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4174,7 +4182,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_PSK_WITH_AES_256_CBC_SHA384; } -#endif +#endif /* BUILD_TLS_PSK_WITH_AES_256_CBC_SHA384 */ #ifdef BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4186,7 +4194,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA256; } -#endif +#endif /* BUILD_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 */ #ifdef BUILD_TLS_PSK_WITH_AES_128_CBC_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4231,7 +4239,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CHACHA_BYTE; suites->suites[idx++] = TLS_PSK_WITH_CHACHA20_POLY1305_SHA256; } -#endif +#endif /* BUILD_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 */ #ifdef BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4243,7 +4251,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CHACHA_BYTE; suites->suites[idx++] = TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256; } -#endif +#endif /* BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 */ #ifdef BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4255,7 +4263,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CHACHA_BYTE; suites->suites[idx++] = TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256; } -#endif +#endif /* BUILD_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 */ #ifdef BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4267,7 +4275,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256; } -#endif +#endif /* BUILD_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 */ #ifdef BUILD_TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4279,7 +4287,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = ECDHE_PSK_BYTE; suites->suites[idx++] = TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256; } -#endif +#endif /* BUILD_TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 */ #ifdef BUILD_TLS_PSK_WITH_AES_128_CCM if (tls && havePSK && haveAES128) { @@ -4319,7 +4327,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA384; } -#endif +#endif /* BUILD_TLS_DHE_PSK_WITH_NULL_SHA384 */ #ifdef BUILD_TLS_PSK_WITH_NULL_SHA384 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4331,7 +4339,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA384; } -#endif +#endif /* BUILD_TLS_PSK_WITH_NULL_SHA384 */ #ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4343,7 +4351,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = ECC_BYTE; suites->suites[idx++] = TLS_ECDHE_PSK_WITH_NULL_SHA256; } -#endif +#endif /* BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256 */ #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4355,7 +4363,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_PSK_WITH_NULL_SHA256; } -#endif +#endif /* BUILD_TLS_DHE_PSK_WITH_NULL_SHA256 */ #ifdef BUILD_TLS_PSK_WITH_NULL_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4367,7 +4375,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_PSK_WITH_NULL_SHA256; } -#endif +#endif /* BUILD_TLS_PSK_WITH_NULL_SHA256 */ #ifdef BUILD_TLS_PSK_WITH_NULL_SHA if (tls && havePSK && haveNull) { @@ -4435,7 +4443,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256; } -#endif +#endif /* BUILD_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 */ #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4447,7 +4455,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256; } -#endif +#endif /* BUILD_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */ #ifdef BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4459,7 +4467,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256; } -#endif +#endif /* BUILD_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 */ #ifdef BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 #ifndef WOLFSSL_OLDTLS_SHA2_CIPHERSUITES @@ -4471,7 +4479,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = CIPHER_BYTE; suites->suites[idx++] = TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256; } -#endif +#endif /* BUILD_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */ #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3 if (tls && haveECC) { @@ -4479,12 +4487,14 @@ void InitSuites(Suites* suites, ProtocolVersion pv, int keySz, word16 haveRSA, suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_SM4_CBC_SM3; } #endif + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3 if (tls && haveECC) { suites->suites[idx++] = SM_BYTE; suites->suites[idx++] = TLS_ECDHE_ECDSA_WITH_SM4_GCM_SM3; } #endif + #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_SM4_CCM_SM3 if (tls && haveECC) { suites->suites[idx++] = SM_BYTE; @@ -4573,14 +4583,11 @@ void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType) } break; #endif -#if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) - case PQC_SA_MAJOR: - /* Hash performed as part of sign/verify operation. - * However, if we want a dual alg signature with a - * classic algorithm as alternative, we need an explicit - * hash algo here. - */ + /* Hash performed as part of sign/verify operation. + * However, if we want a dual alg signature with a classic algorithm as + * alternative, we need an explicit hash algo here. */ #ifdef HAVE_FALCON + case FALCON_SA_MAJOR: if (input[1] == FALCON_LEVEL1_SA_MINOR) { *hsType = falcon_level1_sa_algo; *hashAlgo = sha256_mac; @@ -4589,8 +4596,10 @@ void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType) *hsType = falcon_level5_sa_algo; *hashAlgo = sha512_mac; } + break; #endif /* HAVE_FALCON */ #ifdef HAVE_DILITHIUM + case DILITHIUM_SA_MAJOR: if (input[1] == DILITHIUM_LEVEL2_SA_MINOR) { *hsType = dilithium_level2_sa_algo; *hashAlgo = sha256_mac; @@ -4603,16 +4612,16 @@ void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType) *hsType = dilithium_level5_sa_algo; *hashAlgo = sha512_mac; } - #endif /* HAVE_DILITHIUM */ break; -#endif + #endif /* HAVE_DILITHIUM */ default: *hashAlgo = input[0]; *hsType = input[1]; break; } } -#endif /* !NO_WOLFSSL_SERVER || !NO_CERTS */ +#endif /* !NO_WOLFSSL_SERVER || !NO_CERTS || + * ( !NO_WOLFSSL_CLIENT && (!NO_DH || HAVE_ECC) ) */ #ifndef WOLFSSL_NO_TLS12 #if !defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT) @@ -4897,7 +4906,8 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) } #endif -#if !defined(WOLFSSL_NO_TLS12) && !defined(WOLFSSL_NO_CLIENT_AUTH) +#if !defined(NO_TLS) && !defined(WOLFSSL_NO_TLS12) && \ + !defined(WOLFSSL_NO_CLIENT_AUTH) static void SetDigest(WOLFSSL* ssl, int hashAlgo) { switch (hashAlgo) { @@ -4958,7 +4968,7 @@ word32 MacSize(const WOLFSSL* ssl) } #ifndef NO_RSA -#if !defined(WOLFSSL_NO_TLS12) || \ +#if !defined(NO_TLS) && !defined(WOLFSSL_NO_TLS12) || \ (defined(WC_RSA_PSS) && defined(HAVE_PK_CALLBACKS)) #if !defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT) static int TypeHash(int hashAlgo) @@ -5784,7 +5794,7 @@ int Sm2wSm3Verify(WOLFSSL* ssl, const byte* id, word32 idSz, const byte* sig, return ret; } -#endif /* WOLFSSL_SM2 */ +#endif /* WOLFSSL_SM2 && WOLFSSL_SM3 */ #ifdef HAVE_ED25519 /* Check whether the key contains a public key. @@ -5971,7 +5981,7 @@ int Ed25519Verify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* msg, } #endif /* HAVE_ED25519 */ -#ifndef WOLFSSL_NO_TLS12 +#if !defined(NO_TLS) && !defined(WOLFSSL_NO_TLS12) #ifdef HAVE_CURVE25519 #ifdef HAVE_PK_CALLBACKS @@ -6045,8 +6055,14 @@ static int X25519SharedSecret(WOLFSSL* ssl, curve25519_key* priv_key, else #endif { - ret = wc_curve25519_shared_secret_ex(priv_key, pub_key, out, outlen, - EC25519_LITTLE_ENDIAN); + #ifdef WOLFSSL_CURVE25519_BLINDING + ret = wc_curve25519_set_rng(priv_key, ssl->rng); + if (ret == 0) + #endif + { + ret = wc_curve25519_shared_secret_ex(priv_key, pub_key, out, outlen, + EC25519_LITTLE_ENDIAN); + } } /* Handle async pending response */ @@ -6108,7 +6124,7 @@ static int X25519MakeKey(WOLFSSL* ssl, curve25519_key* key, } #endif /* HAVE_CURVE25519 */ -#endif /* !WOLFSSL_NO_TLS12 */ +#endif /* !NO_TLS && !WOLFSSL_NO_TLS12 */ #ifdef HAVE_ED448 /* Check whether the key contains a public key. @@ -6905,8 +6921,8 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) * then we possibly already have a side defined. Don't overwrite unless * the context has a well defined role. */ if (newSSL || ctx->method->side != WOLFSSL_NEITHER_END) - ssl->options.side = ctx->method->side; - ssl->options.downgrade = ctx->method->downgrade; + ssl->options.side = (word16)(ctx->method->side); + ssl->options.downgrade = (word16)(ctx->method->downgrade); ssl->options.minDowngrade = ctx->minDowngrade; ssl->options.haveRSA = ctx->haveRSA; @@ -6918,7 +6934,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->options.haveDilithiumSig = ctx->haveDilithiumSig; #ifndef NO_PSK - ssl->options.havePSK = ctx->havePSK; + ssl->options.havePSK = (word16)(ctx->havePSK); ssl->options.client_psk_cb = ctx->client_psk_cb; ssl->options.server_psk_cb = ctx->server_psk_cb; ssl->options.psk_ctx = ctx->psk_ctx; @@ -7262,7 +7278,7 @@ void FreeHandshakeHashes(WOLFSSL* ssl) (defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3))) && \ !defined(WOLFSSL_NO_CLIENT_AUTH) if (ssl->hsHashes->messages != NULL) { - ForceZero(ssl->hsHashes->messages, ssl->hsHashes->length); + ForceZero(ssl->hsHashes->messages, (word32)ssl->hsHashes->length); XFREE(ssl->hsHashes->messages, ssl->heap, DYNAMIC_TYPE_HASHES); ssl->hsHashes->messages = NULL; } @@ -7285,11 +7301,13 @@ int InitHandshakeHashesAndCopy(WOLFSSL* ssl, HS_Hashes* source, /* save the original so we can put it back afterward */ tmpHashes = ssl->hsHashes; - ssl->hsHashes = NULL; + ssl->hsHashes = *destination; ret = InitHandshakeHashes(ssl); if (ret != 0) { WOLFSSL_MSG_EX("InitHandshakeHashes failed. err = %d", ret); + ssl->hsHashes = tmpHashes; /* restore hsHashes pointer to original + * before returning */ return ret; } @@ -7330,8 +7348,9 @@ int InitHandshakeHashesAndCopy(WOLFSSL* ssl, HS_Hashes* source, (defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3))) && \ !defined(WOLFSSL_NO_CLIENT_AUTH) if (ret == 0 && source->messages != NULL) { - (*destination)->messages = (byte*)XMALLOC(source->length, ssl->heap, - DYNAMIC_TYPE_HASHES); + (*destination)->messages = (byte*)XMALLOC((size_t)source->length, + ssl->heap, + (int)DYNAMIC_TYPE_HASHES); (*destination)->length = source->length; (*destination)->prevLen = source->prevLen; @@ -7340,7 +7359,7 @@ int InitHandshakeHashesAndCopy(WOLFSSL* ssl, HS_Hashes* source, } else { XMEMCPY((*destination)->messages, source->messages, - source->length); + (size_t)source->length); } } #endif @@ -7446,7 +7465,7 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) wc_MemZero_Add("ServerFinished hash", &ssl->serverFinished, TLS_FINISHED_SZ_MAX); #endif -#endif +#endif /* WOLFSSL_CHECK_MEM_ZERO */ #if defined(WOLFSSL_STATIC_MEMORY) if (ctx->heap != NULL) { @@ -7602,7 +7621,7 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) !defined(HAVE_SELFTEST) ssl->options.dhDoKeyTest = 1; #endif -#endif +#endif /* !NO_DH */ #ifdef WOLFSSL_DTLS #ifdef WOLFSSL_SCTP @@ -7646,7 +7665,7 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->IOCB_ReadCtx = &ssl->rfd; /* prevent invalid pointer access if not */ ssl->IOCB_WriteCtx = &ssl->wfd; /* correctly set */ #endif -#endif +#endif /* WOLFSSL_DTLS */ #ifndef WOLFSSL_AEAD_ONLY @@ -7660,7 +7679,7 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->hmac = Renesas_cmn_TLS_hmac; #endif #endif -#endif +#endif /* WOLFSSL_AEAD_ONLY */ #if defined(WOLFSSL_OPENVPN) && defined(HAVE_KEYING_MATERIAL) /* Save arrays by default for OpenVPN */ @@ -7701,7 +7720,7 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #ifdef WOLFSSL_TLS13_MIDDLEBOX_COMPAT ssl->options.tls13MiddleBoxCompat = 1; #endif -#endif +#endif /* WOLFSSL_TLS13 */ #ifdef HAVE_TLS_EXTENSIONS #ifdef HAVE_MAX_FRAGMENT @@ -7785,6 +7804,14 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) return MEMORY_E; } XMEMSET(ssl->param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM)); + + /* pass on PARAM flags value from ctx to ssl */ + if (wolfSSL_X509_VERIFY_PARAM_set_flags(wolfSSL_get0_param(ssl), + (unsigned long)wolfSSL_X509_VERIFY_PARAM_get_flags( + wolfSSL_CTX_get0_param(ctx))) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("ssl->param set flags error"); + return WOLFSSL_FAILURE; + } #endif if (ctx->suites == NULL) { @@ -8357,13 +8384,21 @@ void FreeKeyExchange(WOLFSSL* ssl) /* Free up all memory used by Suites structure from WOLFSSL */ void FreeSuites(WOLFSSL* ssl) { -#ifdef OPENSSL_ALL +#ifdef OPENSSL_EXTRA if (ssl->suitesStack != NULL) { /* Enough to free stack structure since WOLFSSL_CIPHER * isn't allocated separately. */ wolfSSL_sk_SSL_CIPHER_free(ssl->suitesStack); ssl->suitesStack = NULL; } + if (ssl->clSuitesStack != NULL) { + /* Enough to free stack structure since WOLFSSL_CIPHER + * isn't allocated separately. */ + wolfSSL_sk_SSL_CIPHER_free(ssl->clSuitesStack); + ssl->clSuitesStack = NULL; + } + XFREE(ssl->clSuites, ssl->heap, DYNAMIC_TYPE_SUITES); + ssl->clSuites = NULL; #endif XFREE(ssl->suites, ssl->heap, DYNAMIC_TYPE_SUITES); ssl->suites = NULL; @@ -8405,6 +8440,13 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl) } FreeSuites(ssl); FreeHandshakeHashes(ssl); +#ifdef HAVE_ECH + /* try to free the ech hashes in case we errored out */ + ssl->hsHashes = ssl->hsHashesEch; + FreeHandshakeHashes(ssl); + ssl->hsHashes = ssl->hsHashesEchInner; + FreeHandshakeHashes(ssl); +#endif XFREE(ssl->buffers.domainName.buffer, ssl->heap, DYNAMIC_TYPE_DOMAIN); /* clear keys struct after session */ @@ -8418,9 +8460,6 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl) if (ssl->options.useEch == 1) { FreeEchConfigs(ssl->echConfigs, ssl->heap); ssl->echConfigs = NULL; - /* free the ech specific hashes */ - ssl->hsHashes = ssl->hsHashesEch; - FreeHandshakeHashes(ssl); ssl->options.useEch = 0; } #endif /* HAVE_ECH */ @@ -8659,6 +8698,13 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl) #ifdef OPENSSL_EXTRA XFREE(ssl->param, ssl->heap, DYNAMIC_TYPE_OPENSSL); #endif +#if defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) + if (ssl->ocspResp) { + XFREE(ssl->ocspResp, NULL, 0); + ssl->ocspResp = NULL; + ssl->ocspRespSz = 0; + } +#endif /* defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) */ #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) while (ssl->certReqCtx != NULL) { CertReqCtx* curr = ssl->certReqCtx; @@ -8731,6 +8777,7 @@ void wolfSSL_ResourceFree(WOLFSSL* ssl) * isn't allocated separately. */ wolfSSL_sk_CIPHER_free(ssl->supportedCiphers); wolfSSL_sk_X509_pop_free(ssl->peerCertChain, NULL); + wolfSSL_sk_X509_pop_free(ssl->verifiedChain, NULL); #ifdef KEEP_OUR_CERT wolfSSL_sk_X509_pop_free(ssl->ourCertChain, NULL); #endif @@ -8866,6 +8913,10 @@ void FreeHandshakeResources(WOLFSSL* ssl) FreeKey(ssl, DYNAMIC_TYPE_FALCON, (void**)&ssl->peerFalconKey); ssl->peerFalconKeyPresent = 0; #endif /* HAVE_FALCON */ +#if defined(HAVE_DILITHIUM) + FreeKey(ssl, DYNAMIC_TYPE_DILITHIUM, (void**)&ssl->peerDilithiumKey); + ssl->peerDilithiumKeyPresent = 0; +#endif /* HAVE_DILITHIUM */ } #ifdef HAVE_ECC @@ -8982,6 +9033,14 @@ void FreeHandshakeResources(WOLFSSL* ssl) * !WOLFSSL_POST_HANDSHAKE_AUTH */ #endif /* HAVE_TLS_EXTENSIONS && !NO_TLS */ +#if defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) + if (ssl->ocspResp != NULL) { + XFREE(ssl->ocspResp, NULL, 0); + ssl->ocspResp = NULL; + ssl->ocspRespSz = 0; + } +#endif /* defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) */ + #ifdef WOLFSSL_STATIC_MEMORY /* when done with handshake decrement current handshake count */ if (ssl->heap != NULL) { @@ -9424,7 +9483,7 @@ static void DtlsMsgAssembleCompleteMessage(DtlsMsg* msg) * alignment of char. */ dtls = (DtlsHandShakeHeader*)(void *)((char *)msg->fragBucketList - + OFFSETOF(DtlsFragBucket,buf) + + WC_OFFSETOF(DtlsFragBucket,buf) - DTLS_HANDSHAKE_HEADER_SZ); msg->fragBucketList = NULL; @@ -9843,7 +9902,7 @@ int DtlsMsgPoolSend(WOLFSSL* ssl, int sendOnlyFirstPacket) WriteSEQ(ssl, epochOrder, dtls->sequence_number); DtlsSEQIncrement(ssl, epochOrder); - if ((ret = CheckAvailableSize(ssl, pool->sz)) != 0) { + if ((ret = CheckAvailableSize(ssl, (int)pool->sz)) != 0) { WOLFSSL_ERROR(ret); return ret; } @@ -10316,10 +10375,10 @@ int HashRaw(WOLFSSL* ssl, const byte* data, int sz) #if !defined(NO_SHA) && (!defined(NO_OLD_TLS) || \ defined(WOLFSSL_ALLOW_TLS_SHA1)) - wc_ShaUpdate(&ssl->hsHashes->hashSha, data, sz); + wc_ShaUpdate(&ssl->hsHashes->hashSha, data, (word32)(sz)); #endif #if !defined(NO_MD5) && !defined(NO_OLD_TLS) - wc_Md5Update(&ssl->hsHashes->hashMd5, data, sz); + wc_Md5Update(&ssl->hsHashes->hashMd5, data, (word32)(sz)); #endif if (IsAtLeastTLSv1_2(ssl)) { @@ -10639,7 +10698,7 @@ static int SendHandshakeMsg(WOLFSSL* ssl, byte* input, word32 inputSz, if (!ssl->options.buildingMsg) { /* Hash it before the loop as we modify the input with * encryption on */ - ret = HashRaw(ssl, input + rHdrSz, inputSz + hsHdrSz); + ret = HashRaw(ssl, input + rHdrSz, (int)(inputSz) + hsHdrSz); if (ret != 0) return ret; #ifdef WOLFSSL_DTLS @@ -10899,7 +10958,7 @@ void ShrinkInputBuffer(WOLFSSL* ssl, int forcedFree) if (!forcedFree && usedLength > 0) { XMEMCPY(ssl->buffers.inputBuffer.staticBuffer, ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx, - usedLength); + (size_t)(usedLength)); } ForceZero(ssl->buffers.inputBuffer.buffer, @@ -11207,7 +11266,7 @@ int GrowInputBuffer(WOLFSSL* ssl, int size, int usedLength) if (usedLength) XMEMCPY(tmp, ssl->buffers.inputBuffer.buffer + - ssl->buffers.inputBuffer.idx, usedLength); + ssl->buffers.inputBuffer.idx, (size_t)(usedLength)); if (ssl->buffers.inputBuffer.dynamicFlag) { if (IsEncryptionOn(ssl, 1)) { @@ -11888,7 +11947,7 @@ static int GetRecordHeader(WOLFSSL* ssl, word32* inOutIdx, (!ssl->options.dtls && rh->pvMinor < ssl->version.minor)) #else - rh->pvMinor < ssl->version.minor + (rh->pvMinor < ssl->version.minor) #endif )) { WOLFSSL_MSG("SSL version error"); @@ -13427,7 +13486,9 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) x509->isCa = dCert->isCA; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) + x509->basicConstCrit = dCert->extBasicConstCrit; x509->pathLength = dCert->pathLength; + x509->pathLengthSet = dCert->pathLengthSet; x509->keyUsage = dCert->extKeyUsage; x509->CRLdistSet = dCert->extCRLdistSet; @@ -13481,7 +13542,6 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) } #endif x509->basicConstSet = dCert->extBasicConstSet; - x509->basicConstCrit = dCert->extBasicConstCrit; x509->basicConstPlSet = dCert->pathLengthSet; x509->subjAltNameSet = dCert->extSubjAltNameSet; x509->subjAltNameCrit = dCert->extSubjAltNameCrit; @@ -13594,6 +13654,7 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) if (x509->sapkiDer != NULL) { XMEMCPY(x509->sapkiDer, dCert->sapkiDer, dCert->sapkiLen); x509->sapkiLen = dCert->sapkiLen; + x509->sapkiCrit = dCert->extSapkiCrit; } else { ret = MEMORY_E; @@ -13606,6 +13667,7 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) XMEMCPY(x509->altSigAlgDer, dCert->altSigAlgDer, dCert->altSigAlgLen); x509->altSigAlgLen = dCert->altSigAlgLen; + x509->altSigAlgCrit = dCert->extAltSigAlgCrit; } else { ret = MEMORY_E; @@ -13618,6 +13680,7 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) XMEMCPY(x509->altSigValDer, dCert->altSigValDer, dCert->altSigValLen); x509->altSigValLen = dCert->altSigValLen; + x509->altSigValCrit = dCert->extAltSigValCrit; } else { ret = MEMORY_E; @@ -13756,8 +13819,6 @@ static int ProcessCSR_ex(WOLFSSL* ssl, byte* input, word32* inOutIdx, #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) TLSX* ext = TLSX_Find(ssl->extensions, TLSX_STATUS_REQUEST); CertificateStatusRequest* csr; -#else - (void)idx; #endif #ifdef WOLFSSL_SMALL_STACK CertStatus* status; @@ -13786,6 +13847,8 @@ static int ProcessCSR_ex(WOLFSSL* ssl, byte* input, word32* inOutIdx, ssl->status_request = 0; break; } + #else + (void)idx; #endif #ifdef HAVE_CERTIFICATE_STATUS_REQUEST_V2 @@ -13829,7 +13892,7 @@ static int ProcessCSR_ex(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* InitOcspResponse sets single and status to response struct. */ InitOcspResponse(response, single, status, input +*inOutIdx, status_length, ssl->heap); - if (OcspResponseDecode(response, SSL_CM(ssl), ssl->heap, 0) != 0) + if (OcspResponseDecode(response, SSL_CM(ssl), ssl->heap, 0, 0) != 0) ret = BAD_CERTIFICATE_STATUS_ERROR; else if (CompareOcspReqResp(request, response) != 0) ret = BAD_CERTIFICATE_STATUS_ERROR; @@ -14021,7 +14084,7 @@ int SetupStoreCtxCallback(WOLFSSL_X509_STORE_CTX** store_pt, if (subjectCNLen > ASN_NAME_MAX-1) subjectCNLen = ASN_NAME_MAX-1; if (subjectCNLen > 0) { - XMEMCPY(domain, args->dCert->subjectCN, subjectCNLen); + XMEMCPY(domain, args->dCert->subjectCN, (size_t)(subjectCNLen)); domain[subjectCNLen] = '\0'; } } @@ -14117,8 +14180,10 @@ int SetupStoreCtxCallback(WOLFSSL_X509_STORE_CTX** store_pt, if (store != NULL) wolfSSL_X509_STORE_CTX_free(store); #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) - if (x509 != NULL) + if (x509 != NULL) { wolfSSL_X509_free(x509); + x509 = NULL; + } #endif XFREE(domain, heap, DYNAMIC_TYPE_STRING); return MEMORY_E; @@ -14544,6 +14609,7 @@ int LoadCertByIssuer(WOLFSSL_X509_STORE* store, X509_NAME* issuer, int type) if (x509 != NULL) { ret = wolfSSL_X509_STORE_add_cert(store, x509); wolfSSL_X509_free(x509); + x509 = NULL; } else { WOLFSSL_MSG("failed to load certificate"); ret = WOLFSSL_FAILURE; @@ -14889,6 +14955,7 @@ static int ProcessPeerCertCheckKey(WOLFSSL* ssl, ProcPeerCertArgs* args) break; #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT case DILITHIUM_LEVEL2k: if (ssl->options.minDilithiumKeySz < 0 || DILITHIUM_LEVEL2_KEY_SIZE @@ -14913,6 +14980,31 @@ static int ProcessPeerCertCheckKey(WOLFSSL* ssl, ProcPeerCertArgs* args) ret = DILITHIUM_KEY_SIZE_E; } break; + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ + case ML_DSA_LEVEL2k: + if (ssl->options.minDilithiumKeySz < 0 || + ML_DSA_LEVEL2_KEY_SIZE + < (word16)ssl->options.minDilithiumKeySz) { + WOLFSSL_MSG("Dilithium key size in cert chain error"); + ret = DILITHIUM_KEY_SIZE_E; + } + break; + case ML_DSA_LEVEL3k: + if (ssl->options.minDilithiumKeySz < 0 || + ML_DSA_LEVEL3_KEY_SIZE + < (word16)ssl->options.minDilithiumKeySz) { + WOLFSSL_MSG( "Dilithium key size in cert chain error"); + ret = DILITHIUM_KEY_SIZE_E; + } + break; + case ML_DSA_LEVEL5k: + if (ssl->options.minDilithiumKeySz < 0 || + ML_DSA_LEVEL5_KEY_SIZE + < (word16)ssl->options.minDilithiumKeySz) { + WOLFSSL_MSG("Dilithium key size in cert chain error"); + ret = DILITHIUM_KEY_SIZE_E; + } + break; #endif /* HAVE_DILITHIUM */ default: WOLFSSL_MSG("Key size not checked"); @@ -14995,6 +15087,25 @@ static int ProcessPeerCertsChainCRLCheck(WOLFSSL* ssl, ProcPeerCertArgs* args) } #endif +#ifdef OPENSSL_EXTRA +/* account for verify params flag set */ +static int AdjustCMForParams(WOLFSSL* ssl) +{ + int flags; + WOLFSSL_X509_VERIFY_PARAM* param; + + param = wolfSSL_get0_param(ssl); + flags = wolfSSL_X509_VERIFY_PARAM_get_flags(param); + + /* For now there is a possible contradiction of PARAM flags and store flags. + * Do not disable CRL support if it has already been enabled with store. */ + if (flags == 0) { + return WOLFSSL_SUCCESS; + } + return wolfSSL_X509_STORE_set_flags(SSL_STORE(ssl), flags); +} +#endif + int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 totalSz) { @@ -15063,6 +15174,14 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif } +#ifdef OPENSSL_EXTRA + /* account for verify params flag set */ + if (AdjustCMForParams(ssl) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Issue with updating store flags from PARAMS set"); + ERROR_OUT(WOLFSSL_FAILURE, exit_ppc); + } +#endif + switch (ssl->options.asyncState) { case TLS_ASYNC_BEGIN: @@ -15867,7 +15986,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_MSG( "\tCallback override available, will continue"); /* check if fatal error */ - args->fatal = (args->verifyErr) ? 1 : 0; + args->fatal = (args->verifyErr) ? (word16)(1) + : (word16)(0); if (args->fatal) DoCertFatalAlert(ssl, ret); } @@ -16541,9 +16661,14 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) && \ !defined(WOLFSSL_DILITHIUM_NO_VERIFY) + case ML_DSA_LEVEL2k: + case ML_DSA_LEVEL3k: + case ML_DSA_LEVEL5k: + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT case DILITHIUM_LEVEL2k: case DILITHIUM_LEVEL3k: case DILITHIUM_LEVEL5k: + #endif { int keyRet = 0; if (ssl->peerDilithiumKey == NULL) { @@ -16557,18 +16682,32 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, } if (keyRet == 0) { - if (args->dCert->keyOID == DILITHIUM_LEVEL2k) { + if (args->dCert->keyOID == ML_DSA_LEVEL2k) { keyRet = wc_dilithium_set_level( - ssl->peerDilithiumKey, 2); + ssl->peerDilithiumKey, WC_ML_DSA_44); + } + else if (args->dCert->keyOID == ML_DSA_LEVEL3k) { + keyRet = wc_dilithium_set_level( + ssl->peerDilithiumKey, WC_ML_DSA_65); + } + else if (args->dCert->keyOID == ML_DSA_LEVEL5k) { + keyRet = wc_dilithium_set_level( + ssl->peerDilithiumKey, WC_ML_DSA_87); + } + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT + else if (args->dCert->keyOID == DILITHIUM_LEVEL2k) { + keyRet = wc_dilithium_set_level( + ssl->peerDilithiumKey, WC_ML_DSA_44_DRAFT); } else if (args->dCert->keyOID == DILITHIUM_LEVEL3k) { keyRet = wc_dilithium_set_level( - ssl->peerDilithiumKey, 3); + ssl->peerDilithiumKey, WC_ML_DSA_65_DRAFT); } else if (args->dCert->keyOID == DILITHIUM_LEVEL5k) { keyRet = wc_dilithium_set_level( - ssl->peerDilithiumKey, 5); + ssl->peerDilithiumKey, WC_ML_DSA_87_DRAFT); } + #endif } if (keyRet != 0 || @@ -16726,7 +16865,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, } #endif -#ifndef WOLFSSL_NO_TLS12 +#if !defined(NO_TLS) && !defined(WOLFSSL_NO_TLS12) #if !defined(NO_WOLFSSL_CLIENT) || !defined(WOLFSSL_NO_CLIENT_AUTH) /* handle processing of certificate (11) */ @@ -16863,7 +17002,7 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, status_length, ssl->heap); response->pendingCAs = pendingCAs; if ((OcspResponseDecode(response, SSL_CM(ssl), ssl->heap, - 0) != 0) + 0, 0) != 0) || (response->responseStatus != OCSP_SUCCESSFUL) || (response->single->status->status != CERT_GOOD)) ret = BAD_CERTIFICATE_STATUS_ERROR; @@ -16943,11 +17082,11 @@ static int DoCertificateStatus(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif -#endif /* !WOLFSSL_NO_TLS12 */ +#endif /* !NO_TLS && !WOLFSSL_NO_TLS12 */ #endif /* !NO_CERTS */ -#ifndef WOLFSSL_NO_TLS12 +#if !defined(NO_TLS) && !defined(WOLFSSL_NO_TLS12) static int DoHelloRequest(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size, word32 totalSz) @@ -17556,7 +17695,7 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) } #endif } -#endif +#endif /* !NO_WOLFSSL_SERVER */ if (ssl->options.dtls) ssl->msgsReceived.got_change_cipher = 1; break; @@ -17570,7 +17709,6 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) return 0; } - int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, byte type, word32 size, word32 totalSz) { @@ -18083,8 +18221,7 @@ static int DoHandShakeMsg(WOLFSSL* ssl, byte* input, word32* inOutIdx, WOLFSSL_LEAVE("DoHandShakeMsg()", ret); return ret; } - -#endif /* !WOLFSSL_NO_TLS12 */ +#endif /* !NO_TLS && !WOLFSSL_NO_TLS12 */ #ifdef WOLFSSL_EXTRA_ALERTS int SendFatalAlertOnly(WOLFSSL *ssl, int error) @@ -19524,7 +19661,7 @@ static WC_INLINE int EncryptDo(WOLFSSL* ssl, byte* out, const byte* input, additionalSz = writeAeadAuthData(ssl, /* Length of the plain text minus the explicit * IV length minus the authentication tag size. */ - sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, type, + sz - (word16)(AESGCM_EXP_IV_SZ) - ssl->specs.aead_mac_size, type, ssl->encrypt.additional, 0, NULL, CUR_ORDER); if (additionalSz < 0) { ret = additionalSz; @@ -19548,19 +19685,19 @@ static WC_INLINE int EncryptDo(WOLFSSL* ssl, byte* out, const byte* input, ssl->encrypt.nonce, AESGCM_NONCE_SZ, out + sz - ssl->specs.aead_mac_size, ssl->specs.aead_mac_size, - ssl->encrypt.additional, additionalSz); + ssl->encrypt.additional, (word32)(additionalSz)); } if (ret == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) #endif /* HAVE_PK_CALLBACKS */ { ret = aes_auth_fn(ssl->encrypt.aes, - out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ, - sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, - ssl->encrypt.nonce, AESGCM_NONCE_SZ, - out + sz - ssl->specs.aead_mac_size, - ssl->specs.aead_mac_size, - ssl->encrypt.additional, additionalSz); + out + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ, + sz - (word16)(AESGCM_EXP_IV_SZ) - ssl->specs.aead_mac_size, + ssl->encrypt.nonce, AESGCM_NONCE_SZ, + out + sz - ssl->specs.aead_mac_size, + ssl->specs.aead_mac_size, + ssl->encrypt.additional, (word32)(additionalSz)); } #ifdef WOLFSSL_ASYNC_CRYPT @@ -20016,24 +20153,24 @@ static WC_INLINE int DecryptDo(WOLFSSL* ssl, byte* plain, const byte* input, ret = ssl->ctx->PerformTlsRecordProcessingCb(ssl, 0, plain + AESGCM_EXP_IV_SZ, input + AESGCM_EXP_IV_SZ, - sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, + sz - (word16)(AESGCM_EXP_IV_SZ) - ssl->specs.aead_mac_size, ssl->decrypt.nonce, AESGCM_NONCE_SZ, (byte *)(input + sz - ssl->specs.aead_mac_size), ssl->specs.aead_mac_size, - ssl->decrypt.additional, additionalSz); + ssl->decrypt.additional, (word32)(additionalSz)); } if (ret == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) #endif /* HAVE_PK_CALLBACKS */ { if ((ret = aes_auth_fn(ssl->decrypt.aes, - plain + AESGCM_EXP_IV_SZ, - input + AESGCM_EXP_IV_SZ, - sz - AESGCM_EXP_IV_SZ - ssl->specs.aead_mac_size, - ssl->decrypt.nonce, AESGCM_NONCE_SZ, - input + sz - ssl->specs.aead_mac_size, - ssl->specs.aead_mac_size, - ssl->decrypt.additional, additionalSz)) < 0) { + plain + AESGCM_EXP_IV_SZ, + input + AESGCM_EXP_IV_SZ, + sz - (word16)(AESGCM_EXP_IV_SZ) - ssl->specs.aead_mac_size, + ssl->decrypt.nonce, AESGCM_NONCE_SZ, + input + sz - ssl->specs.aead_mac_size, + ssl->specs.aead_mac_size, + ssl->decrypt.additional, (word32)(additionalSz))) < 0) { #ifdef WOLFSSL_ASYNC_CRYPT if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) { ret = wolfSSL_AsyncPush(ssl, @@ -20794,7 +20931,7 @@ static byte MaskMac(const byte* data, int sz, int macSz, byte* expMac) r = (macSz - (scanStart - macStart)) % WC_SHA384_DIGEST_SIZE; #endif - XMEMSET(mac, 0, macSz); + XMEMSET(mac, 0, (size_t)(macSz)); for (i = scanStart; i < sz; i += macSz) { for (j = 0; j < macSz && j + i < sz; j++) { started = ctMaskGTE(i + j, macStart); @@ -20881,6 +21018,16 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx, int sniff) isEarlyData = isEarlyData && w64Equal(ssl->keys.curEpoch64, w64From32(0x0, DTLS13_EPOCH_EARLYDATA)); #endif +#ifdef WOLFSSL_DTLS13 + /* Application data should never appear in epoch 0 or 2 */ + if (ssl->options.tls1_3 && ssl->options.dtls && + (w64Equal(ssl->keys.curEpoch64, w64From32(0x0, DTLS13_EPOCH_HANDSHAKE)) + || w64Equal(ssl->keys.curEpoch64, w64From32(0x0, 0x0)))) + { + WOLFSSL_ERROR_VERBOSE(SANITY_MSG_E); + return SANITY_MSG_E; + } +#endif #ifdef WOLFSSL_EARLY_DATA if (isEarlyData && acceptEarlyData) { @@ -20945,7 +21092,7 @@ int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx, int sniff) } #endif - dataSz = msgSz - ssl->keys.padSz; + dataSz = (int)(msgSz - ssl->keys.padSz); if (dataSz < 0) { WOLFSSL_MSG("App data buffer error, malicious input?"); if (sniff == NO_SNIFF) { @@ -21150,6 +21297,13 @@ const char* AlertTypeToString(int type) return internal_error_str; } + case inappropriate_fallback: + { + static const char inappropriate_fallback_str[] = + "inappropriate_fallback"; + return inappropriate_fallback_str; + } + case user_canceled: { static const char user_canceled_str[] = @@ -21164,6 +21318,20 @@ const char* AlertTypeToString(int type) return no_renegotiation_str; } + case missing_extension: + { + static const char missing_extension_str[] = + "missing_extension"; + return missing_extension_str; + } + + case unsupported_extension: + { + static const char unsupported_extension_str[] = + "unsupported_extension"; + return unsupported_extension_str; + } + case unrecognized_name: { static const char unrecognized_name_str[] = @@ -21178,6 +21346,20 @@ const char* AlertTypeToString(int type) return bad_certificate_status_response_str; } + case unknown_psk_identity: + { + static const char unknown_psk_identity_str[] = + "unknown_psk_identity"; + return unknown_psk_identity_str; + } + + case certificate_required: + { + static const char certificate_required_str[] = + "certificate_required"; + return certificate_required_str; + } + case no_application_protocol: { static const char no_application_protocol_str[] = @@ -21335,7 +21517,7 @@ static int GetInputData(WOLFSSL *ssl, word32 size) if (usedLength > 0 && ssl->buffers.inputBuffer.idx != 0) XMEMMOVE(ssl->buffers.inputBuffer.buffer, ssl->buffers.inputBuffer.buffer + ssl->buffers.inputBuffer.idx, - usedLength); + (size_t)(usedLength)); /* remove processed data */ ssl->buffers.inputBuffer.idx = 0; @@ -21395,6 +21577,7 @@ static WC_INLINE int VerifyMacEnc(WOLFSSL* ssl, const byte* input, word32 msgSz, WOLFSSL_ERROR_VERBOSE(VERIFY_MAC_ERROR); return VERIFY_MAC_ERROR; } + XMEMSET(verify, 0, WC_MAX_DIGEST_SIZE); ret = ssl->hmac(ssl, verify, input, msgSz - digestSz, -1, content, 1, PEER_ORDER); ret |= ConstantCompare(verify, input + msgSz - digestSz, (int)digestSz); @@ -21417,7 +21600,7 @@ static WC_INLINE int VerifyMac(WOLFSSL* ssl, const byte* input, word32 msgSz, word32 digestSz = MacSize(ssl); byte verify[WC_MAX_DIGEST_SIZE]; - + XMEMSET(verify, 0, WC_MAX_DIGEST_SIZE); if (ssl->specs.cipher_type == block) { pad = input[msgSz - 1]; padByte = 1; @@ -22918,7 +23101,8 @@ int SendChangeCipher(WOLFSSL* ssl) else return SendBuffered(ssl); } -#endif +#endif /* !WOLFSSL_NO_TLS12 || !NO_OLD_TLS || + * (WOLFSSL_TLS13 && WOLFSSL_TLS13_MIDDLEBOX_COMPAT) */ #if !defined(NO_OLD_TLS) && !defined(WOLFSSL_AEAD_ONLY) @@ -23481,7 +23665,7 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, min(args->ivSz, MAX_IV_SZ)); args->idx += min(args->ivSz, MAX_IV_SZ); } - XMEMCPY(output + args->idx, input, inSz); + XMEMCPY(output + args->idx, input, (size_t)(inSz)); args->idx += (word32)inSz; #if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_CID) if (ssl->options.dtls && DtlsGetCidTxSize(ssl) > 0) { @@ -23995,7 +24179,7 @@ int CreateOcspRequest(WOLFSSL* ssl, OcspRequest* request, ret = InitOcspRequest(request, cert, 0, ssl->heap); if (ret == 0) { /* make sure ctx OCSP request is updated */ - if (!ssl->buffers.weOwnCert) { + if (!ssl->buffers.weOwnCert && SSL_CM(ssl) != NULL) { wolfSSL_Mutex* ocspLock = &SSL_CM(ssl)->ocsp_stapling->ocspLock; if (wc_LockMutex(ocspLock) == 0) { if (ssl->ctx->certOcspRequest == NULL) { @@ -24143,7 +24327,9 @@ int cipherExtraData(WOLFSSL* ssl) #ifndef WOLFSSL_NO_TLS12 #ifndef NO_CERTS -#if !defined(NO_WOLFSSL_SERVER) || !defined(WOLFSSL_NO_CLIENT_AUTH) + +#if (!defined(NO_WOLFSSL_SERVER) || !defined(WOLFSSL_NO_CLIENT_AUTH)) && \ + !defined(NO_TLS) /* handle generation of certificate (11) */ int SendCertificate(WOLFSSL* ssl) { @@ -24250,12 +24436,12 @@ int SendCertificate(WOLFSSL* ssl) else { fragSz = maxFragment - HANDSHAKE_HEADER_SZ; } - sendSz += fragSz + HANDSHAKE_HEADER_SZ; + sendSz += (int)(fragSz) + HANDSHAKE_HEADER_SZ; i += HANDSHAKE_HEADER_SZ; } else { fragSz = min(length, maxFragment); - sendSz += fragSz; + sendSz += (int)(fragSz); } if (IsEncryptionOn(ssl, 1)) @@ -24384,7 +24570,7 @@ int SendCertificate(WOLFSSL* ssl) DYNAMIC_TYPE_IN_BUFFER); if (input == NULL) return MEMORY_E; - XMEMCPY(input, output + recordHeaderSz, inputSz); + XMEMCPY(input, output + recordHeaderSz, (size_t)(inputSz)); } #ifndef WOLFSSL_DTLS @@ -24456,8 +24642,9 @@ int SendCertificate(WOLFSSL* ssl) return ret; } -#endif /* !NO_WOLFSSL_SERVER || !WOLFSSL_NO_CLIENT_AUTH */ +#endif /* !NO_TLS && (!NO_WOLFSSL_SERVER || !WOLFSSL_NO_CLIENT_AUTH) */ +#if !defined(NO_TLS) /* handle generation of certificate_request (13) */ int SendCertificateRequest(WOLFSSL* ssl) { @@ -24611,7 +24798,7 @@ int SendCertificateRequest(WOLFSSL* ssl) if (input == NULL) return MEMORY_E; - XMEMCPY(input, output + recordHeaderSz, inputSz); + XMEMCPY(input, output + recordHeaderSz, (size_t)(inputSz)); #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl) && (ret = DtlsMsgPoolSave(ssl, input, (word32)inputSz, @@ -24665,8 +24852,11 @@ int SendCertificateRequest(WOLFSSL* ssl) return ret; } +#endif /* !NO_TLS */ + #ifndef NO_WOLFSSL_SERVER + #if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \ || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status, @@ -24736,6 +24926,53 @@ static int BuildCertificateStatus(WOLFSSL* ssl, byte type, buffer* status, return ret; } #endif + +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \ + (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ + defined(WOLFSSL_HAPROXY)) +static int BuildCertificateStatusWithStatusCB(WOLFSSL* ssl) +{ + WOLFSSL_OCSP *ocsp; + void *ioCtx = NULL; + buffer response; + int ret; + + if (ssl == NULL) { + return BAD_FUNC_ARG; + } + + ocsp = SSL_CM(ssl)->ocsp_stapling; + if (ocsp == NULL || ocsp->statusCb == NULL) + return BAD_FUNC_ARG; + ioCtx = (ssl->ocspIOCtx != NULL) ? ssl->ocspIOCtx : ocsp->cm->ocspIOCtx; + XMEMSET(&response, 0, sizeof(response)); + WOLFSSL_MSG("Calling ocsp->statusCb"); + ret = ocsp->statusCb(ssl, ioCtx); + switch (ret) { + case SSL_TLSEXT_ERR_OK: + if (ssl->ocspResp == NULL || ssl->ocspRespSz == 0) { + ret = 0; + break; + } + response.buffer = ssl->ocspResp; + response.length = ssl->ocspRespSz; + ret = BuildCertificateStatus(ssl, WOLFSSL_CSR_OCSP, &response, 1); + break; + case SSL_TLSEXT_ERR_NOACK: + /* No OCSP response to send */ + ret = 0; + break; + case SSL_TLSEXT_ERR_ALERT_FATAL: + /* fall through */ + default: + ret = WOLFSSL_FATAL_ERROR; + break; + } + return ret; +} +#endif /* HAVE_CERTIFICATE_STATUS_REQUEST && (defined(OPENSSL_ALL) || + defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) */ + #endif /* NO_WOLFSSL_SERVER */ /* handle generation of certificate_status (22) */ @@ -24747,7 +24984,10 @@ int SendCertificateStatus(WOLFSSL* ssl) WOLFSSL_START(WC_FUNC_CERTIFICATE_STATUS_SEND); WOLFSSL_ENTER("SendCertificateStatus"); - (void) ssl; + if (ssl == NULL || SSL_CM(ssl) == NULL) { + WOLFSSL_MSG("SendCertificateStatus bad args"); + return BAD_FUNC_ARG; + } #ifdef HAVE_CERTIFICATE_STATUS_REQUEST status_type = ssl->status_request; @@ -24757,6 +24997,16 @@ int SendCertificateStatus(WOLFSSL* ssl) status_type = status_type ? status_type : ssl->status_request_v2; #endif +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) && \ + (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ + defined(WOLFSSL_HAPROXY)) + if (SSL_CM(ssl)->ocsp_stapling != NULL && + SSL_CM(ssl)->ocsp_stapling->statusCb != NULL) { + if (ssl->status_request == WOLFSSL_CSR_OCSP) + return BuildCertificateStatusWithStatusCB(ssl); + } +#endif + switch (status_type) { #ifndef NO_WOLFSSL_SERVER @@ -25032,7 +25282,8 @@ static int ModifyForMTU(WOLFSSL* ssl, int buffSz, int outputSz, int mtuSz) } #endif /* WOLFSSL_DTLS */ -#if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_TLS13_IGNORE_AEAD_LIMITS) +#if !defined(NO_TLS) && defined(WOLFSSL_TLS13) && \ + !defined(WOLFSSL_TLS13_IGNORE_AEAD_LIMITS) /* * Enforce limits specified in * https://www.rfc-editor.org/rfc/rfc8446#section-5.5 @@ -25164,10 +25415,12 @@ int SendAsyncData(WOLFSSL* ssl) * 2 in SCR and we have plain data ready * Early data logic may bypass this logic in TLSv1.3 when appropriate. */ -static int ssl_in_handshake(WOLFSSL *ssl, int send) +static int ssl_in_handshake(WOLFSSL *ssl, int sending_data) { +int SendAsyncData = 1; +(void)SendAsyncData; if (IsSCR(ssl)) { - if (send) { + if (sending_data) { /* allow sending data in SCR */ return 0; } else { @@ -25200,16 +25453,21 @@ static int ssl_in_handshake(WOLFSSL *ssl, int send) return 0; } -int SendData(WOLFSSL* ssl, const void* data, int sz) +int SendData(WOLFSSL* ssl, const void* data, size_t sz) { - int sent = 0, /* plainText size */ - sendSz, + word32 sent = 0; /* plainText size */ + int sendSz, ret; #if defined(WOLFSSL_EARLY_DATA) && defined(WOLFSSL_EARLY_DATA_GROUP) int groupMsgs = 0; #endif int error = ssl->error; + if (sz > INT_MAX) { + WOLFSSL_MSG("SendData sz overflow"); + return WOLFSSL_FATAL_ERROR; + } + if (error == WC_NO_ERR_TRACE(WANT_WRITE) #ifdef WOLFSSL_ASYNC_CRYPT || error == WC_NO_ERR_TRACE(WC_PENDING_E) @@ -25314,7 +25572,7 @@ int SendData(WOLFSSL* ssl, const void* data, int sz) sent = ssl->buffers.prevSent + ssl->buffers.plainSz; WOLFSSL_MSG("sent write buffered data"); - if (sent > sz) { + if (sent > (word32)sz) { WOLFSSL_MSG("error: write() after WANT_WRITE with short size"); return (ssl->error = BAD_FUNC_ARG); } @@ -25403,19 +25661,19 @@ int SendData(WOLFSSL* ssl, const void* data, int sz) #ifdef WOLFSSL_DTLS if (ssl->options.dtls) { - buffSz = wolfSSL_GetMaxFragSize(ssl, sz - sent); + buffSz = wolfSSL_GetMaxFragSize(ssl, (word32)sz - sent); } else #endif { - buffSz = wolfSSL_GetMaxFragSize(ssl, sz - sent); + buffSz = wolfSSL_GetMaxFragSize(ssl, (word32)sz - sent); } - if (sent == sz) break; + if (sent == (word32)sz) break; #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_DTLS_SIZE_CHECK) - if (ssl->options.dtls && (buffSz < sz - sent)) { + if (ssl->options.dtls && ((size_t)buffSz < (word32)sz - sent)) { error = DTLS_SIZE_ERROR; ssl->error = error; WOLFSSL_ERROR(error); @@ -25571,6 +25829,9 @@ int SendData(WOLFSSL* ssl, const void* data, int sz) } return error; } + else { + ssl->error = 0; /* Clear any previous errors */ + } sent += buffSz; @@ -25586,13 +25847,18 @@ int SendData(WOLFSSL* ssl, const void* data, int sz) } /* process input data */ -int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek) +int ReceiveData(WOLFSSL* ssl, byte* output, size_t sz, int peek) { int size; int error = ssl->error; WOLFSSL_ENTER("ReceiveData"); + if (sz > INT_MAX) { + WOLFSSL_MSG("ReceiveData sz overflow"); + return WOLFSSL_FATAL_ERROR; + } + /* reset error state */ if (error == WC_NO_ERR_TRACE(WANT_READ) || error == WOLFSSL_ERROR_WANT_READ) { @@ -25742,9 +26008,10 @@ int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek) #endif } - size = (int)min((word32)sz, ssl->buffers.clearOutputBuffer.length); + size = (sz < (size_t)ssl->buffers.clearOutputBuffer.length) ? + (int)sz : (int)ssl->buffers.clearOutputBuffer.length; - XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, size); + XMEMCPY(output, ssl->buffers.clearOutputBuffer.buffer, (size_t)(size)); if (peek == 0) { ssl->buffers.clearOutputBuffer.length -= (word32)size; @@ -25766,10 +26033,19 @@ static int SendAlert_ex(WOLFSSL* ssl, int severity, int type) int ret; int outputSz; int dtlsExtra = 0; + const char* alert_str = NULL; WOLFSSL_ENTER("SendAlert"); - WOLFSSL_MSG_EX("SendAlert: %d %s", type, AlertTypeToString(type)); + alert_str = AlertTypeToString(type); + if (alert_str != NULL) + { + WOLFSSL_MSG_EX("SendAlert: %d %s", type, alert_str); + } + else + { + WOLFSSL_MSG_EX("SendAlert: %d", type); + } #ifdef WOLFSSL_QUIC if (WOLFSSL_IS_QUIC(ssl)) { @@ -27708,6 +27984,7 @@ static int ParseCipherList(Suites* suites, } if (currLen == 0) break; + ++next; /* increment to skip ':' */ } #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) @@ -28059,8 +28336,7 @@ static int ParseCipherList(Suites* suites, break; } } - } - while (next++); /* increment to skip ':' */ + } while (next); if (ret) { int keySz = 0; @@ -28294,7 +28570,7 @@ int SetCipherListFromBytes(WOLFSSL_CTX* ctx, Suites* suites, const byte* list, return ret; } -#endif /* OPENSSL_EXTRA */ +#endif /* OPENSSL_EXTRA || WOLFSSL_SET_CIPHER_BYTES */ #ifdef OPENSSL_EXTRA @@ -28487,6 +28763,7 @@ static int MatchSigAlgo(WOLFSSL* ssl, int sigAlgo) } #endif /* HAVE_FALCON */ #ifdef HAVE_DILITHIUM + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT if (ssl->pkCurveOID == CTC_DILITHIUM_LEVEL2) { /* Certificate has Dilithium level 2 key, only match with it. */ return sigAlgo == dilithium_level2_sa_algo; @@ -28499,6 +28776,19 @@ static int MatchSigAlgo(WOLFSSL* ssl, int sigAlgo) /* Certificate has Dilithium level 5 key, only match with it. */ return sigAlgo == dilithium_level5_sa_algo; } + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ + if (ssl->pkCurveOID == CTC_ML_DSA_LEVEL2) { + /* Certificate has ML-DSA level 2 key, only match with it. */ + return sigAlgo == dilithium_level2_sa_algo; + } + if (ssl->pkCurveOID == CTC_ML_DSA_LEVEL3) { + /* Certificate has ML-DSA level 3 key, only match with it. */ + return sigAlgo == dilithium_level3_sa_algo; + } + if (ssl->pkCurveOID == CTC_ML_DSA_LEVEL5) { + /* Certificate has ML-DSA level 5 key, only match with it. */ + return sigAlgo == dilithium_level5_sa_algo; + } #endif /* HAVE_DILITHIUM */ #ifdef WC_RSA_PSS /* RSA certificate and PSS sig alg. */ @@ -28661,10 +28951,16 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz, } #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) - if (ssl->pkCurveOID == CTC_DILITHIUM_LEVEL2 || - ssl->pkCurveOID == CTC_DILITHIUM_LEVEL3 || - ssl->pkCurveOID == CTC_DILITHIUM_LEVEL5) { - /* Matched Dilithium - set chosen and finished. */ + if (ssl->pkCurveOID == CTC_ML_DSA_LEVEL2 || + ssl->pkCurveOID == CTC_ML_DSA_LEVEL3 || + ssl->pkCurveOID == CTC_ML_DSA_LEVEL5 + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT + || ssl->pkCurveOID == CTC_DILITHIUM_LEVEL2 + || ssl->pkCurveOID == CTC_DILITHIUM_LEVEL3 + || ssl->pkCurveOID == CTC_DILITHIUM_LEVEL5 + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ + ) { + /* Matched ML-DSA or Dilithium - set chosen and finished. */ ssl->options.sigAlgo = sigAlgo; ssl->options.hashAlgo = hashAlgo; ret = 0; @@ -29010,7 +29306,7 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz, return 0; } -#endif /* WOLFSSL_CALLBACKS */ +#endif /* WOLFSSL_CALLBACKS || OPENSSL_EXTRA */ #if !defined(NO_CERTS) @@ -29183,7 +29479,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word32* length) (ssl->buffers.keyType == dilithium_level3_sa_algo) || (ssl->buffers.keyType == dilithium_level5_sa_algo)) ssl->hsType = DYNAMIC_TYPE_DILITHIUM; - ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey); + ret = AllocKey(ssl, (int)(ssl->hsType), &ssl->hsKey); if (ret != 0) { goto exit_dpk; } @@ -29197,9 +29493,10 @@ int DecodePrivateKey(WOLFSSL *ssl, word32* length) } else if (ssl->buffers.keyId) { ret = wc_InitRsaKey_Id((RsaKey*)ssl->hsKey, - ssl->buffers.key->buffer, - ssl->buffers.key->length, ssl->heap, - ssl->buffers.keyDevId); + (ssl->buffers.key->buffer), + (int)(ssl->buffers.key->length), + ssl->heap, + ssl->buffers.keyDevId); } if (ret == 0) { if (ssl->buffers.keySz < ssl->options.minRsaKeySz) { @@ -29223,7 +29520,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word32* length) } else if (ssl->buffers.keyId) { ret = wc_ecc_init_id((ecc_key*)ssl->hsKey, - ssl->buffers.key->buffer, + (ssl->buffers.key->buffer), ssl->buffers.key->length, ssl->heap, ssl->buffers.keyDevId); } @@ -29292,13 +29589,13 @@ int DecodePrivateKey(WOLFSSL *ssl, word32* length) } if (ret == 0) { if (ssl->buffers.keyType == dilithium_level2_sa_algo) { - ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, 2); + ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, WC_ML_DSA_44); } else if (ssl->buffers.keyType == dilithium_level3_sa_algo) { - ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, 3); + ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, WC_ML_DSA_65); } else if (ssl->buffers.keyType == dilithium_level5_sa_algo) { - ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, 5); + ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, WC_ML_DSA_87); } } if (ret == 0) { @@ -29632,13 +29929,13 @@ int DecodePrivateKey(WOLFSSL *ssl, word32* length) } if (ssl->buffers.keyType == dilithium_level2_sa_algo) { - ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, 2); + ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, WC_ML_DSA_44); } else if (ssl->buffers.keyType == dilithium_level3_sa_algo) { - ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, 3); + ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, WC_ML_DSA_65); } else if (ssl->buffers.keyType == dilithium_level5_sa_algo) { - ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, 5); + ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, WC_ML_DSA_87); } else { /* What if ssl->buffers.keyType is 0? We might want to do something @@ -29845,15 +30142,15 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length) if (ret == 0) { if (ssl->buffers.altKeyType == dilithium_level2_sa_algo) { ret = wc_dilithium_set_level( - (dilithium_key*)ssl->hsAltKey, 2); + (dilithium_key*)ssl->hsAltKey, WC_ML_DSA_44); } else if (ssl->buffers.altKeyType == dilithium_level3_sa_algo) { ret = wc_dilithium_set_level( - (dilithium_key*)ssl->hsAltKey, 3); + (dilithium_key*)ssl->hsAltKey, WC_ML_DSA_65); } else if (ssl->buffers.altKeyType == dilithium_level5_sa_algo) { ret = wc_dilithium_set_level( - (dilithium_key*)ssl->hsAltKey, 5); + (dilithium_key*)ssl->hsAltKey, WC_ML_DSA_87); } } if (ret == 0) { @@ -30064,13 +30361,13 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length) } if (ssl->buffers.altKeyType == dilithium_level2_sa_algo) { - ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey, 2); + ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey, WC_ML_DSA_44); } else if (ssl->buffers.altKeyType == dilithium_level3_sa_algo) { - ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey, 3); + ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey, WC_ML_DSA_65); } else if (ssl->buffers.altKeyType == dilithium_level5_sa_algo) { - ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey, 5); + ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey, WC_ML_DSA_87); } else { /* What if ssl->buffers.keyType is 0? We might want to do something @@ -30139,7 +30436,8 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length) return ret; } #endif /* WOLFSSL_DUAL_ALG_CERTS */ -#endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */ + +#endif /* !NO_CERTS */ #if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_TLS12) /* returns 1 if able to do TLS 1.3 otherwise 0 */ @@ -30164,7 +30462,7 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length) } #endif /* WOLFSSL_TLS13 */ -#ifndef WOLFSSL_NO_TLS12 +#if !defined(NO_TLS) && !defined(WOLFSSL_NO_TLS12) #if (!defined(NO_WOLFSSL_CLIENT) && (!defined(NO_DH) || defined(HAVE_ECC) || \ defined(HAVE_CURVE25519) || defined(HAVE_CURVE448))) || \ (!defined(NO_WOLFSSL_SERVER) && (defined(HAVE_ECC) || \ @@ -30275,8 +30573,8 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, return ret; } -#endif -#endif /* !WOLFSSL_NO_TLS12 */ +#endif /* !NO_WOLFSSL_CLIENT [...etc] || !NO_WOLFSSL_SERVER [...etc] */ +#endif /* !NO_TLS && !WOLFSSL_NO_TLS12 */ /* client only parts */ #if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS) @@ -30352,7 +30650,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, idSz = 0; } -#endif +#endif /* HAVE_SESSION_TICKET */ length = VERSION_SZ + RAN_LEN + (word32)idSz + ENUM_LEN + SUITE_LEN @@ -30383,7 +30681,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, #endif if (extSz != 0) length += extSz + HELLO_EXT_SZ_SZ; -#endif +#endif /* HAVE_TLS_EXTENSIONS */ sendSz = (int)length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; if (ssl->arrays == NULL) { @@ -30455,7 +30753,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, idx += cookieSz; } } -#endif +#endif /* WOLFSSL_DTLS */ #ifndef NO_FORCE_SCR_SAME_SUITE if (IsSCR(ssl)) { @@ -30465,7 +30763,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, output[idx++] = ssl->options.cipherSuite; } else -#endif +#endif /* NO_FORCE_SCR_SAME_SUITE */ { /* then cipher suites */ c16toa(suites->suiteSz, output + idx); @@ -30491,7 +30789,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, (void)idx; /* suppress analyzer warning, keep idx current */ #else if (extSz != 0) { - c16toa(extSz, output + idx); + c16toa((word16)(extSz), output + idx); idx += HELLO_EXT_SZ_SZ; if (IsAtLeastTLSv1_2(ssl)) { @@ -30521,7 +30819,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, } #endif } -#endif +#endif /* HAVE_TLS_EXTENSIONS */ if (IsEncryptionOn(ssl, 1)) { byte* input; @@ -30536,7 +30834,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, if (input == NULL) return MEMORY_E; - XMEMCPY(input, output + recordHeaderSz, inputSz); + XMEMCPY(input, output + recordHeaderSz, (size_t)(inputSz)); #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl) && (ret = DtlsMsgPoolSave(ssl, input, (word32)inputSz, @@ -30671,7 +30969,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, && ssl->session->ticketLen > 0 #endif ); -#endif +#endif /* HAVE_SECRET_CALLBACK */ #ifdef HAVE_SESSION_TICKET /* server may send blank ticket which may not be expected to indicate @@ -30705,11 +31003,11 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, } #endif - #ifdef OPENSSL_EXTRA + #ifdef OPENSSL_EXTRA if (ssl->CBIS != NULL) { ssl->CBIS(ssl, WOLFSSL_CB_HANDSHAKE_START, WOLFSSL_SUCCESS); } - #endif + #endif if (ssl->options.dtls) { if (pv.major != DTLS_MAJOR || pv.minor == DTLS_BOGUS_MINOR) { @@ -30757,7 +31055,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, WOLFSSL_ERROR_VERBOSE(VERSION_ERROR); return VERSION_ERROR; } - #endif + #endif /* HAVE_SECURE_RENEGOTIATION */ /* Checks made - OK to downgrade. */ ssl->version.minor = pv.minor; @@ -30921,7 +31219,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, } } else -#endif +#endif /* HAVE_SECURE_RENEGOTIATION && !NO_FORCE_SCR_SAME_SUITE */ { word32 idx, found = 0; const Suites* suites = WOLFSSL_SUITES(ssl); @@ -30991,6 +31289,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, else ssl->options.haveEMS = 0; /* If no extensions, no EMS */ #else + /* !HAVE_TLS_EXTENSIONS */ { byte pendingEMS = 0; @@ -31038,7 +31337,9 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, else i += extSz; - totalExtSz -= OPAQUE16_LEN + OPAQUE16_LEN + extSz; + totalExtSz -= (word16)(OPAQUE16_LEN) + + (word16)(OPAQUE16_LEN) + + extSz; } *inOutIdx = i; @@ -31050,7 +31351,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, if (!pendingEMS && ssl->options.haveEMS) ssl->options.haveEMS = 0; } -#endif +#endif /* HAVE_TLS_EXTENSIONS */ #if defined(WOLFSSL_HARDEN_TLS) && !defined(WOLFSSL_HARDEN_TLS_NO_SCR_CHECK) if (ssl->secure_renegotiation == NULL || @@ -31115,7 +31416,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, } } else - #endif + #endif /* WOLFSSL_TLS13 */ if (ssl->ctx->method->version.major == SSLv3_MAJOR && ssl->ctx->method->version.minor == TLSv1_2_MINOR && (wolfSSL_get_options(ssl) & WOLFSSL_OP_NO_TLSv1_2) == 0) { @@ -31350,7 +31651,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, #endif *inOutIdx += dnSz; - len -= OPAQUE16_LEN + dnSz; + len -= (word16)(OPAQUE16_LEN) + dnSz; } #ifdef OPENSSL_EXTRA @@ -31366,6 +31667,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, return CLIENT_CERT_CB_ERROR; } wolfSSL_X509_free(x509); + x509 = NULL; wolfSSL_EVP_PKEY_free(pkey); } @@ -31862,7 +32164,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, /* get PSK server hint from the wire */ srvHintLen = (int)min(length, MAX_PSK_ID_LEN); XMEMCPY(ssl->arrays->server_hint, input + args->idx, - srvHintLen); + (size_t)(srvHintLen)); ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */ args->idx += length; break; @@ -32082,7 +32384,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, /* get PSK server hint from the wire */ srvHintLen = (int)min(length, MAX_PSK_ID_LEN); XMEMCPY(ssl->arrays->server_hint, input + args->idx, - srvHintLen); + (size_t)(srvHintLen)); ssl->arrays->server_hint[srvHintLen] = '\0'; /* null term */ args->idx += length; @@ -32998,7 +33300,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) /* create private key */ ssl->hsType = DYNAMIC_TYPE_CURVE25519; - ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey); + ret = AllocKey(ssl, (int)(ssl->hsType), &ssl->hsKey); if (ret != 0) { goto exit_scke; } @@ -33049,7 +33351,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) /* create ephemeral private key */ ssl->hsType = DYNAMIC_TYPE_ECC; - ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey); + ret = AllocKey(ssl, (int)(ssl->hsType), &ssl->hsKey); if (ret != 0) { goto exit_scke; } @@ -33100,7 +33402,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) /* create private key */ ssl->hsType = DYNAMIC_TYPE_CURVE25519; - ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey); + ret = AllocKey(ssl, (int)(ssl->hsType), &ssl->hsKey); if (ret != 0) { goto exit_scke; } @@ -34837,7 +35139,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif /* WOLF_PRIVATE_KEY_ID || HAVE_PK_CALLBACKS */ -#endif /* NO_CERTS */ +#endif /* !NO_CERTS */ #ifdef HAVE_ECC /* returns the WOLFSSL_* version of the curve from the OID sum */ @@ -34924,6 +35226,57 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif /* HAVE_ECC */ +#ifdef WOLFSSL_HAVE_MLKEM + /* Returns 1 when the given group is a PQC group, 0 otherwise. */ + int NamedGroupIsPqc(int group) + { + switch (group) { + #ifndef WOLFSSL_NO_ML_KEM + case WOLFSSL_ML_KEM_512: + case WOLFSSL_ML_KEM_768: + case WOLFSSL_ML_KEM_1024: + #endif + #ifdef WOLFSSL_MLKEM_KYBER + case WOLFSSL_KYBER_LEVEL1: + case WOLFSSL_KYBER_LEVEL3: + case WOLFSSL_KYBER_LEVEL5: + #endif + return 1; + default: + return 0; + } + } + + /* Returns 1 when the given group is a PQC hybrid group, 0 otherwise. */ + int NamedGroupIsPqcHybrid(int group) + { + switch (group) { + #ifndef WOLFSSL_NO_ML_KEM + case WOLFSSL_P256_ML_KEM_768: + case WOLFSSL_X25519_ML_KEM_768: + case WOLFSSL_P384_ML_KEM_1024: + case WOLFSSL_P256_ML_KEM_512: + case WOLFSSL_P384_ML_KEM_768: + case WOLFSSL_P521_ML_KEM_1024: + case WOLFSSL_X25519_ML_KEM_512: + case WOLFSSL_X448_ML_KEM_768: + #endif + #ifdef WOLFSSL_MLKEM_KYBER + case WOLFSSL_P256_KYBER_LEVEL3: + case WOLFSSL_X25519_KYBER_LEVEL3: + case WOLFSSL_P256_KYBER_LEVEL1: + case WOLFSSL_P384_KYBER_LEVEL3: + case WOLFSSL_P521_KYBER_LEVEL5: + case WOLFSSL_X25519_KYBER_LEVEL1: + case WOLFSSL_X448_KYBER_LEVEL3: + #endif + return 1; + default: + return 0; + } + } +#endif /* WOLFSSL_HAVE_MLKEM */ + int TranslateErrorToAlert(int err) { switch (err) { @@ -35164,7 +35517,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (input == NULL) return MEMORY_E; - XMEMCPY(input, output + recordHeaderSz, inputSz); + XMEMCPY(input, output + recordHeaderSz, (size_t)(inputSz)); #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl) && (ret = DtlsMsgPoolSave(ssl, input, (word32)inputSz, server_hello)) != 0) { @@ -37553,11 +37906,6 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, { byte b; ProtocolVersion pv; -#ifdef WOLFSSL_SMALL_STACK - Suites* clSuites = NULL; -#else - Suites clSuites[1]; -#endif word32 i = *inOutIdx; word32 begin = i; int ret = 0; @@ -37625,8 +37973,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_3_MINOR) pv.minor = TLSv1_2_MINOR; - lesserVersion = !ssl->options.dtls && ssl->version.minor > pv.minor; - lesserVersion |= ssl->options.dtls && ssl->version.minor < pv.minor; + lesserVersion = (byte)(!ssl->options.dtls && + ssl->version.minor > pv.minor); + lesserVersion |= ssl->options.dtls &&ssl->version.minor < pv.minor; if (lesserVersion) { byte belowMinDowngrade; @@ -37855,40 +38204,40 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, goto out; } -#ifdef WOLFSSL_SMALL_STACK - clSuites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap, + XFREE(ssl->clSuites, ssl->heap, DYNAMIC_TYPE_SUITES); + ssl->clSuites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap, DYNAMIC_TYPE_SUITES); - if (clSuites == NULL) { + if (ssl->clSuites == NULL) { ret = MEMORY_E; goto out; } -#endif - XMEMSET(clSuites, 0, sizeof(Suites)); - ato16(&input[i], &clSuites->suiteSz); + XMEMSET(ssl->clSuites, 0, sizeof(Suites)); + ato16(&input[i], &ssl->clSuites->suiteSz); i += OPAQUE16_LEN; /* Cipher suite lists are always multiples of two in length. */ - if (clSuites->suiteSz % 2 != 0) { + if (ssl->clSuites->suiteSz % 2 != 0) { ret = BUFFER_ERROR; goto out; } /* suites and compression length check */ - if ((i - begin) + clSuites->suiteSz + OPAQUE8_LEN > helloSz) { + if ((i - begin) + ssl->clSuites->suiteSz + OPAQUE8_LEN > helloSz) { ret = BUFFER_ERROR; goto out; } - if (clSuites->suiteSz > WOLFSSL_MAX_SUITE_SZ) { + if (ssl->clSuites->suiteSz > WOLFSSL_MAX_SUITE_SZ) { ret = BUFFER_ERROR; goto out; } - XMEMCPY(clSuites->suites, input + i, clSuites->suiteSz); + XMEMCPY(ssl->clSuites->suites, input + i, ssl->clSuites->suiteSz); #ifdef HAVE_SERVER_RENEGOTIATION_INFO /* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */ - if (FindSuite(clSuites, 0, TLS_EMPTY_RENEGOTIATION_INFO_SCSV) >= 0) { + if (FindSuite(ssl->clSuites, 0, TLS_EMPTY_RENEGOTIATION_INFO_SCSV) >= + 0) { TLSX* extension; /* check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV suite */ @@ -37910,7 +38259,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif /* HAVE_SERVER_RENEGOTIATION_INFO */ #if defined(HAVE_FALLBACK_SCSV) || defined(OPENSSL_ALL) /* check for TLS_FALLBACK_SCSV suite */ - if (FindSuite(clSuites, TLS_FALLBACK_SCSV, 0) >= 0) { + if (FindSuite(ssl->clSuites, TLS_FALLBACK_SCSV, 0) >= 0) { WOLFSSL_MSG("Found Fallback SCSV"); if (ssl->ctx->method->version.minor > pv.minor) { WOLFSSL_MSG("Client trying to connect with lesser version"); @@ -37921,8 +38270,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif - i += clSuites->suiteSz; - clSuites->hashSigAlgoSz = 0; + i += ssl->clSuites->suiteSz; + ssl->clSuites->hashSigAlgoSz = 0; /* compression length */ b = input[i++]; @@ -38009,7 +38358,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef HAVE_TLS_EXTENSIONS /* tls extensions */ if ((ret = TLSX_Parse(ssl, input + i, totalExtSz, client_hello, - clSuites))) + ssl->clSuites))) goto out; #ifdef WOLFSSL_TLS13 if (TLSX_Find(ssl->extensions, @@ -38065,15 +38414,16 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, goto out; } - clSuites->hashSigAlgoSz = hashSigAlgoSz; - if (clSuites->hashSigAlgoSz > WOLFSSL_MAX_SIGALGO) { + ssl->clSuites->hashSigAlgoSz = hashSigAlgoSz; + if (ssl->clSuites->hashSigAlgoSz > + WOLFSSL_MAX_SIGALGO) { WOLFSSL_MSG("ClientHello SigAlgo list exceeds max, " "truncating"); - clSuites->hashSigAlgoSz = WOLFSSL_MAX_SIGALGO; + ssl->clSuites->hashSigAlgoSz = WOLFSSL_MAX_SIGALGO; } - XMEMCPY(clSuites->hashSigAlgo, &input[i], - clSuites->hashSigAlgoSz); + XMEMCPY(ssl->clSuites->hashSigAlgo, &input[i], + ssl->clSuites->hashSigAlgoSz); i += hashSigAlgoSz; } @@ -38084,7 +38434,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, else i += extSz; - totalExtSz -= OPAQUE16_LEN + OPAQUE16_LEN + extSz; + totalExtSz -= (word16)(OPAQUE16_LEN + OPAQUE16_LEN) + extSz; } #endif *inOutIdx = i; @@ -38104,7 +38454,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* ProcessOld uses same resume code */ WOLFSSL_MSG_EX("ssl->options.resuming %d", ssl->options.resuming); if (ssl->options.resuming) { - ret = HandleTlsResumption(ssl, clSuites); + ret = HandleTlsResumption(ssl, ssl->clSuites); if (ret != 0) goto out; @@ -38140,19 +38490,12 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif #ifdef OPENSSL_EXTRA - ssl->clSuites = clSuites; /* cppcheck-suppress autoVariables - * - * (suppress warning that ssl, a persistent - * non-local allocation, has its ->clSuites - * set to clSuites, a local stack allocation. - * we clear this assignment before returning.) - */ /* Give user last chance to provide a cert for cipher selection */ if (ret == 0 && ssl->ctx->certSetupCb != NULL) ret = CertSetupCbWrapper(ssl); #endif if (ret == 0) - ret = MatchSuite(ssl, clSuites); + ret = MatchSuite(ssl, ssl->clSuites); #if defined(HAVE_TLS_EXTENSIONS) && defined(HAVE_ENCRYPT_THEN_MAC) && \ !defined(WOLFSSL_AEAD_ONLY) @@ -38170,11 +38513,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif out: -#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) +#if !defined(OPENSSL_EXTRA) + XFREE(ssl->clSuites, ssl->heap, DYNAMIC_TYPE_SUITES); ssl->clSuites = NULL; -#endif -#ifdef WOLFSSL_SMALL_STACK - XFREE(clSuites, ssl->heap, DYNAMIC_TYPE_SUITES); #endif WOLFSSL_LEAVE("DoClientHello", ret); WOLFSSL_END(WC_FUNC_CLIENT_HELLO_DO); @@ -38709,7 +39050,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (input == NULL) return MEMORY_E; - XMEMCPY(input, output + recordHeaderSz, inputSz); + XMEMCPY(input, output + recordHeaderSz, (size_t)(inputSz)); #ifdef WOLFSSL_DTLS if (IsDtlsNotSctpMode(ssl) && (ret = DtlsMsgPoolSave(ssl, input, (word32)inputSz, server_hello_done)) != 0) { @@ -39404,8 +39745,19 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, WOLFSSL_MSG("Found session matching the session id" " found in the ticket"); /* Allocate and populate an InternalTicket */ + #ifdef WOLFSSL_NO_REALLOC + tmp = (byte*)XMALLOC(sizeof(InternalTicket), ssl->heap, + DYNAMIC_TYPE_TLSX); + if (tmp != NULL && psk->identity != NULL) + { + XMEMCPY(tmp, psk->identity, psk->identityLen); + XFREE(psk->identity, ssl->heap, DYNAMIC_TYPE_TLSX); + psk->identity = NULL; + } + #else tmp = (byte*)XREALLOC(psk->identity, sizeof(InternalTicket), ssl->heap, DYNAMIC_TYPE_TLSX); + #endif if (tmp != NULL) { XMEMSET(tmp, 0, sizeof(InternalTicket)); psk->identity = tmp; @@ -41522,8 +41874,7 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], ret = args->lastErr; args->lastErr = 0; /* reset */ /* On error 'ret' will be negative */ - mask = ((unsigned int)ret >> - ((sizeof(ret) * 8) - 1)) - 1; + mask = (byte)(((unsigned int)ret >> ((sizeof(ret) * 8) - 1)) - 1); /* build PreMasterSecret */ ssl->arrays->preMasterSecret[0] = ssl->chVersion.major; @@ -41962,7 +42313,7 @@ int wolfSSL_set_iotsafe_ctx(WOLFSSL *ssl, IOTSAFE *iotsafe) return 0; } -#endif +#endif /* WOLFSSL_IOTSAFE && HAVE_PK_CALLBACKS */ #if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR) /* create an instance of WOLFSSL_BY_DIR_HASH structure */ @@ -42051,32 +42402,7 @@ WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_value( WOLFSSL_BY_DIR_HASH* wolfSSL_sk_BY_DIR_HASH_pop( WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk) { - WOLFSSL_STACK* node; - WOLFSSL_BY_DIR_HASH* hash; - - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_pop"); - - if (sk == NULL) { - return NULL; - } - - node = sk->next; - hash = sk->data.dir_hash; - - if (node != NULL) { /* update sk and remove node from stack */ - sk->data.dir_hash = node->data.dir_hash; - sk->next = node->next; - wolfSSL_sk_free_node(node); - } - else { /* last x509 in stack */ - sk->data.dir_hash = NULL; - } - - if (sk->num > 0) { - sk->num -= 1; - } - - return hash; + return (WOLFSSL_BY_DIR_HASH *)wolfSSL_sk_pop(sk); } /* release all contents in stack, and then release stack itself. */ /* Second argument is a function pointer to release resources. */ @@ -42131,39 +42457,13 @@ void wolfSSL_sk_BY_DIR_HASH_free(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH) *sk) int wolfSSL_sk_BY_DIR_HASH_push(WOLF_STACK_OF(WOLFSSL_BY_DIR_HASH)* sk, WOLFSSL_BY_DIR_HASH* in) { - WOLFSSL_STACK* node; - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_HASH_push"); if (sk == NULL || in == NULL) { return WOLFSSL_FAILURE; } - /* no previous values in stack */ - if (sk->data.dir_hash == NULL) { - sk->data.dir_hash = in; - sk->num += 1; - return WOLFSSL_SUCCESS; - } - - /* stack already has value(s) create a new node and add more */ - node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_OPENSSL); - if (node == NULL) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_FAILURE; - } - XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); - - /* push new obj onto head of stack */ - node->data.dir_hash = sk->data.dir_hash; - node->next = sk->next; - node->type = sk->type; - sk->next = node; - sk->data.dir_hash = in; - sk->num += 1; - - return WOLFSSL_SUCCESS; + return wolfSSL_sk_push(sk, in); } /* create an instance of WOLFSSL_BY_DIR_entry structure */ WOLFSSL_BY_DIR_entry* wolfSSL_BY_DIR_entry_new(void) @@ -42234,32 +42534,7 @@ WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_value( WOLFSSL_BY_DIR_entry* wolfSSL_sk_BY_DIR_entry_pop( WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk) { - WOLFSSL_STACK* node; - WOLFSSL_BY_DIR_entry* entry; - - WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_pop"); - - if (sk == NULL) { - return NULL; - } - - node = sk->next; - entry = sk->data.dir_entry; - - if (node != NULL) { /* update sk and remove node from stack */ - sk->data.dir_entry = node->data.dir_entry; - sk->next = node->next; - wolfSSL_sk_free_node(node); - } - else { /* last x509 in stack */ - sk->data.dir_entry = NULL; - } - - if (sk->num > 0) { - sk->num -= 1; - } - - return entry; + return (WOLFSSL_BY_DIR_entry *)wolfSSL_sk_pop(sk); } /* release all contents in stack, and then release stack itself. */ /* Second argument is a function pointer to release resources. */ @@ -42315,40 +42590,16 @@ void wolfSSL_sk_BY_DIR_entry_free(WOLF_STACK_OF(wolfSSL_BY_DIR_entry) *sk) int wolfSSL_sk_BY_DIR_entry_push(WOLF_STACK_OF(WOLFSSL_BY_DIR_entry)* sk, WOLFSSL_BY_DIR_entry* in) { - WOLFSSL_STACK* node; + WOLFSSL_ENTER("wolfSSL_sk_BY_DIR_entry_push"); if (sk == NULL || in == NULL) { return WOLFSSL_FAILURE; } - /* no previous values in stack */ - if (sk->data.dir_entry == NULL) { - sk->data.dir_entry = in; - sk->num += 1; - return WOLFSSL_SUCCESS; - } - - /* stack already has value(s) create a new node and add more */ - node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, - DYNAMIC_TYPE_OPENSSL); - if (node == NULL) { - WOLFSSL_MSG("Memory error"); - return WOLFSSL_FAILURE; - } - XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); - - /* push new obj onto head of stack */ - node->data.dir_entry = sk->data.dir_entry; - node->next = sk->next; - node->type = sk->type; - sk->next = node; - sk->data.dir_entry = in; - sk->num += 1; - - return WOLFSSL_SUCCESS; + return wolfSSL_sk_push(sk, in); } -#endif /* OPENSSL_ALL */ +#endif /* OPENSSL_ALL && !NO_FILESYSTEM && !NO_FILESYSTEM */ #if defined(__APPLE__) && defined(WOLFSSL_SYS_CA_CERTS) @@ -42487,4 +42738,4 @@ static int DoAppleNativeCertValidation(const WOLFSSL_BUFFER_INFO* certs, #undef ERROR_OUT -#endif /* WOLFCRYPT_ONLY */ +#endif /* !WOLFCRYPT_ONLY */ diff --git a/src/src/keys.c b/src/src/keys.c index 4ff687e..8f8d2eb 100644 --- a/src/src/keys.c +++ b/src/src/keys.c @@ -1,6 +1,6 @@ /* keys.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -22,11 +22,7 @@ /* Name change compatibility layer no longer needs to be included here */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if !defined(WOLFCRYPT_ONLY) && !defined(NO_TLS) @@ -128,6 +124,9 @@ int GetCipherSpec(word16 side, byte cipherSuite0, byte cipherSuite, } #endif /* NO_WOLFSSL_CLIENT */ + /* Initialize specs */ + XMEMSET(specs, 0, sizeof(CipherSpecs)); + /* Chacha extensions, 0xcc */ if (cipherSuite0 == CHACHA_BYTE) { @@ -3908,7 +3907,8 @@ int DeriveKeys(WOLFSSL* ssl) XMEMCPY(shaInput + idx, ssl->arrays->clientRandom, RAN_LEN); if (ret == 0) { ret = wc_ShaUpdate(sha, shaInput, - (KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN) - KEY_PREFIX + j); + (KEY_PREFIX + SECRET_LEN + 2 * RAN_LEN) - KEY_PREFIX + + (word32)(j)); } if (ret == 0) { ret = wc_ShaFinal(sha, shaOutput); @@ -3942,12 +3942,13 @@ int DeriveKeys(WOLFSSL* ssl) static int CleanPreMaster(WOLFSSL* ssl) { - int i, ret, sz = ssl->arrays->preMasterSz; + int i, ret, sz = (int)(ssl->arrays->preMasterSz); for (i = 0; i < sz; i++) ssl->arrays->preMasterSecret[i] = 0; - ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, sz); + ret = wc_RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, + (word32)(sz)); if (ret != 0) return ret; @@ -4035,8 +4036,8 @@ static int MakeSslMasterSecret(WOLFSSL* ssl) } idx = 0; - XMEMCPY(shaInput, prefix, i + 1); - idx += i + 1; + XMEMCPY(shaInput, prefix, (size_t)(i + 1)); + idx += (word32)(i + 1); XMEMCPY(shaInput + idx, ssl->arrays->preMasterSecret, pmsSz); idx += pmsSz; diff --git a/src/src/ocsp.c b/src/src/ocsp.c index cf824f6..c90936a 100644 --- a/src/src/ocsp.c +++ b/src/src/ocsp.c @@ -1,6 +1,6 @@ /* ocsp.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,15 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include /* Name change compatibility layer no longer needs to be included here */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - /* * WOLFSSL_NO_OCSP_ISSUER_CHAIN_CHECK: * Disable looking for an authorized responder in the verification path of @@ -333,7 +328,7 @@ int CheckOcspResponse(WOLFSSL_OCSP *ocsp, byte *response, int responseSz, ocspResponse->pendingCAs = TLSX_CSR2_GetPendingSigners(((WOLFSSL*)ocspRequest->ssl)->extensions); } #endif - ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0); + ret = OcspResponseDecode(ocspResponse, ocsp->cm, ocsp->cm->heap, 0, 0); if (ret != 0) { ocsp->error = ret; WOLFSSL_LEAVE("OcspResponseDecode failed", ocsp->error); @@ -480,31 +475,6 @@ int CheckOcspRequest(WOLFSSL_OCSP* ocsp, OcspRequest* ocspRequest, ioCtx = (ssl && ssl->ocspIOCtx != NULL) ? ssl->ocspIOCtx : ocsp->cm->ocspIOCtx; -#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) - if (ocsp->statusCb != NULL && ssl != NULL) { - WOLFSSL_MSG("Calling ocsp->statusCb"); - ret = ocsp->statusCb(ssl, ioCtx); - switch (ret) { - case SSL_TLSEXT_ERR_OK: - ret = wolfSSL_get_ocsp_response(ssl, &response); - ret = CheckOcspResponse(ocsp, response, ret, responseBuffer, - status, entry, NULL, heap); - XFREE(response, NULL, DYNAMIC_TYPE_OPENSSL); - break; - case SSL_TLSEXT_ERR_NOACK: - ret = OCSP_LOOKUP_FAIL; - break; - case SSL_TLSEXT_ERR_ALERT_FATAL: - default: - WOLFSSL_LEAVE("CheckOcspRequest", ocsp->error); - ret = WOLFSSL_FATAL_ERROR; - break; - } - WOLFSSL_LEAVE("CheckOcspRequest", ret); - return ret; - } -#endif - if (ocsp->cm->ocspUseOverrideURL) { url = ocsp->cm->ocspOverrideURL; if (url != NULL && url[0] != '\0') @@ -656,9 +626,6 @@ int CheckOcspResponder(OcspResponse *bs, DecodedCert *cert, void* vp) if (!passed) { WOLFSSL_MSG("\tOCSP Responder not authorized"); -#ifdef OPENSSL_EXTRA - bs->verifyError = OCSP_BAD_ISSUER; -#endif ret = BAD_OCSP_RESPONDER; break; } @@ -755,13 +722,23 @@ WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id( WOLFSSL_CERT_MANAGER* cm = NULL; int ret = -1; DerBuffer* derCert = NULL; + int dgstType; #ifdef WOLFSSL_SMALL_STACK DecodedCert *cert = NULL; #else DecodedCert cert[1]; #endif - (void)dgst; + if (dgst == NULL) { + dgstType = WC_HASH_TYPE_SHA; + } + else if (wolfSSL_EVP_get_hashinfo(dgst, &dgstType, NULL) != + WOLFSSL_SUCCESS) { + return NULL; + } + + if (dgstType != OCSP_DIGEST) + return NULL; cm = wolfSSL_CertManagerNew(); if (cm == NULL @@ -813,6 +790,7 @@ WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_cert_to_id( goto out; } else { + certId->hashAlgoOID = wc_HashGetOID(OCSP_DIGEST); XMEMCPY(certId->issuerHash, cert->issuerHash, OCSP_DIGEST_SIZE); XMEMCPY(certId->issuerKeyHash, cert->issuerKeyHash, OCSP_DIGEST_SIZE); XMEMCPY(certId->status->serial, cert->serial, (size_t)cert->serialSz); @@ -850,79 +828,246 @@ void wolfSSL_OCSP_BASICRESP_free(WOLFSSL_OCSP_BASICRESP* basicResponse) wolfSSL_OCSP_RESPONSE_free(basicResponse); } -/* Signature verified in DecodeBasicOcspResponse. - * But no store available to verify certificate. */ -int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP *bs, - WOLF_STACK_OF(WOLFSSL_X509) *certs, WOLFSSL_X509_STORE *st, unsigned long flags) +/* Calculate ancode CertID DER encoding following RFC 6960: + CertID ::= SEQUENCE { + hashAlgorithm AlgorithmIdentifier, + issuerNameHash OCTET STRING, + issuerKeyHash OCTET STRING, + serialNumber CertificateSerialNumber } +*/ +static int OcspEncodeCertID(WOLFSSL_OCSP_CERTID* id, byte* output, + word32* totalSz, word32* intSize) { - int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE); -#ifdef WOLFSSL_SMALL_STACK - DecodedCert *cert; -#else - DecodedCert cert[1]; -#endif - byte certInit = 0; - int idx; + word32 idx = 0; + int ret; - (void)certs; + if (id == NULL || totalSz == NULL || intSize == NULL || + (output != NULL && (*totalSz == 0 || *totalSz <= *intSize))) + return BAD_FUNC_ARG; - if (flags & WOLFSSL_OCSP_NOVERIFY) - return WOLFSSL_SUCCESS; + if (output != NULL) { + ret = SetSequence(*intSize, output); + if (ret < 0) + return ret; + idx += ret; + } -#ifdef WOLFSSL_SMALL_STACK - cert = (DecodedCert *) - XMALLOC(sizeof(*cert), (st && st->cm) ? st->cm->heap : NULL, - DYNAMIC_TYPE_DCERT); - if (cert == NULL) - return WOLFSSL_FAILURE; -#endif + ret = SetAlgoID(id->hashAlgoOID, ((output != NULL) ? output + idx : output), + oidHashType, 0); + if (ret <= 0) + return -1; + idx += ret; - if (bs->verifyError != OCSP_VERIFY_ERROR_NONE) - goto out; + /* issuerNameHash */ + ret = SetOctetString(OCSP_DIGEST_SIZE, ((output != NULL) ? output + idx : output)); + if (ret < 0) + return ret; + idx += ret; + if (output != NULL) + XMEMCPY(output + idx, id->issuerHash, OCSP_DIGEST_SIZE); + idx += OCSP_DIGEST_SIZE; + + /* issuerKeyHash */ + ret = SetOctetString(OCSP_DIGEST_SIZE, ((output != NULL) ? output + idx : output)); + if (ret < 0) + return ret; + idx += ret; + if (output != NULL) + XMEMCPY(output + idx, id->issuerKeyHash, OCSP_DIGEST_SIZE); + idx += OCSP_DIGEST_SIZE; + + /* serialNumber */ + ret = SetASNInt(id->status->serialSz, id->status->serial[0], ((output != NULL) ? output + idx : output)); + if (ret < 0) + return ret; + idx += ret; + if (output != NULL) + XMEMCPY(output + idx, id->status->serial, id->status->serialSz); + idx += id->status->serialSz; - if (flags & WOLFSSL_OCSP_TRUSTOTHER) { - for (idx = 0; idx < wolfSSL_sk_X509_num(certs); idx++) { - WOLFSSL_X509* x = wolfSSL_sk_X509_value(certs, idx); - int derSz = 0; - const byte* der = wolfSSL_X509_get_der(x, &derSz); - if (der != NULL && derSz == (int)bs->certSz && - XMEMCMP(bs->cert, der, (size_t)derSz) == 0) { - ret = WOLFSSL_SUCCESS; - goto out; - } + if (output == NULL) { + *intSize = idx; + ret = SetSequence(idx, NULL); + if (ret < 0) + return ret; + idx += ret; + *totalSz = idx; + } + else if (idx != *totalSz) { + return BUFFER_E; + } + + return 0; +} + +static int OcspRespIdMatches(OcspResponse* resp, const byte* NameHash, + const byte* keyHash) +{ + if (resp->responderIdType == OCSP_RESPONDER_ID_NAME) { + return XMEMCMP(NameHash, resp->responderId.nameHash, + SIGNER_DIGEST_SIZE) == 0; + } + else if (resp->responderIdType == OCSP_RESPONDER_ID_KEY) { + return XMEMCMP(keyHash, resp->responderId.keyHash, KEYID_SIZE) == 0; + } + + return 0; +} + +static int OcspFindSigner(WOLFSSL_OCSP_BASICRESP *resp, + WOLF_STACK_OF(WOLFSSL_X509) *certs, DecodedCert **signer, int *embedded, + unsigned long flags) +{ + WOLFSSL_X509 *signer_x509 = NULL; + DecodedCert *certDecoded; + int i; + + certDecoded = (DecodedCert *)XMALLOC(sizeof(*certDecoded), resp->heap, + DYNAMIC_TYPE_DCERT); + if (certDecoded == NULL) + return MEMORY_E; + + for (i = 0; i < wolfSSL_sk_X509_num(certs); i++) { + signer_x509 = wolfSSL_sk_X509_value(certs, i); + if (signer_x509 == NULL) + continue; + + InitDecodedCert(certDecoded, signer_x509->derCert->buffer, + signer_x509->derCert->length, resp->heap); + if (ParseCertRelative(certDecoded, CERT_TYPE, NO_VERIFY, + NULL, NULL) == 0) { + if (OcspRespIdMatches(resp, certDecoded->subjectHash, + certDecoded->subjectKeyHash)) { + *signer = certDecoded; + *embedded = 0; + return 0; + } } + FreeDecodedCert(certDecoded); } - InitDecodedCert(cert, bs->cert, bs->certSz, NULL); - certInit = 1; - if (ParseCertRelative(cert, CERT_TYPE, VERIFY, st->cm, NULL) < 0) - goto out; + if (flags & WOLFSSL_OCSP_NOINTERN) { + XFREE(certDecoded, resp->heap, DYNAMIC_TYPE_DCERT); + return ASN_NO_SIGNER_E; + } - if (!(flags & WOLFSSL_OCSP_NOCHECKS)) { - if (CheckOcspResponder(bs, cert, st->cm) != 0) - goto out; + /* not found in certs, search the cert embedded in the response */ + InitDecodedCert(certDecoded, resp->cert, resp->certSz, resp->heap); + if (ParseCertRelative(certDecoded, CERT_TYPE, NO_VERIFY, NULL, NULL) == 0) { + if (OcspRespIdMatches(resp, certDecoded->subjectHash, + certDecoded->subjectKeyHash)) { + *signer = certDecoded; + *embedded = 1; + return 0; + } } + FreeDecodedCert(certDecoded); - ret = WOLFSSL_SUCCESS; -out: - if (certInit) - FreeDecodedCert(cert); + XFREE(certDecoded, resp->heap, DYNAMIC_TYPE_DCERT); + return ASN_NO_SIGNER_E; +} +static int OcspVerifySigner(WOLFSSL_OCSP_BASICRESP *resp, DecodedCert *cert, + WOLFSSL_X509_STORE *st, unsigned long flags) +{ #ifdef WOLFSSL_SMALL_STACK - XFREE(cert, (st && st->cm) ? st->cm->heap : NULL, DYNAMIC_TYPE_DCERT); + DecodedCert *c = NULL; +#else + DecodedCert c[1]; +#endif + + int ret = -1; + if (st == NULL) + return ASN_OCSP_CONFIRM_E; + +#ifdef WOLFSSL_SMALL_STACK + c = (DecodedCert *)XMALLOC(sizeof(*c), NULL, DYNAMIC_TYPE_DCERT); + if (c == NULL) + return MEMORY_E; #endif + InitDecodedCert(c, cert->source, cert->maxIdx, NULL); + if (ParseCertRelative(c, CERT_TYPE, VERIFY, st->cm, NULL) != 0) { + ret = ASN_OCSP_CONFIRM_E; + goto err; + } +#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK + if ((flags & WOLFSSL_OCSP_NOCHECKS) == 0) { + ret = CheckOcspResponder(resp, c, st->cm); + } + else { + ret = 0; + } +#else + (void)resp; + (void)flags; + ret = 0; +#endif + +err: + FreeDecodedCert(c); +#ifdef WOLFSSL_SMALL_STACK + XFREE(c, NULL, DYNAMIC_TYPE_DCERT); +#endif return ret; } +/* Signature verified in DecodeBasicOcspResponse. + * But no store available to verify certificate. */ +int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP* bs, + WOLF_STACK_OF(WOLFSSL_X509) * certs, WOLFSSL_X509_STORE* st, + unsigned long flags) +{ + int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE); + int embedded; + DecodedCert *cert = NULL; + + ret = OcspFindSigner(bs, certs, &cert, &embedded, flags); + if (ret != 0) { + WOLFSSL_MSG("OCSP no signer found"); + return WOLFSSL_FAILURE; + } + + /* skip certificate verification if cert in certs and TRUST_OTHER is true */ + if (!embedded && (flags & WOLFSSL_OCSP_TRUSTOTHER) != 0) + flags |= WOLFSSL_OCSP_NOVERIFY; + + /* verify response signature */ + ret = ConfirmSignature( + &cert->sigCtx, + bs->response, bs->responseSz, + cert->publicKey, cert->pubKeySize, cert->keyOID, + bs->sig, bs->sigSz, bs->sigOID, bs->sigParams, bs->sigParamsSz, + NULL); + + if (ret != 0) { + WOLFSSL_MSG("OCSP signature verification failed"); + ret = -1; + goto err; + } + + if ((flags & WOLFSSL_OCSP_NOVERIFY) == 0) { + ret = OcspVerifySigner(bs, cert, st, flags); + } + +err: + FreeDecodedCert(cert); + XFREE(cert, NULL, DYNAMIC_TYPE_DCERT); + return ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} void wolfSSL_OCSP_RESPONSE_free(OcspResponse* response) { + OcspEntry *s, *sNext; if (response == NULL) return; - if (response->single != NULL) { - FreeOcspEntry(response->single, NULL); - XFREE(response->single, NULL, DYNAMIC_TYPE_OCSP_ENTRY); + + s = response->single; + while (s != NULL) { + sNext = s->next; + FreeOcspEntry(s, NULL); + XFREE(s, NULL, DYNAMIC_TYPE_OCSP_ENTRY); + s = sNext; } XFREE(response->source, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -1045,7 +1190,7 @@ OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response, XMEMCPY(resp->source, *data, (size_t)len); resp->maxIdx = (word32)len; - ret = OcspResponseDecode(resp, NULL, NULL, 1); + ret = OcspResponseDecode(resp, NULL, NULL, 1, 1); if (ret != 0 && ret != WC_NO_ERR_TRACE(ASN_OCSP_CONFIRM_E)) { /* for just converting from a DER to an internal structure the CA may * not yet be known to this function for signature verification */ @@ -1100,27 +1245,9 @@ const char *wolfSSL_OCSP_response_status_str(long s) WOLFSSL_OCSP_BASICRESP* wolfSSL_OCSP_response_get1_basic(OcspResponse* response) { WOLFSSL_OCSP_BASICRESP* bs; + const unsigned char *ptr = response->source; - bs = (WOLFSSL_OCSP_BASICRESP*)XMALLOC(sizeof(WOLFSSL_OCSP_BASICRESP), NULL, - DYNAMIC_TYPE_OCSP_REQUEST); - if (bs == NULL) - return NULL; - - XMEMCPY(bs, response, sizeof(OcspResponse)); - bs->single = (OcspEntry*)XMALLOC(sizeof(OcspEntry), NULL, - DYNAMIC_TYPE_OCSP_ENTRY); - bs->source = (byte*)XMALLOC(bs->maxIdx, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (bs->single == NULL || bs->source == NULL) { - XFREE(bs->single, NULL, DYNAMIC_TYPE_OCSP_ENTRY); - bs->single = NULL; - wolfSSL_OCSP_RESPONSE_free(bs); - bs = NULL; - } - else { - XMEMCPY(bs->single, response->single, sizeof(OcspEntry)); - XMEMCPY(bs->source, response->source, response->maxIdx); - bs->single->ownStatus = 0; - } + bs = wolfSSL_d2i_OCSP_RESPONSE(NULL, &ptr, response->maxIdx); return bs; } @@ -1235,22 +1362,59 @@ int wolfSSL_i2d_OCSP_REQUEST_bio(WOLFSSL_BIO* out, int wolfSSL_i2d_OCSP_CERTID(WOLFSSL_OCSP_CERTID* id, unsigned char** data) { - if (id == NULL || data == NULL) - return WOLFSSL_FAILURE; + int allocated = 0; + word32 derSz = 0; + word32 intSz = 0; + int ret; + WOLFSSL_ENTER("wolfSSL_i2d_OCSP_CERTID"); - if (*data != NULL) { - XMEMCPY(*data, id->rawCertId, (size_t)id->rawCertIdSize); - *data = *data + id->rawCertIdSize; + if (id == NULL) + return -1; + + if (id->rawCertId != NULL) { + derSz = id->rawCertIdSize; } else { - *data = (unsigned char*)XMALLOC((size_t)id->rawCertIdSize, NULL, DYNAMIC_TYPE_OPENSSL); + ret = OcspEncodeCertID(id, NULL, &derSz, &intSz); + if (ret != 0) { + WOLFSSL_MSG("Failed to calculate CertID size"); + return -1; + } + } + + if (data == NULL) { + return derSz; + } + + if (*data == NULL) { + /* Allocate buffer for DER encoding */ + *data = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_OPENSSL); if (*data == NULL) { - return WOLFSSL_FAILURE; + WOLFSSL_MSG("Failed to allocate memory for CertID DER encoding"); + return -1; } - XMEMCPY(*data, id->rawCertId, (size_t)id->rawCertIdSize); + allocated = 1; } - return id->rawCertIdSize; + if (id->rawCertId != NULL) { + XMEMCPY(*data, id->rawCertId, id->rawCertIdSize); + } + else { + ret = OcspEncodeCertID(id, *data, &derSz, &intSz); + if (ret < 0) { + WOLFSSL_MSG("Failed to encode CertID"); + if (allocated) { + XFREE(*data, NULL, DYNAMIC_TYPE_OPENSSL); + *data = NULL; + } + return -1; + } + } + + if (!allocated) + *data += derSz; + + return derSz; } WOLFSSL_OCSP_CERTID* wolfSSL_d2i_OCSP_CERTID(WOLFSSL_OCSP_CERTID** cidOut, @@ -1258,44 +1422,50 @@ WOLFSSL_OCSP_CERTID* wolfSSL_d2i_OCSP_CERTID(WOLFSSL_OCSP_CERTID** cidOut, int length) { WOLFSSL_OCSP_CERTID *cid = NULL; + int isAllocated = 0; + word32 idx = 0; + int ret; - if ((cidOut != NULL) && (derIn != NULL) && (*derIn != NULL) && - (length > 0)) { + if (derIn == NULL || *derIn == NULL || length <= 0) + return NULL; + if (cidOut != NULL && *cidOut != NULL) { cid = *cidOut; + FreeOcspEntry(cid, NULL); + } + else { + cid = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(WOLFSSL_OCSP_CERTID), NULL, + DYNAMIC_TYPE_OPENSSL); + if (cid == NULL) + return NULL; + isAllocated = 1; + } - /* If a NULL is passed we allocate the memory for the caller. */ - if (cid == NULL) { - cid = (WOLFSSL_OCSP_CERTID*)XMALLOC(sizeof(*cid), NULL, - DYNAMIC_TYPE_OPENSSL); - } - else if (cid->rawCertId != NULL) { - XFREE(cid->rawCertId, NULL, DYNAMIC_TYPE_OPENSSL); - cid->rawCertId = NULL; - cid->rawCertIdSize = 0; - } - - if (cid != NULL) { - cid->rawCertId = (byte*)XMALLOC((size_t)length + 1, NULL, DYNAMIC_TYPE_OPENSSL); - if (cid->rawCertId != NULL) { - XMEMCPY(cid->rawCertId, *derIn, (size_t)length); - cid->rawCertIdSize = length; - - /* Per spec. advance past the data that is being returned - * to the caller. */ - *cidOut = cid; - *derIn = *derIn + length; + XMEMSET(cid, 0, sizeof(WOLFSSL_OCSP_CERTID)); + cid->status = (CertStatus*)XMALLOC(sizeof(CertStatus), NULL, + DYNAMIC_TYPE_OCSP_STATUS); + if (cid->status == NULL) { + XFREE(cid, NULL, DYNAMIC_TYPE_OPENSSL); + return NULL; + } + XMEMSET(cid->status, 0, sizeof(CertStatus)); + cid->ownStatus = 1; - return cid; - } + ret = OcspDecodeCertID(*derIn, &idx, length, cid); + if (ret != 0) { + FreeOcspEntry(cid, NULL); + if (isAllocated) { + XFREE(cid, NULL, DYNAMIC_TYPE_OPENSSL); } + return NULL; } - if ((cid != NULL) && ((cidOut == NULL) || (cid != *cidOut))) { - XFREE(cid, NULL, DYNAMIC_TYPE_OPENSSL); - } + *derIn += idx; - return NULL; + if (isAllocated && cidOut != NULL) + *cidOut = cid; + + return cid; } const WOLFSSL_OCSP_CERTID* wolfSSL_OCSP_SINGLERESP_get0_id( diff --git a/src/src/pk.c b/src/src/pk.c index 6c55bee..3136cf9 100644 --- a/src/src/pk.c +++ b/src/src/pk.c @@ -1,6 +1,6 @@ /* pk.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #include #ifndef WC_NO_RNG @@ -414,7 +410,7 @@ int EncryptDerKey(byte *der, int *derSz, const WOLFSSL_EVP_CIPHER* cipher, if (ret == 0) { /* Generate a random salt. */ - if (wolfSSL_RAND_bytes(info->iv, info->ivSz) != 1) { + if (wolfSSL_RAND_bytes(info->iv, (int)info->ivSz) != 1) { WOLFSSL_MSG("generate iv failed"); ret = WOLFSSL_FATAL_ERROR; } @@ -422,7 +418,7 @@ int EncryptDerKey(byte *der, int *derSz, const WOLFSSL_EVP_CIPHER* cipher, if (ret == 0) { /* Calculate padding size - always a padding block. */ - paddingSz = info->ivSz - ((*derSz) % info->ivSz); + paddingSz = (int)info->ivSz - ((*derSz) % (int)info->ivSz); /* Check der is big enough. */ if (maxDerSz < (*derSz) + paddingSz) { WOLFSSL_MSG("not enough DER buffer allocated"); @@ -431,7 +427,7 @@ int EncryptDerKey(byte *der, int *derSz, const WOLFSSL_EVP_CIPHER* cipher, } if (ret == 0) { /* Set padding bytes to padding length. */ - XMEMSET(der + (*derSz), (byte)paddingSz, paddingSz); + XMEMSET(der + (*derSz), (byte)paddingSz, (size_t)paddingSz); /* Add padding to DER size. */ (*derSz) += (int)paddingSz; @@ -518,8 +514,19 @@ static int der_to_enc_pem_alloc(unsigned char* der, int derSz, byte *tmpBuf; /* Add space for padding. */ + #ifdef WOLFSSL_NO_REALLOC + tmpBuf = (byte*)XMALLOC((size_t)(derSz + blockSz), heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (tmpBuf != NULL && der != NULL) + { + XMEMCPY(tmpBuf, der, (size_t)(derSz)); + XFREE(der, heap, DYNAMIC_TYPE_TMP_BUFFER); + der = NULL; + } + #else tmpBuf = (byte*)XREALLOC(der, (size_t)(derSz + blockSz), heap, DYNAMIC_TYPE_TMP_BUFFER); + #endif if (tmpBuf == NULL) { WOLFSSL_ERROR_MSG("Extending DER buffer failed"); ret = 0; /* der buffer is free'd at the end of the function */ @@ -724,7 +731,7 @@ static int wolfssl_print_indent(WOLFSSL_BIO* bio, char* line, int lineLen, if (indent > 0) { /* Print indent spaces. */ int len_wanted = XSNPRINTF(line, (size_t)lineLen, "%*s", indent, " "); - if (len_wanted >= lineLen) { + if ((len_wanted < 0) || (len_wanted >= lineLen)) { WOLFSSL_ERROR_MSG("Buffer overflow formatting indentation"); ret = 0; } @@ -1547,7 +1554,11 @@ static int wolfssl_read_der_bio(WOLFSSL_BIO* bio, unsigned char** out) WOLFSSL_ERROR_MSG("Malloc failure"); err = 1; } - if (!err) { + if ((!err) && (derLen <= (int)sizeof(seq))) { + /* Copy the previously read data into the buffer. */ + XMEMCPY(der, seq, derLen); + } + else if (!err) { /* Calculate the unread amount. */ int len = derLen - (int)sizeof(seq); /* Copy the previously read data into the buffer. */ @@ -5630,7 +5641,8 @@ static int dsa_do_verify(const unsigned char* d, int dLen, unsigned char* sig, ret = dLen == WC_SHA_DIGEST_SIZE ? wc_DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck) : BAD_FUNC_ARG; #else - ret = wc_DsaVerify_ex(d, dLen, sig, (DsaKey*)dsa->internal, dsacheck); + ret = wc_DsaVerify_ex(d, (word32)dLen, sig, (DsaKey*)dsa->internal, + dsacheck); #endif if (ret != 0) { WOLFSSL_MSG("DsaVerify failed"); @@ -9475,16 +9487,16 @@ int wolfSSL_i2d_ECPKParameters(const WOLFSSL_EC_GROUP* grp, unsigned char** pp) /* Get the actual DER encoding of the OID. ecc_sets[grp->curve_idx].oid * is just the numerical representation. */ - if (wc_ecc_get_oid(grp->curve_oid, &oid, &oidSz) < 0) + if (wc_ecc_get_oid((word32)grp->curve_oid, &oid, &oidSz) < 0) return WOLFSSL_FATAL_ERROR; - len = SetObjectId(oidSz, NULL) + oidSz; + len = SetObjectId((int)oidSz, NULL) + (int)oidSz; if (pp == NULL) return len; if (*pp == NULL) { - out = (unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1); + out = (unsigned char*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_ASN1); if (out == NULL) return WOLFSSL_FATAL_ERROR; } @@ -9492,7 +9504,7 @@ int wolfSSL_i2d_ECPKParameters(const WOLFSSL_EC_GROUP* grp, unsigned char** pp) out = *pp; } - idx = SetObjectId(oidSz, out); + idx = SetObjectId((int)oidSz, out); XMEMCPY(out + idx, oid, oidSz); if (*pp == NULL) *pp = out; @@ -10273,7 +10285,7 @@ WOLFSSL_EC_POINT* wolfSSL_EC_POINT_hex2point(const WOLFSSL_EC_GROUP *group, key_sz = (wolfSSL_EC_GROUP_get_degree(group) + 7) / 8; if (hex[0] == '0' && hex[1] == '4') { /* uncompressed mode */ - str_sz = key_sz * 2; + str_sz = (size_t)key_sz * 2; XMEMSET(strGx, 0x0, str_sz + 1); XMEMCPY(strGx, hex + 2, str_sz); @@ -10299,7 +10311,7 @@ WOLFSSL_EC_POINT* wolfSSL_EC_POINT_hex2point(const WOLFSSL_EC_GROUP *group, if (hex_to_bytes(hex + 2, octGx + 1, sz) != sz) { goto err; } - if (wolfSSL_ECPoint_d2i(octGx, key_sz + 1, group, p) + if (wolfSSL_ECPoint_d2i(octGx, (word32)key_sz + 1, group, p) != WOLFSSL_SUCCESS) { goto err; } @@ -12234,7 +12246,7 @@ int wolfSSL_i2o_ECPublicKey(const WOLFSSL_EC_KEY *key, unsigned char **out) if (ret == 1) { #ifdef HAVE_COMP_KEY /* Default to compressed form if not set */ - form = (key->form != WC_POINT_CONVERSION_UNCOMPRESSED) ? + form = (key->form == WC_POINT_CONVERSION_UNCOMPRESSED) ? WC_POINT_CONVERSION_UNCOMPRESSED : WC_POINT_CONVERSION_COMPRESSED; #endif @@ -12361,7 +12373,7 @@ WOLFSSL_EC_KEY* wolfSSL_d2i_ECPrivateKey(WOLFSSL_EC_KEY** key, * * @param [in] key EC key to encode. * @param [in, out] out On in, reference to buffer to place DER encoding into. - * On out, reference to buffer adter the encoding. + * On out, reference to buffer after the encoding. * May be NULL. * @return Length of DER encoding on success. * @return 0 on error. @@ -14652,6 +14664,13 @@ int wolfSSL_EC25519_shared_key(unsigned char *shared, unsigned int *sharedSz, res = 0; } if (res) { + #ifdef WOLFSSL_CURVE25519_BLINDING + /* An RNG is needed. */ + if (wc_curve25519_set_rng(&privkey, wolfssl_make_global_rng()) != 0) { + res = 0; + } + else + #endif /* Initialize public key object. */ if (wc_curve25519_init(&pubkey) != MP_OKAY) { WOLFSSL_MSG("wc_curve25519_init pubkey failed"); @@ -15473,7 +15492,7 @@ int wolfSSL_PEM_def_callback(char* buf, int num, int rwFlag, void* userData) if ((buf != NULL) && (userData != NULL)) { sz = (int)XSTRLEN((const char*)userData); sz = (int)min((word32)sz, (word32)num); - XMEMCPY(buf, userData, sz); + XMEMCPY(buf, userData, (size_t)sz); } else { WOLFSSL_MSG("Error, default password cannot be created."); @@ -15967,7 +15986,7 @@ static void pem_find_pattern(char* pem, int pemLen, int idx, const char* prefix, /* Find prefix part. */ for (; idx < pemLen - prefixLen; idx++) { if ((pem[idx] == prefix[0]) && - (XMEMCMP(pem + idx, prefix, prefixLen) == 0)) { + (XMEMCMP(pem + idx, prefix, (size_t)prefixLen) == 0)) { idx += prefixLen; *start = idx; break; @@ -15976,7 +15995,7 @@ static void pem_find_pattern(char* pem, int pemLen, int idx, const char* prefix, /* Find postfix part. */ for (; idx < pemLen - postfixLen; idx++) { if ((pem[idx] == postfix[0]) && - (XMEMCMP(pem + idx, postfix, postfixLen) == 0)) { + (XMEMCMP(pem + idx, postfix, (size_t)postfixLen) == 0)) { *len = idx - *start; break; } @@ -16012,7 +16031,7 @@ static int pem_read_data(char* pem, int pemLen, char **name, char **header, /* Find header. */ pem_find_pattern(pem, pemLen, 0, PEM_BEGIN, PEM_HDR_FIN, &start, &nameLen); /* Allocate memory for header name. */ - *name = (char*)XMALLOC(nameLen + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER); + *name = (char*)XMALLOC((size_t)nameLen + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (*name == NULL) { ret = MEMORY_E; } @@ -16023,7 +16042,7 @@ static int pem_read_data(char* pem, int pemLen, char **name, char **header, ret = ASN_NO_PEM_HEADER; } else { - XMEMCPY(*name, pem + start, nameLen); + XMEMCPY(*name, pem + start, (size_t)nameLen); } } if (ret == 0) { @@ -16035,7 +16054,8 @@ static int pem_read_data(char* pem, int pemLen, char **name, char **header, hdrLen++; } /* Allocate memory for encryption header string. */ - *header = (char*)XMALLOC(hdrLen + 1, NULL, DYNAMIC_TYPE_TMP_BUFFER); + *header = (char*)XMALLOC((size_t)hdrLen + 1, NULL, + DYNAMIC_TYPE_TMP_BUFFER); if (*header == NULL) { ret = MEMORY_E; } @@ -16044,7 +16064,7 @@ static int pem_read_data(char* pem, int pemLen, char **name, char **header, /* Put in encryption header string. */ (*header)[hdrLen] = '\0'; if (hdrLen > 0) { - XMEMCPY(*header, pem + startHdr, hdrLen); + XMEMCPY(*header, pem + startHdr, (size_t)hdrLen); start = startHdr + hdrLen + 1; } @@ -16053,7 +16073,7 @@ static int pem_read_data(char* pem, int pemLen, char **name, char **header, &endLen); /* Validate header name and footer name are the same. */ if ((endLen != nameLen) || - (XMEMCMP(*name, pem + startEnd, nameLen) != 0)) { + (XMEMCMP(*name, pem + startEnd, (size_t)nameLen) != 0)) { ret = ASN_NO_PEM_HEADER; } } @@ -16103,13 +16123,13 @@ static int pem_write_data(const char *name, const char *header, pemLen = (derLen + 2) / 3 * 4; pemLen += (pemLen + 63) / 64; /* Header */ - pemLen += PEM_BEGIN_SZ + nameLen + PEM_HDR_FIN_EOL_SZ; + pemLen += (word32)(PEM_BEGIN_SZ + nameLen + PEM_HDR_FIN_EOL_SZ); if (headerLen > 0) { /* Encryption lines plus extra carriage return. */ - pemLen += headerLen + 1; + pemLen += (word32)headerLen + 1; } /* Trailer */ - pemLen += PEM_END_SZ + nameLen + PEM_HDR_FIN_EOL_SZ; + pemLen += (word32)(PEM_END_SZ + nameLen + PEM_HDR_FIN_EOL_SZ); pem = (char*)XMALLOC(pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { @@ -16121,14 +16141,14 @@ static int pem_write_data(const char *name, const char *header, /* Add header. */ XMEMCPY(p, PEM_BEGIN, PEM_BEGIN_SZ); p += PEM_BEGIN_SZ; - XMEMCPY(p, name, nameLen); + XMEMCPY(p, name, (size_t)nameLen); p += nameLen; XMEMCPY(p, PEM_HDR_FIN_EOL_NEWLINE, PEM_HDR_FIN_EOL_SZ); p += PEM_HDR_FIN_EOL_SZ; if (headerLen > 0) { /* Add encryption header. */ - XMEMCPY(p, header, headerLen); + XMEMCPY(p, header, (size_t)headerLen); p += headerLen; /* Blank line after a header and before body. */ *(p++) = '\n'; @@ -16144,7 +16164,7 @@ static int pem_write_data(const char *name, const char *header, /* Add trailer. */ XMEMCPY(p, PEM_END, PEM_END_SZ); p += PEM_END_SZ; - XMEMCPY(p, name, nameLen); + XMEMCPY(p, name, (size_t)nameLen); p += nameLen; XMEMCPY(p, PEM_HDR_FIN_EOL_NEWLINE, PEM_HDR_FIN_EOL_SZ); p += PEM_HDR_FIN_EOL_SZ; @@ -16153,6 +16173,11 @@ static int pem_write_data(const char *name, const char *header, *pemOut = pem; *pemOutLen = (word32)((size_t)p - (size_t)pem); } + else { + /* Dispose of any allocated memory. */ + XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER); + pem = NULL; + } return ret; } @@ -16192,13 +16217,13 @@ int wolfSSL_PEM_read_bio(WOLFSSL_BIO* bio, char **name, char **header, } if ((res == 1) && (!memAlloced)) { /* Need to return allocated memory - make sure it is allocated. */ - char* p = (char*)XMALLOC(pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + char* p = (char*)XMALLOC((size_t)pemLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (p == NULL) { res = 0; } else { /* Copy the data into new buffer. */ - XMEMCPY(p, pem, pemLen); + XMEMCPY(p, pem, (size_t)pemLen); pem = p; } } @@ -16250,7 +16275,7 @@ int wolfSSL_PEM_write_bio(WOLFSSL_BIO* bio, const char *name, } XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return (!err) ? pemLen : 0; + return (!err) ? (int)pemLen : 0; } #endif /* !NO_BIO */ @@ -16475,7 +16500,8 @@ int pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey, if (ret == 0) { /* Encrypt private into buffer. */ - ret = TraditionalEnc((byte*)pkey->pkey.ptr, pkey->pkey_sz, + ret = TraditionalEnc((byte*)pkey->pkey.ptr + pkey->pkcs8HeaderSz, + (word32)pkey->pkey_sz - pkey->pkcs8HeaderSz, key, keySz, passwd, passwdSz, PKCS5, PBES2, encAlgId, NULL, 0, WC_PKCS12_ITT_DEFAULT, &rng, NULL); if (ret > 0) { @@ -16509,7 +16535,7 @@ int pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz) if (pkey->type == WC_EVP_PKEY_EC) { /* ECC private and get curve OID information. */ algId = ECDSAk; - ret = wc_ecc_get_oid(pkey->ecc->group->curve_oid, &curveOid, + ret = wc_ecc_get_oid((word32)pkey->ecc->group->curve_oid, &curveOid, &oidSz); } else @@ -16536,7 +16562,7 @@ int pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz) if (keySz == NULL) return BAD_FUNC_ARG; - *keySz = pkey->pkey_sz; + *keySz = (word32)pkey->pkey_sz; if (key == NULL) return LENGTH_ONLY_E; @@ -16556,8 +16582,9 @@ int pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz) if (ret >= 0) { /* Encode private key in PKCS#8 format. */ - ret = wc_CreatePKCS8Key(key, keySz, (byte*)pkey->pkey.ptr, - pkey->pkey_sz, algId, curveOid, oidSz); + ret = wc_CreatePKCS8Key(key, keySz, (byte*)pkey->pkey.ptr + + pkey->pkcs8HeaderSz, (word32)pkey->pkey_sz - pkey->pkcs8HeaderSz, + algId, curveOid, oidSz); } return ret; diff --git a/src/src/quic.c b/src/src/quic.c index 64cf14f..5791a7d 100644 --- a/src/src/quic.c +++ b/src/src/quic.c @@ -1,6 +1,6 @@ /* quic.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,14 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include /* Name change compatibility layer no longer needs to be included here */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include #ifdef NO_INLINE #include #else @@ -154,17 +150,15 @@ static int quic_record_append(WOLFSSL *ssl, QuicRecord *qr, const uint8_t *data, } } - if (quic_record_complete(qr) || len == 0) { - return 0; - } - - missing = qr->len - qr->end; - if (len > missing) { - len = missing; + if (!quic_record_complete(qr) && len != 0) { + missing = qr->len - qr->end; + if (len > missing) { + len = missing; + } + XMEMCPY(qr->data + qr->end, data, len); + qr->end += (word32)len; + consumed += len; } - XMEMCPY(qr->data + qr->end, data, len); - qr->end += (word32)len; - consumed += len; cleanup: *pconsumed = (ret == WOLFSSL_SUCCESS) ? consumed : 0; @@ -927,8 +921,12 @@ int wolfSSL_quic_forward_secrets(WOLFSSL* ssl, int ktype, int side) goto cleanup; } - ret = !ssl->quic.method->set_encryption_secrets( - ssl, level, rx_secret, tx_secret, ssl->specs.hash_size); + if(!ssl->quic.method->set_encryption_secrets( + ssl, level, rx_secret, tx_secret, ssl->specs.hash_size)) { + WOLFSSL_MSG("WOLFSSL_QUIC_FORWARD_SECRETS failed"); + ret = WOLFSSL_FATAL_ERROR; + goto cleanup; + } /* Having installed the secrets, any future read/write will happen * at the level. Except early data, which is detected on the record diff --git a/src/src/sniffer.c b/src/src/sniffer.c index a3814a4..4d0c8e1 100644 --- a/src/src/sniffer.c +++ b/src/src/sniffer.c @@ -1,6 +1,6 @@ /* sniffer.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,14 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include -#include -#include +#include #ifdef WOLFSSL_ASYNC_CRYPT #include diff --git a/src/src/ssl.c b/src/src/ssl.c index c38fcbf..0b74065 100644 --- a/src/src/ssl.c +++ b/src/src/ssl.c @@ -1,6 +1,6 @@ /* ssl.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include -#ifdef HAVE_CONFIG_H - #include -#endif - -#include #if defined(OPENSSL_EXTRA) && !defined(_WIN32) && !defined(_GNU_SOURCE) /* turn on GNU extensions for XISASCII */ #define _GNU_SOURCE 1 @@ -202,79 +198,20 @@ * * For OpenSSL compatibility. * - * This function shouldn't exist! - * Uses defines in wolfssl/openssl/evp.h. - * Uses EccEnumToNID which uses defines in wolfssl/openssl/ec.h. - * * @param [in] sn Short name of OID. * @return NID corresponding to shortname on success. * @return WC_NID_undef when not recognized. */ int wc_OBJ_sn2nid(const char *sn) { - const struct { - const char *sn; - int nid; - } sn2nid[] = { -#ifndef NO_CERTS - {WOLFSSL_COMMON_NAME, WC_NID_commonName}, - {WOLFSSL_COUNTRY_NAME, WC_NID_countryName}, - {WOLFSSL_LOCALITY_NAME, WC_NID_localityName}, - {WOLFSSL_STATE_NAME, WC_NID_stateOrProvinceName}, - {WOLFSSL_ORG_NAME, WC_NID_organizationName}, - {WOLFSSL_ORGUNIT_NAME, WC_NID_organizationalUnitName}, - #ifdef WOLFSSL_CERT_NAME_ALL - {WOLFSSL_NAME, WC_NID_name}, - {WOLFSSL_INITIALS, WC_NID_initials}, - {WOLFSSL_GIVEN_NAME, WC_NID_givenName}, - {WOLFSSL_DNQUALIFIER, WC_NID_dnQualifier}, - #endif - {WOLFSSL_EMAIL_ADDR, WC_NID_emailAddress}, -#endif - {"SHA1", WC_NID_sha1}, - {NULL, -1}}; - int i; -#ifdef HAVE_ECC - char curveName[ECC_MAXNAME + 1]; - int eccEnum; -#endif - + const WOLFSSL_ObjectInfo *obj_info = wolfssl_object_info; + size_t i; WOLFSSL_ENTER("wc_OBJ_sn2nid"); - - for(i=0; sn2nid[i].sn != NULL; i++) { - if (XSTRCMP(sn, sn2nid[i].sn) == 0) { - return sn2nid[i].nid; - } + for (i = 0; i < wolfssl_object_info_sz; i++, obj_info++) { + if (XSTRCMP(sn, obj_info->sName) == 0) + return obj_info->nid; } - -#ifdef HAVE_ECC - if (XSTRLEN(sn) > ECC_MAXNAME) - return WC_NID_undef; - - /* Nginx uses this OpenSSL string. */ - if (XSTRCMP(sn, "prime256v1") == 0) - sn = "SECP256R1"; - /* OpenSSL allows lowercase curve names */ - for (i = 0; i < (int)(sizeof(curveName) - 1) && *sn; i++) { - curveName[i] = (char)XTOUPPER((unsigned char) *sn++); - } - curveName[i] = '\0'; - /* find based on name and return NID */ - for (i = 0; -#ifndef WOLFSSL_ECC_CURVE_STATIC - ecc_sets[i].size != 0 && ecc_sets[i].name != NULL; -#else - ecc_sets[i].size != 0; -#endif - i++) { - if (XSTRCMP(curveName, ecc_sets[i].name) == 0) { - eccEnum = ecc_sets[i].id; - /* Convert enum value in ecc_curve_id to OpenSSL NID */ - return EccEnumToNID(eccEnum); - } - } -#endif /* HAVE_ECC */ - + WOLFSSL_MSG("short name not found in table"); return WC_NID_undef; } #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ @@ -423,6 +360,8 @@ int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx, const char* publicName, { int ret = 0; word16 encLen = DHKEM_X25519_ENC_LEN; + WOLFSSL_EchConfig* newConfig; + WOLFSSL_EchConfig* parentConfig; #ifdef WOLFSSL_SMALL_STACK Hpke* hpke = NULL; WC_RNG* rng; @@ -447,16 +386,16 @@ int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx, const char* publicName, return ret; } - ctx->echConfigs = (WOLFSSL_EchConfig*)XMALLOC(sizeof(WOLFSSL_EchConfig), + newConfig = (WOLFSSL_EchConfig*)XMALLOC(sizeof(WOLFSSL_EchConfig), ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (ctx->echConfigs == NULL) + if (newConfig == NULL) ret = MEMORY_E; else - XMEMSET(ctx->echConfigs, 0, sizeof(WOLFSSL_EchConfig)); + XMEMSET(newConfig, 0, sizeof(WOLFSSL_EchConfig)); /* set random config id */ if (ret == 0) - ret = wc_RNG_GenerateByte(rng, &ctx->echConfigs->configId); + ret = wc_RNG_GenerateByte(rng, &newConfig->configId); /* if 0 is selected for algorithms use default, may change with draft */ if (kemId == 0) @@ -470,19 +409,20 @@ int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx, const char* publicName, if (ret == 0) { /* set the kem id */ - ctx->echConfigs->kemId = kemId; + newConfig->kemId = kemId; /* set the cipher suite, only 1 for now */ - ctx->echConfigs->numCipherSuites = 1; - ctx->echConfigs->cipherSuites = (EchCipherSuite*)XMALLOC( - sizeof(EchCipherSuite), ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); + newConfig->numCipherSuites = 1; + newConfig->cipherSuites = + (EchCipherSuite*)XMALLOC(sizeof(EchCipherSuite), ctx->heap, + DYNAMIC_TYPE_TMP_BUFFER); - if (ctx->echConfigs->cipherSuites == NULL) { + if (newConfig->cipherSuites == NULL) { ret = MEMORY_E; } else { - ctx->echConfigs->cipherSuites[0].kdfId = kdfId; - ctx->echConfigs->cipherSuites[0].aeadId = aeadId; + newConfig->cipherSuites[0].kdfId = kdfId; + newConfig->cipherSuites[0].aeadId = aeadId; } } @@ -499,38 +439,47 @@ int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx, const char* publicName, /* generate the receiver private key */ if (ret == 0) - ret = wc_HpkeGenerateKeyPair(hpke, &ctx->echConfigs->receiverPrivkey, - rng); + ret = wc_HpkeGenerateKeyPair(hpke, &newConfig->receiverPrivkey, rng); /* done with RNG */ wc_FreeRng(rng); /* serialize the receiver key */ if (ret == 0) - ret = wc_HpkeSerializePublicKey(hpke, ctx->echConfigs->receiverPrivkey, - ctx->echConfigs->receiverPubkey, &encLen); + ret = wc_HpkeSerializePublicKey(hpke, newConfig->receiverPrivkey, + newConfig->receiverPubkey, &encLen); if (ret == 0) { - ctx->echConfigs->publicName = (char*)XMALLOC(XSTRLEN(publicName) + 1, + newConfig->publicName = (char*)XMALLOC(XSTRLEN(publicName) + 1, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (ctx->echConfigs->publicName == NULL) { + if (newConfig->publicName == NULL) { ret = MEMORY_E; } else { - XMEMCPY(ctx->echConfigs->publicName, publicName, + XMEMCPY(newConfig->publicName, publicName, XSTRLEN(publicName) + 1); } } if (ret != 0) { - if (ctx->echConfigs) { - XFREE(ctx->echConfigs->cipherSuites, ctx->heap, - DYNAMIC_TYPE_TMP_BUFFER); - XFREE(ctx->echConfigs->publicName, ctx->heap, - DYNAMIC_TYPE_TMP_BUFFER); - XFREE(ctx->echConfigs, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); - /* set to null to avoid double free in cleanup */ - ctx->echConfigs = NULL; + if (newConfig) { + XFREE(newConfig->cipherSuites, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(newConfig->publicName, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(newConfig, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); + } + } + else { + parentConfig = ctx->echConfigs; + + if (parentConfig == NULL) { + ctx->echConfigs = newConfig; + } + else { + while (parentConfig->next != NULL) { + parentConfig = parentConfig->next; + } + + parentConfig->next = newConfig; } } @@ -545,6 +494,59 @@ int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx, const char* publicName, return ret; } +int wolfSSL_CTX_SetEchConfigsBase64(WOLFSSL_CTX* ctx, const char* echConfigs64, + word32 echConfigs64Len) +{ + int ret = 0; + word32 decodedLen = echConfigs64Len * 3 / 4 + 1; + byte* decodedConfigs; + + if (ctx == NULL || echConfigs64 == NULL || echConfigs64Len == 0) + return BAD_FUNC_ARG; + + decodedConfigs = (byte*)XMALLOC(decodedLen, ctx->heap, + DYNAMIC_TYPE_TMP_BUFFER); + + if (decodedConfigs == NULL) + return MEMORY_E; + + decodedConfigs[decodedLen - 1] = 0; + + /* decode the echConfigs */ + ret = Base64_Decode((const byte*)echConfigs64, echConfigs64Len, + decodedConfigs, &decodedLen); + + if (ret != 0) { + XFREE(decodedConfigs, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); + return ret; + } + + ret = wolfSSL_CTX_SetEchConfigs(ctx, decodedConfigs, decodedLen); + + XFREE(decodedConfigs, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER); + + return ret; +} + +int wolfSSL_CTX_SetEchConfigs(WOLFSSL_CTX* ctx, const byte* echConfigs, + word32 echConfigsLen) +{ + int ret; + + if (ctx == NULL || echConfigs == NULL || echConfigsLen == 0) + return BAD_FUNC_ARG; + + FreeEchConfigs(ctx->echConfigs, ctx->heap); + ctx->echConfigs = NULL; + ret = SetEchConfigsEx(&ctx->echConfigs, ctx->heap, echConfigs, + echConfigsLen); + + if (ret == 0) + return WOLFSSL_SUCCESS; + + return ret; +} + /* get the ech configs that the server context is using */ int wolfSSL_CTX_GetEchConfigs(WOLFSSL_CTX* ctx, byte* output, word32* outputLen) { @@ -552,9 +554,8 @@ int wolfSSL_CTX_GetEchConfigs(WOLFSSL_CTX* ctx, byte* output, return BAD_FUNC_ARG; /* if we don't have ech configs */ - if (ctx->echConfigs == NULL) { + if (ctx->echConfigs == NULL) return WOLFSSL_FATAL_ERROR; - } return GetEchConfigsEx(ctx->echConfigs, output, outputLen); } @@ -615,7 +616,202 @@ int wolfSSL_SetEchConfigsBase64(WOLFSSL* ssl, char* echConfigs64, /* set the ech config from a raw buffer, this is the format ech configs are * sent using retry_configs from the ech server */ int wolfSSL_SetEchConfigs(WOLFSSL* ssl, const byte* echConfigs, - word32 echConfigsLen) + word32 echConfigsLen) +{ + int ret; + + if (ssl == NULL || echConfigs == NULL || echConfigsLen == 0) + return BAD_FUNC_ARG; + + /* already have ech configs */ + if (ssl->options.useEch == 1) { + return WOLFSSL_FATAL_ERROR; + } + + ret = SetEchConfigsEx(&ssl->echConfigs, ssl->heap, echConfigs, + echConfigsLen); + + /* if we found valid configs */ + if (ret == 0) { + ssl->options.useEch = 1; + return WOLFSSL_SUCCESS; + } + + return ret; +} + +/* get the raw ech config from our struct */ +int GetEchConfig(WOLFSSL_EchConfig* config, byte* output, word32* outputLen) +{ + int i; + word16 totalLen = 0; + + if (config == NULL || (output == NULL && outputLen == NULL)) + return BAD_FUNC_ARG; + + /* 2 for version */ + totalLen += 2; + /* 2 for length */ + totalLen += 2; + /* 1 for configId */ + totalLen += 1; + /* 2 for kemId */ + totalLen += 2; + /* 2 for hpke_len */ + totalLen += 2; + + /* hpke_pub_key */ + switch (config->kemId) { + case DHKEM_P256_HKDF_SHA256: + totalLen += DHKEM_P256_ENC_LEN; + break; + case DHKEM_P384_HKDF_SHA384: + totalLen += DHKEM_P384_ENC_LEN; + break; + case DHKEM_P521_HKDF_SHA512: + totalLen += DHKEM_P521_ENC_LEN; + break; + case DHKEM_X25519_HKDF_SHA256: + totalLen += DHKEM_X25519_ENC_LEN; + break; + case DHKEM_X448_HKDF_SHA512: + totalLen += DHKEM_X448_ENC_LEN; + break; + } + + /* cipherSuitesLen */ + totalLen += 2; + /* cipherSuites */ + totalLen += config->numCipherSuites * 4; + /* public name len */ + totalLen += 2; + + /* public name */ + totalLen += XSTRLEN(config->publicName); + /* trailing zeros */ + totalLen += 2; + + if (output == NULL) { + *outputLen = totalLen; + return WC_NO_ERR_TRACE(LENGTH_ONLY_E); + } + + if (totalLen > *outputLen) { + *outputLen = totalLen; + return INPUT_SIZE_E; + } + + /* version */ + c16toa(TLSX_ECH, output); + output += 2; + + /* length - 4 for version and length itself */ + c16toa(totalLen - 4, output); + output += 2; + + /* configId */ + *output = config->configId; + output++; + /* kemId */ + c16toa(config->kemId, output); + output += 2; + + /* length and key itself */ + switch (config->kemId) { + case DHKEM_P256_HKDF_SHA256: + c16toa(DHKEM_P256_ENC_LEN, output); + output += 2; + XMEMCPY(output, config->receiverPubkey, DHKEM_P256_ENC_LEN); + output += DHKEM_P256_ENC_LEN; + break; + case DHKEM_P384_HKDF_SHA384: + c16toa(DHKEM_P384_ENC_LEN, output); + output += 2; + XMEMCPY(output, config->receiverPubkey, DHKEM_P384_ENC_LEN); + output += DHKEM_P384_ENC_LEN; + break; + case DHKEM_P521_HKDF_SHA512: + c16toa(DHKEM_P521_ENC_LEN, output); + output += 2; + XMEMCPY(output, config->receiverPubkey, DHKEM_P521_ENC_LEN); + output += DHKEM_P521_ENC_LEN; + break; + case DHKEM_X25519_HKDF_SHA256: + c16toa(DHKEM_X25519_ENC_LEN, output); + output += 2; + XMEMCPY(output, config->receiverPubkey, DHKEM_X25519_ENC_LEN); + output += DHKEM_X25519_ENC_LEN; + break; + case DHKEM_X448_HKDF_SHA512: + c16toa(DHKEM_X448_ENC_LEN, output); + output += 2; + XMEMCPY(output, config->receiverPubkey, DHKEM_X448_ENC_LEN); + output += DHKEM_X448_ENC_LEN; + break; + } + + /* cipherSuites len */ + c16toa(config->numCipherSuites * 4, output); + output += 2; + + /* cipherSuites */ + for (i = 0; i < config->numCipherSuites; i++) { + c16toa(config->cipherSuites[i].kdfId, output); + output += 2; + c16toa(config->cipherSuites[i].aeadId, output); + output += 2; + } + + /* set maximum name length to 0 */ + *output = 0; + output++; + + /* publicName len */ + *output = XSTRLEN(config->publicName); + output++; + + /* publicName */ + XMEMCPY(output, config->publicName, + XSTRLEN(config->publicName)); + output += XSTRLEN(config->publicName); + + /* terminating zeros */ + c16toa(0, output); + /* output += 2; */ + + *outputLen = totalLen; + + return 0; +} + +/* wrapper function to get ech configs from application code */ +int wolfSSL_GetEchConfigs(WOLFSSL* ssl, byte* output, word32* outputLen) +{ + if (ssl == NULL || outputLen == NULL) + return BAD_FUNC_ARG; + + /* if we don't have ech configs */ + if (ssl->options.useEch != 1) { + return WOLFSSL_FATAL_ERROR; + } + + return GetEchConfigsEx(ssl->echConfigs, output, outputLen); +} + +void wolfSSL_SetEchEnable(WOLFSSL* ssl, byte enable) +{ + if (ssl != NULL) { + ssl->options.disableECH = !enable; + if (ssl->options.disableECH) { + TLSX_Remove(&ssl->extensions, TLSX_ECH, ssl->heap); + FreeEchConfigs(ssl->echConfigs, ssl->heap); + ssl->echConfigs = NULL; + } + } +} + +int SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap, + const byte* echConfigs, word32 echConfigsLen) { int ret = 0; int i; @@ -631,14 +827,9 @@ int wolfSSL_SetEchConfigs(WOLFSSL* ssl, const byte* echConfigs, WOLFSSL_EchConfig* lastConfig = NULL; byte* echConfig = NULL; - if (ssl == NULL || echConfigs == NULL || echConfigsLen == 0) + if (outputConfigs == NULL || echConfigs == NULL || echConfigsLen == 0) return BAD_FUNC_ARG; - /* already have ech configs */ - if (ssl->options.useEch == 1) { - return WOLFSSL_FATAL_ERROR; - } - /* check that the total length is well formed */ ato16(echConfigs, &totalLength); @@ -673,8 +864,8 @@ int wolfSSL_SetEchConfigs(WOLFSSL* ssl, const byte* echConfigs, if (workingConfig == NULL) { workingConfig = - (WOLFSSL_EchConfig*)XMALLOC(sizeof(WOLFSSL_EchConfig), - ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + (WOLFSSL_EchConfig*)XMALLOC(sizeof(WOLFSSL_EchConfig), heap, + DYNAMIC_TYPE_TMP_BUFFER); configList = workingConfig; if (workingConfig != NULL) { workingConfig->next = NULL; @@ -684,7 +875,7 @@ int wolfSSL_SetEchConfigs(WOLFSSL* ssl, const byte* echConfigs, lastConfig = workingConfig; workingConfig->next = (WOLFSSL_EchConfig*)XMALLOC(sizeof(WOLFSSL_EchConfig), - ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + heap, DYNAMIC_TYPE_TMP_BUFFER); workingConfig = workingConfig->next; } @@ -700,7 +891,7 @@ int wolfSSL_SetEchConfigs(WOLFSSL* ssl, const byte* echConfigs, /* raw body */ workingConfig->raw = (byte*)XMALLOC(workingConfig->rawLen, - ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + heap, DYNAMIC_TYPE_TMP_BUFFER); if (workingConfig->raw == NULL) { ret = MEMORY_E; break; @@ -727,7 +918,7 @@ int wolfSSL_SetEchConfigs(WOLFSSL* ssl, const byte* echConfigs, ato16(echConfig, &cipherSuitesLen); workingConfig->cipherSuites = (EchCipherSuite*)XMALLOC(cipherSuitesLen, - ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + heap, DYNAMIC_TYPE_TMP_BUFFER); if (workingConfig->cipherSuites == NULL) { ret = MEMORY_E; break; @@ -742,16 +933,17 @@ int wolfSSL_SetEchConfigs(WOLFSSL* ssl, const byte* echConfigs, &workingConfig->cipherSuites[j].aeadId); } echConfig += cipherSuitesLen; + /* ignore the maximum name length */ + echConfig++; /* publicNameLen */ - ato16(echConfig, &publicNameLen); + publicNameLen = *(echConfig); workingConfig->publicName = (char*)XMALLOC(publicNameLen + 1, - ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + heap, DYNAMIC_TYPE_TMP_BUFFER); if (workingConfig->publicName == NULL) { ret = MEMORY_E; break; } - - echConfig += 2; + echConfig++; /* publicName */ XMEMCPY(workingConfig->publicName, echConfig, publicNameLen); /* null terminated */ @@ -770,206 +962,39 @@ int wolfSSL_SetEchConfigs(WOLFSSL* ssl, const byte* echConfigs, if (j >= HPKE_SUPPORTED_KEM_LEN || EchConfigGetSupportedCipherSuite(workingConfig) < 0) { - XFREE(workingConfig->cipherSuites, ssl->heap, + XFREE(workingConfig->cipherSuites, heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(workingConfig->publicName, ssl->heap, + XFREE(workingConfig->publicName, heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(workingConfig->raw, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(workingConfig->raw, heap, DYNAMIC_TYPE_TMP_BUFFER); workingConfig = lastConfig; } } while ((word32)i < echConfigsLen); - /* if we found valid configs */ - if (ret == 0 && configList != NULL) { - ssl->options.useEch = 1; - ssl->echConfigs = configList; - - return WOLFSSL_SUCCESS; - } - - workingConfig = configList; - - while (workingConfig != NULL) { - lastConfig = workingConfig; - workingConfig = workingConfig->next; - - XFREE(lastConfig->cipherSuites, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(lastConfig->publicName, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(lastConfig->raw, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - - XFREE(lastConfig, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - } - - if (ret == 0) - return WOLFSSL_FATAL_ERROR; - - return ret; -} - -/* get the raw ech config from our struct */ -int GetEchConfig(WOLFSSL_EchConfig* config, byte* output, word32* outputLen) -{ - int i; - word16 totalLen = 0; - - if (config == NULL || (output == NULL && outputLen == NULL)) - return BAD_FUNC_ARG; - - /* 2 for version */ - totalLen += 2; - /* 2 for length */ - totalLen += 2; - /* 1 for configId */ - totalLen += 1; - /* 2 for kemId */ - totalLen += 2; - /* 2 for hpke_len */ - totalLen += 2; - - /* hpke_pub_key */ - switch (config->kemId) { - case DHKEM_P256_HKDF_SHA256: - totalLen += DHKEM_P256_ENC_LEN; - break; - case DHKEM_P384_HKDF_SHA384: - totalLen += DHKEM_P384_ENC_LEN; - break; - case DHKEM_P521_HKDF_SHA512: - totalLen += DHKEM_P521_ENC_LEN; - break; - case DHKEM_X25519_HKDF_SHA256: - totalLen += DHKEM_X25519_ENC_LEN; - break; - case DHKEM_X448_HKDF_SHA512: - totalLen += DHKEM_X448_ENC_LEN; - break; - } - - /* cipherSuitesLen */ - totalLen += 2; - /* cipherSuites */ - totalLen += config->numCipherSuites * 4; - /* public name len */ - totalLen += 2; - - /* public name */ - totalLen += XSTRLEN(config->publicName); - /* trailing zeros */ - totalLen += 2; - - if (output == NULL) { - *outputLen = totalLen; - return WC_NO_ERR_TRACE(LENGTH_ONLY_E); - } - - if (totalLen > *outputLen) { - *outputLen = totalLen; - return INPUT_SIZE_E; - } - - /* version */ - c16toa(TLSX_ECH, output); - output += 2; - - /* length - 4 for version and length itself */ - c16toa(totalLen - 4, output); - output += 2; - - /* configId */ - *output = config->configId; - output++; - /* kemId */ - c16toa(config->kemId, output); - output += 2; - - /* length and key itself */ - switch (config->kemId) { - case DHKEM_P256_HKDF_SHA256: - c16toa(DHKEM_P256_ENC_LEN, output); - output += 2; - XMEMCPY(output, config->receiverPubkey, DHKEM_P256_ENC_LEN); - output += DHKEM_P256_ENC_LEN; - break; - case DHKEM_P384_HKDF_SHA384: - c16toa(DHKEM_P384_ENC_LEN, output); - output += 2; - XMEMCPY(output, config->receiverPubkey, DHKEM_P384_ENC_LEN); - output += DHKEM_P384_ENC_LEN; - break; - case DHKEM_P521_HKDF_SHA512: - c16toa(DHKEM_P521_ENC_LEN, output); - output += 2; - XMEMCPY(output, config->receiverPubkey, DHKEM_P521_ENC_LEN); - output += DHKEM_P521_ENC_LEN; - break; - case DHKEM_X25519_HKDF_SHA256: - c16toa(DHKEM_X25519_ENC_LEN, output); - output += 2; - XMEMCPY(output, config->receiverPubkey, DHKEM_X25519_ENC_LEN); - output += DHKEM_X25519_ENC_LEN; - break; - case DHKEM_X448_HKDF_SHA512: - c16toa(DHKEM_X448_ENC_LEN, output); - output += 2; - XMEMCPY(output, config->receiverPubkey, DHKEM_X448_ENC_LEN); - output += DHKEM_X448_ENC_LEN; - break; - } - - /* cipherSuites len */ - c16toa(config->numCipherSuites * 4, output); - output += 2; - - /* cipherSuites */ - for (i = 0; i < config->numCipherSuites; i++) { - c16toa(config->cipherSuites[i].kdfId, output); - output += 2; - c16toa(config->cipherSuites[i].aeadId, output); - output += 2; - } - - /* publicName len */ - c16toa(XSTRLEN(config->publicName), output); - output += 2; - - /* publicName */ - XMEMCPY(output, config->publicName, - XSTRLEN(config->publicName)); - output += XSTRLEN(config->publicName); + /* if we found valid configs */ + if (ret == 0 && configList != NULL) { + *outputConfigs = configList; - /* terminating zeros */ - c16toa(0, output); - /* output += 2; */ + return ret; + } - *outputLen = totalLen; + workingConfig = configList; - return 0; -} + while (workingConfig != NULL) { + lastConfig = workingConfig; + workingConfig = workingConfig->next; -/* wrapper function to get ech configs from application code */ -int wolfSSL_GetEchConfigs(WOLFSSL* ssl, byte* output, word32* outputLen) -{ - if (ssl == NULL || outputLen == NULL) - return BAD_FUNC_ARG; + XFREE(lastConfig->cipherSuites, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(lastConfig->publicName, heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(lastConfig->raw, heap, DYNAMIC_TYPE_TMP_BUFFER); - /* if we don't have ech configs */ - if (ssl->options.useEch != 1) { - return WOLFSSL_FATAL_ERROR; + XFREE(lastConfig, heap, DYNAMIC_TYPE_TMP_BUFFER); } - return GetEchConfigsEx(ssl->echConfigs, output, outputLen); -} + if (ret == 0) + return WOLFSSL_FATAL_ERROR; -void wolfSSL_SetEchEnable(WOLFSSL* ssl, byte enable) -{ - if (ssl != NULL) { - ssl->options.disableECH = !enable; - if (ssl->options.disableECH) { - TLSX_Remove(&ssl->extensions, TLSX_ECH, ssl->heap); - FreeEchConfigs(ssl->echConfigs, ssl->heap); - ssl->echConfigs = NULL; - } - } + return ret; } /* get the raw ech configs from our linked list of ech config structs */ @@ -981,7 +1006,7 @@ int GetEchConfigsEx(WOLFSSL_EchConfig* configs, byte* output, word32* outputLen) word32 totalLen = 2; word32 workingOutputLen; - if (configs == NULL || outputLen == NULL) + if (configs == NULL || outputLen == NULL || *outputLen < totalLen) return BAD_FUNC_ARG; workingOutputLen = *outputLen - totalLen; @@ -1194,16 +1219,6 @@ void wolfSSL_CTX_free(WOLFSSL_CTX* ctx) { WOLFSSL_ENTER("wolfSSL_CTX_free"); if (ctx) { -#if defined(OPENSSL_EXTRA) && defined(WOLFCRYPT_HAVE_SRP) \ -&& !defined(NO_SHA256) && !defined(WC_NO_RNG) - if (ctx->srp != NULL) { - XFREE(ctx->srp_password, ctx->heap, DYNAMIC_TYPE_SRP); - ctx->srp_password = NULL; - wc_SrpTerm(ctx->srp); - XFREE(ctx->srp, ctx->heap, DYNAMIC_TYPE_SRP); - ctx->srp = NULL; - } -#endif FreeSSL_Ctx(ctx); } @@ -1689,7 +1704,7 @@ int wolfSSL_get_ciphers(char* buf, int len) for (i = 0; i < ciphersSz; i++) { int cipherNameSz = (int)XSTRLEN(ciphers[i].name); if (cipherNameSz + 1 < len) { - XSTRNCPY(buf, ciphers[i].name, len); + XSTRNCPY(buf, ciphers[i].name, (size_t)len); buf += cipherNameSz; if (i < ciphersSz - 1) @@ -1726,7 +1741,7 @@ int wolfSSL_get_ciphers_iana(char* buf, int len) #endif cipherNameSz = (int)XSTRLEN(ciphers[i].name_iana); if (cipherNameSz + 1 < len) { - XSTRNCPY(buf, ciphers[i].name_iana, len); + XSTRNCPY(buf, ciphers[i].name_iana, (size_t)len); buf += cipherNameSz; if (i < ciphersSz - 1) @@ -1752,7 +1767,7 @@ const char* wolfSSL_get_shared_ciphers(WOLFSSL* ssl, char* buf, int len) cipher = wolfSSL_get_cipher_name_iana(ssl); len = (int)min((word32)len, (word32)(XSTRLEN(cipher) + 1)); - XMEMCPY(buf, cipher, len); + XMEMCPY(buf, cipher, (size_t)len); return buf; } @@ -2124,14 +2139,17 @@ int wolfSSL_dtls_set_mtu(WOLFSSL* ssl, word16 newMtu) return WOLFSSL_SUCCESS; } -#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) -int wolfSSL_set_mtu_compat(WOLFSSL* ssl, unsigned short mtu) { - if (wolfSSL_dtls_set_mtu(ssl, mtu) == 0) +#ifdef OPENSSL_EXTRA +/* Maps to compatibility API SSL_set_mtu and is same as wolfSSL_dtls_set_mtu, + * but expects only success or failure returns. */ +int wolfSSL_set_mtu_compat(WOLFSSL* ssl, unsigned short mtu) +{ + if (wolfSSL_dtls_set_mtu(ssl, mtu) == WOLFSSL_SUCCESS) return WOLFSSL_SUCCESS; else return WOLFSSL_FAILURE; } -#endif /* OPENSSL_ALL || OPENSSL_EXTRA */ +#endif /* OPENSSL_EXTRA */ #endif /* WOLFSSL_DTLS && (WOLFSSL_SCTP || WOLFSSL_DTLS_MTU) */ @@ -2218,6 +2236,15 @@ static int DtlsSrtpSelProfiles(word16* id, const char* profile_str) return WOLFSSL_SUCCESS; } +/** + * @brief Set the SRTP protection profiles for DTLS. + * + * @param ctx Pointer to the WOLFSSL_CTX structure representing the SSL/TLS + * context. + * @param profile_str A colon-separated string of SRTP profile names. + * @return 0 on success to match OpenSSL + * @return 1 on error to match OpenSSL + */ int wolfSSL_CTX_set_tlsext_use_srtp(WOLFSSL_CTX* ctx, const char* profile_str) { int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE); @@ -2233,6 +2260,16 @@ int wolfSSL_CTX_set_tlsext_use_srtp(WOLFSSL_CTX* ctx, const char* profile_str) return ret; } + +/** + * @brief Set the SRTP protection profiles for DTLS. + * + * @param ssl Pointer to the WOLFSSL structure representing the SSL/TLS + * session. + * @param profile_str A colon-separated string of SRTP profile names. + * @return 0 on success to match OpenSSL + * @return 1 on error to match OpenSSL + */ int wolfSSL_set_tlsext_use_srtp(WOLFSSL* ssl, const char* profile_str) { int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE); @@ -2294,7 +2331,7 @@ int wolfSSL_export_dtls_srtp_keying_material(WOLFSSL* ssl, return BUFFER_E; } - return wolfSSL_export_keying_material(ssl, out, profile->kdfBits, + return wolfSSL_export_keying_material(ssl, out, (size_t)profile->kdfBits, DTLS_SRTP_KEYING_MATERIAL_LABEL, XSTR_SIZEOF(DTLS_SRTP_KEYING_MATERIAL_LABEL), NULL, 0, 0); } @@ -2845,23 +2882,32 @@ int wolfSSL_GetOutputSize(WOLFSSL* ssl, int inSz) #ifdef HAVE_ECC int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz) { + short keySzBytes; + WOLFSSL_ENTER("wolfSSL_CTX_SetMinEccKey_Sz"); - if (ctx == NULL || keySz < 0 || keySz % 8 != 0) { - WOLFSSL_MSG("Key size must be divisible by 8 or ctx was null"); + if (ctx == NULL || keySz < 0) { + WOLFSSL_MSG("Key size must be positive value or ctx was null"); return BAD_FUNC_ARG; } + if (keySz % 8 == 0) { + keySzBytes = keySz / 8; + } + else { + keySzBytes = (keySz / 8) + 1; + } + #if defined(WOLFSSL_SYS_CRYPTO_POLICY) if (crypto_policy.enabled) { - if (ctx->minEccKeySz > (keySz / 8)) { + if (ctx->minEccKeySz > (keySzBytes)) { return CRYPTO_POLICY_FORBIDDEN; } } #endif /* WOLFSSL_SYS_CRYPTO_POLICY */ - ctx->minEccKeySz = keySz / 8; + ctx->minEccKeySz = keySzBytes; #ifndef NO_CERTS - ctx->cm->minEccKeySz = keySz / 8; + ctx->cm->minEccKeySz = keySzBytes; #endif return WOLFSSL_SUCCESS; } @@ -2869,21 +2915,30 @@ int wolfSSL_CTX_SetMinEccKey_Sz(WOLFSSL_CTX* ctx, short keySz) int wolfSSL_SetMinEccKey_Sz(WOLFSSL* ssl, short keySz) { + short keySzBytes; + WOLFSSL_ENTER("wolfSSL_SetMinEccKey_Sz"); - if (ssl == NULL || keySz < 0 || keySz % 8 != 0) { - WOLFSSL_MSG("Key size must be divisible by 8 or ssl was null"); + if (ssl == NULL || keySz < 0) { + WOLFSSL_MSG("Key size must be positive value or ctx was null"); return BAD_FUNC_ARG; } + if (keySz % 8 == 0) { + keySzBytes = keySz / 8; + } + else { + keySzBytes = (keySz / 8) + 1; + } + #if defined(WOLFSSL_SYS_CRYPTO_POLICY) if (crypto_policy.enabled) { - if (ssl->options.minEccKeySz > (keySz / 8)) { + if (ssl->options.minEccKeySz > (keySzBytes)) { return CRYPTO_POLICY_FORBIDDEN; } } #endif /* WOLFSSL_SYS_CRYPTO_POLICY */ - ssl->options.minEccKeySz = keySz / 8; + ssl->options.minEccKeySz = keySzBytes; return WOLFSSL_SUCCESS; } @@ -3036,14 +3091,13 @@ int wolfSSL_GetDhKey_Sz(WOLFSSL* ssl) #endif /* !NO_DH */ -WOLFSSL_ABI -int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz) +static int wolfSSL_write_internal(WOLFSSL* ssl, const void* data, size_t sz) { int ret; WOLFSSL_ENTER("wolfSSL_write"); - if (ssl == NULL || data == NULL || sz < 0) + if (ssl == NULL || data == NULL) return BAD_FUNC_ARG; #ifdef WOLFSSL_QUIC @@ -3103,6 +3157,17 @@ int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz) return ret; } +WOLFSSL_ABI +int wolfSSL_write(WOLFSSL* ssl, const void* data, int sz) +{ + WOLFSSL_ENTER("wolfSSL_write"); + + if (sz < 0) + return BAD_FUNC_ARG; + + return wolfSSL_write_internal(ssl, data, (size_t)sz); +} + int wolfSSL_inject(WOLFSSL* ssl, const void* data, int sz) { int maxLength; @@ -3139,13 +3204,50 @@ int wolfSSL_inject(WOLFSSL* ssl, const void* data, int sz) return WOLFSSL_SUCCESS; } -static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, int sz, int peek) + +int wolfSSL_write_ex(WOLFSSL* ssl, const void* data, size_t sz, size_t* wr) +{ + int ret; + + if (wr != NULL) { + *wr = 0; + } + + ret = wolfSSL_write_internal(ssl, data, sz); + if (ret >= 0) { + if (wr != NULL) { + *wr = (size_t)ret; + } + + /* handle partial write cases, if not set then a partial write is + * considered a failure case, or if set and ret is 0 then is a fail */ + if (ret == 0 && ssl->options.partialWrite) { + ret = 0; + } + else if ((size_t)ret < sz && !ssl->options.partialWrite) { + ret = 0; + } + else { + /* wrote out all application data, or wrote out 1 byte or more with + * partial write flag set */ + ret = 1; + } + } + else { + ret = 0; + } + + return ret; +} + + +static int wolfSSL_read_internal(WOLFSSL* ssl, void* data, size_t sz, int peek) { int ret; WOLFSSL_ENTER("wolfSSL_read_internal"); - if (ssl == NULL || data == NULL || sz < 0) + if (ssl == NULL || data == NULL) return BAD_FUNC_ARG; #ifdef WOLFSSL_QUIC @@ -3223,7 +3325,10 @@ int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz) { WOLFSSL_ENTER("wolfSSL_peek"); - return wolfSSL_read_internal(ssl, data, sz, TRUE); + if (sz < 0) + return BAD_FUNC_ARG; + + return wolfSSL_read_internal(ssl, data, (size_t)sz, TRUE); } @@ -3232,6 +3337,9 @@ int wolfSSL_read(WOLFSSL* ssl, void* data, int sz) { WOLFSSL_ENTER("wolfSSL_read"); + if (sz < 0) + return BAD_FUNC_ARG; + #ifdef OPENSSL_EXTRA if (ssl == NULL) { return BAD_FUNC_ARG; @@ -3241,10 +3349,34 @@ int wolfSSL_read(WOLFSSL* ssl, void* data, int sz) ssl->cbmode = WOLFSSL_CB_READ; } #endif - return wolfSSL_read_internal(ssl, data, sz, FALSE); + return wolfSSL_read_internal(ssl, data, (size_t)sz, FALSE); } +/* returns 0 on failure and on no read */ +int wolfSSL_read_ex(WOLFSSL* ssl, void* data, size_t sz, size_t* rd) +{ + int ret; + + #ifdef OPENSSL_EXTRA + if (ssl == NULL) { + return BAD_FUNC_ARG; + } + if (ssl->CBIS != NULL) { + ssl->CBIS(ssl, WOLFSSL_CB_READ, WOLFSSL_SUCCESS); + ssl->cbmode = WOLFSSL_CB_READ; + } + #endif + ret = wolfSSL_read_internal(ssl, data, sz, FALSE); + + if (ret > 0 && rd != NULL) { + *rd = (size_t)ret; + } + + if (ret <= 0) ret = 0; + return ret; +} + #ifdef WOLFSSL_MULTICAST int wolfSSL_mcast_read(WOLFSSL* ssl, word16* id, void* data, int sz) @@ -3253,10 +3385,10 @@ int wolfSSL_mcast_read(WOLFSSL* ssl, word16* id, void* data, int sz) WOLFSSL_ENTER("wolfSSL_mcast_read"); - if (ssl == NULL) + if ((ssl == NULL) || (sz < 0)) return BAD_FUNC_ARG; - ret = wolfSSL_read_internal(ssl, data, sz, FALSE); + ret = wolfSSL_read_internal(ssl, data, (size_t)sz, FALSE); if (ssl->options.dtls && ssl->options.haveMcast && id != NULL) *id = ssl->keys.curPeerId; return ret; @@ -3562,27 +3694,36 @@ static int isValidCurveGroup(word16 name) case WOLFSSL_FFDHE_6144: case WOLFSSL_FFDHE_8192: -#ifdef WOLFSSL_HAVE_KYBER +#ifdef WOLFSSL_HAVE_MLKEM #ifndef WOLFSSL_NO_ML_KEM case WOLFSSL_ML_KEM_512: case WOLFSSL_ML_KEM_768: case WOLFSSL_ML_KEM_1024: - #if defined(WOLFSSL_WC_KYBER) || defined(HAVE_LIBOQS) + #if defined(WOLFSSL_WC_MLKEM) || defined(HAVE_LIBOQS) case WOLFSSL_P256_ML_KEM_512: case WOLFSSL_P384_ML_KEM_768: case WOLFSSL_P521_ML_KEM_1024: + case WOLFSSL_P384_ML_KEM_1024: + case WOLFSSL_X25519_ML_KEM_512: + case WOLFSSL_X448_ML_KEM_768: + case WOLFSSL_X25519_ML_KEM_768: + case WOLFSSL_P256_ML_KEM_768: #endif #endif /* !WOLFSSL_NO_ML_KEM */ -#ifdef WOLFSSL_KYBER_ORIGINAL +#ifdef WOLFSSL_MLKEM_KYBER case WOLFSSL_KYBER_LEVEL1: case WOLFSSL_KYBER_LEVEL3: case WOLFSSL_KYBER_LEVEL5: - #if defined(WOLFSSL_WC_KYBER) || defined(HAVE_LIBOQS) + #if defined(WOLFSSL_WC_MLKEM) || defined(HAVE_LIBOQS) case WOLFSSL_P256_KYBER_LEVEL1: case WOLFSSL_P384_KYBER_LEVEL3: case WOLFSSL_P521_KYBER_LEVEL5: + case WOLFSSL_X25519_KYBER_LEVEL1: + case WOLFSSL_X448_KYBER_LEVEL3: + case WOLFSSL_X25519_KYBER_LEVEL3: + case WOLFSSL_P256_KYBER_LEVEL3: #endif -#endif /* WOLFSSL_KYBER_ORIGINAL */ +#endif /* WOLFSSL_MLKEM_KYBER */ #endif return 1; @@ -3808,7 +3949,7 @@ int wolfSSL_ALPN_GetPeerProtocol(WOLFSSL* ssl, char **list, word16 *listSz) *list = NULL; return WOLFSSL_FAILURE; } - XMEMCPY(p, s + i, len); + XMEMCPY(p, s + i, (size_t)len); } *p = 0; @@ -5805,6 +5946,7 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) break; #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT case DILITHIUM_LEVEL2k: if (cm->minDilithiumKeySz < 0 || DILITHIUM_LEVEL2_KEY_SIZE < (word16)cm->minDilithiumKeySz) { @@ -5826,6 +5968,28 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) WOLFSSL_MSG("\tCA Dilithium level 5 key size error"); } break; + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ + case ML_DSA_LEVEL2k: + if (cm->minDilithiumKeySz < 0 || + ML_DSA_LEVEL2_KEY_SIZE < (word16)cm->minDilithiumKeySz) { + ret = DILITHIUM_KEY_SIZE_E; + WOLFSSL_MSG("\tCA Dilithium level 2 key size error"); + } + break; + case ML_DSA_LEVEL3k: + if (cm->minDilithiumKeySz < 0 || + ML_DSA_LEVEL3_KEY_SIZE < (word16)cm->minDilithiumKeySz) { + ret = DILITHIUM_KEY_SIZE_E; + WOLFSSL_MSG("\tCA Dilithium level 3 key size error"); + } + break; + case ML_DSA_LEVEL5k: + if (cm->minDilithiumKeySz < 0 || + ML_DSA_LEVEL5_KEY_SIZE < (word16)cm->minDilithiumKeySz) { + ret = DILITHIUM_KEY_SIZE_E; + WOLFSSL_MSG("\tCA Dilithium level 5 key size error"); + } + break; #endif /* HAVE_DILITHIUM */ default: @@ -6844,9 +7008,15 @@ static int check_cert_key_dev(word32 keyOID, byte* privKey, word32 privSz, } #endif #if defined(HAVE_DILITHIUM) - if ((keyOID == DILITHIUM_LEVEL2k) || - (keyOID == DILITHIUM_LEVEL3k) || - (keyOID == DILITHIUM_LEVEL5k)) { + if ((keyOID == ML_DSA_LEVEL2k) || + (keyOID == ML_DSA_LEVEL3k) || + (keyOID == ML_DSA_LEVEL5k) + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT + || (keyOID == DILITHIUM_LEVEL2k) + || (keyOID == DILITHIUM_LEVEL3k) + || (keyOID == DILITHIUM_LEVEL5k) + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ + ) { type = DYNAMIC_TYPE_DILITHIUM; } #endif @@ -6876,9 +7046,15 @@ static int check_cert_key_dev(word32 keyOID, byte* privKey, word32 privSz, } #endif #if defined(HAVE_DILITHIUM) - if ((keyOID == DILITHIUM_LEVEL2k) || - (keyOID == DILITHIUM_LEVEL3k) || - (keyOID == DILITHIUM_LEVEL5k)) { + if ((keyOID == ML_DSA_LEVEL2k) || + (keyOID == ML_DSA_LEVEL3k) || + (keyOID == ML_DSA_LEVEL5k) + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT + || (keyOID == DILITHIUM_LEVEL2k) + || (keyOID == DILITHIUM_LEVEL3k) + || (keyOID == DILITHIUM_LEVEL5k) + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ + ) { ret = wc_CryptoCb_PqcSignatureCheckPrivKey(pkey, WC_PQC_SIG_TYPE_DILITHIUM, pubKey, pubSz); @@ -6915,9 +7091,15 @@ static int check_cert_key_dev(word32 keyOID, byte* privKey, word32 privSz, } #endif #if defined(HAVE_DILITHIUM) - if ((keyOID == DILITHIUM_LEVEL2k) || - (keyOID == DILITHIUM_LEVEL3k) || - (keyOID == DILITHIUM_LEVEL5k)) { + if ((keyOID == ML_DSA_LEVEL2k) || + (keyOID == ML_DSA_LEVEL3k) || + (keyOID == ML_DSA_LEVEL5k) + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT + || (keyOID == DILITHIUM_LEVEL2k) + || (keyOID == DILITHIUM_LEVEL3k) + || (keyOID == DILITHIUM_LEVEL5k) + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ + ) { wc_dilithium_free((dilithium_key*)pkey); } #endif @@ -7129,6 +7311,11 @@ int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx) #endif #endif + /* placing error into error queue for Python port */ + if (res != WOLFSSL_SUCCESS) { + WOLFSSL_ERROR(WC_KEY_MISMATCH_E); + } + return res; } #endif /* !NO_CHECK_PRIVATE_KEY */ @@ -7252,7 +7439,7 @@ static int d2iTryRsaKey(WOLFSSL_EVP_PKEY** out, const unsigned char* mem, } pkey->pkey_sz = (int)keyIdx; - pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL, + pkey->pkey.ptr = (char*)XMALLOC((size_t)memSz, NULL, priv ? DYNAMIC_TYPE_PRIVATE_KEY : DYNAMIC_TYPE_PUBLIC_KEY); if (pkey->pkey.ptr == NULL) { @@ -7424,7 +7611,7 @@ static int d2iTryDsaKey(WOLFSSL_EVP_PKEY** out, const unsigned char* mem, } pkey->pkey_sz = (int)keyIdx; - pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL, + pkey->pkey.ptr = (char*)XMALLOC((size_t)memSz, NULL, priv ? DYNAMIC_TYPE_PRIVATE_KEY : DYNAMIC_TYPE_PUBLIC_KEY); if (pkey->pkey.ptr == NULL) { @@ -7508,14 +7695,14 @@ static int d2iTryDhKey(WOLFSSL_EVP_PKEY** out, const unsigned char* mem, } pkey->pkey_sz = (int)memSz; - pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL, + pkey->pkey.ptr = (char*)XMALLOC((size_t)memSz, NULL, priv ? DYNAMIC_TYPE_PRIVATE_KEY : DYNAMIC_TYPE_PUBLIC_KEY); if (pkey->pkey.ptr == NULL) { ret = 0; } if (ret == 1) { - XMEMCPY(pkey->pkey.ptr, mem, memSz); + XMEMCPY(pkey->pkey.ptr, mem, (size_t)memSz); pkey->type = WC_EVP_PKEY_DH; pkey->ownDh = 1; @@ -7593,14 +7780,14 @@ static int d2iTryAltDhKey(WOLFSSL_EVP_PKEY** out, const unsigned char* mem, ret = 1; pkey->type = WC_EVP_PKEY_DH; pkey->pkey_sz = (int)memSz; - pkey->pkey.ptr = (char*)XMALLOC(memSz, NULL, + pkey->pkey.ptr = (char*)XMALLOC((size_t)memSz, NULL, priv ? DYNAMIC_TYPE_PRIVATE_KEY : DYNAMIC_TYPE_PUBLIC_KEY); if (pkey->pkey.ptr == NULL) { ret = 0; } if (ret == 1) { - XMEMCPY(pkey->pkey.ptr, mem, memSz); + XMEMCPY(pkey->pkey.ptr, mem, (size_t)memSz); pkey->ownDh = 1; pkey->dh = wolfSSL_DH_new(); if (pkey->dh == NULL) { @@ -7742,31 +7929,31 @@ static int d2iTryDilithiumKey(WOLFSSL_EVP_PKEY** out, const unsigned char* mem, /* Test if Dilithium key. Try all levels. */ if (priv) { - isDilithium = ((wc_dilithium_set_level(dilithium, 2) == 0) && + isDilithium = ((wc_dilithium_set_level(dilithium, WC_ML_DSA_44) == 0) && (wc_dilithium_import_private(mem, (word32)memSz, dilithium) == 0)); if (!isDilithium) { - isDilithium = ((wc_dilithium_set_level(dilithium, 3) == 0) && + isDilithium = ((wc_dilithium_set_level(dilithium, WC_ML_DSA_65) == 0) && (wc_dilithium_import_private(mem, (word32)memSz, dilithium) == 0)); } if (!isDilithium) { - isDilithium = ((wc_dilithium_set_level(dilithium, 5) == 0) && + isDilithium = ((wc_dilithium_set_level(dilithium, WC_ML_DSA_87) == 0) && (wc_dilithium_import_private(mem, (word32)memSz, dilithium) == 0)); } } else { - isDilithium = ((wc_dilithium_set_level(dilithium, 2) == 0) && + isDilithium = ((wc_dilithium_set_level(dilithium, WC_ML_DSA_44) == 0) && (wc_dilithium_import_public(mem, (word32)memSz, dilithium) == 0)); if (!isDilithium) { - isDilithium = ((wc_dilithium_set_level(dilithium, 3) == 0) && + isDilithium = ((wc_dilithium_set_level(dilithium, WC_ML_DSA_65) == 0) && (wc_dilithium_import_public(mem, (word32)memSz, dilithium) == 0)); } if (!isDilithium) { - isDilithium = ((wc_dilithium_set_level(dilithium, 5) == 0) && + isDilithium = ((wc_dilithium_set_level(dilithium, WC_ML_DSA_87) == 0) && (wc_dilithium_import_public(mem, (word32)memSz, dilithium) == 0)); } @@ -7921,16 +8108,16 @@ WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY( pkcs8Der->length, &algId); if (ret >= 0) { if (advanceLen == 0) /* Set only if not PEM */ - advanceLen = inOutIdx + ret; + advanceLen = (int)inOutIdx + ret; if (algId == DHk) { /* Special case for DH as we expect the DER buffer to be always * be in PKCS8 format */ rawDer.buffer = pkcs8Der->buffer; - rawDer.length = inOutIdx + ret; + rawDer.length = inOutIdx + (word32)ret; } else { rawDer.buffer = pkcs8Der->buffer + inOutIdx; - rawDer.length = ret; + rawDer.length = (word32)ret; } ret = 0; /* good DER */ } @@ -7988,11 +8175,11 @@ int wolfSSL_i2d_PKCS8_PKEY(WOLFSSL_PKCS8_PRIV_KEY_INFO* key, unsigned char** pp) return WOLFSSL_FATAL_ERROR; len = (int)keySz; - if (pp == NULL) + if ((pp == NULL) || (len == 0)) return len; if (*pp == NULL) { - out = (unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1); + out = (unsigned char*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_ASN1); if (out == NULL) return WOLFSSL_FATAL_ERROR; } @@ -8082,7 +8269,8 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PUBKEY_bio(WOLFSSL_BIO* bio, return NULL; } - mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); + mem = (unsigned char*)XMALLOC((size_t)memSz, bio->heap, + DYNAMIC_TYPE_TMP_BUFFER); if (mem == NULL) { return NULL; } @@ -8141,15 +8329,16 @@ static int wolfSSL_EVP_PKEY_get_der(const WOLFSSL_EVP_PKEY* key, if (*der) { /* since this function signature has no size value passed in it is * assumed that the user has allocated a large enough buffer */ - XMEMCPY(*der, pt + pkcs8HeaderSz, sz); + XMEMCPY(*der, pt + pkcs8HeaderSz, (size_t)sz); *der += sz; } else { - *der = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_OPENSSL); + *der = (unsigned char*)XMALLOC((size_t)sz, NULL, + DYNAMIC_TYPE_OPENSSL); if (*der == NULL) { return WOLFSSL_FATAL_ERROR; } - XMEMCPY(*der, pt + pkcs8HeaderSz, sz); + XMEMCPY(*der, pt + pkcs8HeaderSz, (size_t)sz); } } return sz; @@ -8221,14 +8410,15 @@ static WOLFSSL_EVP_PKEY* _d2i_PublicKey(int type, WOLFSSL_EVP_PKEY** out, local->type = type; local->pkey_sz = (int)inSz; local->pkcs8HeaderSz = pkcs8HeaderSz; - local->pkey.ptr = (char*)XMALLOC(inSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY); + local->pkey.ptr = (char*)XMALLOC((size_t)inSz, NULL, + DYNAMIC_TYPE_PUBLIC_KEY); if (local->pkey.ptr == NULL) { wolfSSL_EVP_PKEY_free(local); local = NULL; return NULL; } else { - XMEMCPY(local->pkey.ptr, *in, inSz); + XMEMCPY(local->pkey.ptr, *in, (size_t)inSz); } switch (type) { @@ -9164,8 +9354,14 @@ static int CheckcipherList(const char* list) next = XSTRSTR(next, ":"); - current_length = (!next) ? (word32)XSTRLEN(current) - : (word32)(next - current); + if (next) { + current_length = (word32)(next - current); + ++next; /* increment to skip ':' */ + } + else { + current_length = (word32)XSTRLEN(current); + } + if (current_length == 0) { break; } @@ -9222,8 +9418,7 @@ static int CheckcipherList(const char* list) /* list has mixed suites */ return 0; } - } - while (next++); /* increment to skip ':' */ + } while (next); if (findTLSv13Suites == 0 && findbeforeSuites == 1) { ret = 1;/* only before TLSv13 suites */ @@ -11271,7 +11466,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #endif byte* myBuffer = staticBuffer; int dynamic = 0; - int sending = 0; + word32 sending = 0; int idx = 0; int i; int ret; @@ -11279,11 +11474,11 @@ int wolfSSL_set_compression(WOLFSSL* ssl) WOLFSSL_ENTER("wolfSSL_writev"); for (i = 0; i < iovcnt; i++) - sending += (int)iov[i].iov_len; + sending += iov[i].iov_len; - if (sending > (int)sizeof(staticBuffer)) { - myBuffer = (byte*)XMALLOC((size_t)sending, ssl->heap, - DYNAMIC_TYPE_WRITEV); + if (sending > sizeof(staticBuffer)) { + myBuffer = (byte*)XMALLOC(sending, ssl->heap, + DYNAMIC_TYPE_WRITEV); if (!myBuffer) return MEMORY_ERROR; @@ -11300,7 +11495,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) */ PRAGMA_GCC_DIAG_PUSH PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") - ret = wolfSSL_write(ssl, myBuffer, sending); + ret = wolfSSL_write_internal(ssl, myBuffer, sending); PRAGMA_GCC_DIAG_POP if (dynamic) @@ -12094,13 +12289,13 @@ int wolfSSL_set_compression(WOLFSSL* ssl) *sigAlgo = FALCON_LEVEL5k; break; case dilithium_level2_sa_algo: - *sigAlgo = DILITHIUM_LEVEL2k; + *sigAlgo = ML_DSA_LEVEL2k; break; case dilithium_level3_sa_algo: - *sigAlgo = DILITHIUM_LEVEL3k; + *sigAlgo = ML_DSA_LEVEL3k; break; case dilithium_level5_sa_algo: - *sigAlgo = DILITHIUM_LEVEL5k; + *sigAlgo = ML_DSA_LEVEL5k; break; case sm2_sa_algo: *sigAlgo = SM2k; @@ -12316,6 +12511,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) err = WOLFSSL_SUCCESS; cleanup: wolfSSL_X509_free(cert); + cert = NULL; wolfSSL_BIO_free(bio); if (err != WOLFSSL_SUCCESS) { /* We failed so return NULL */ @@ -12596,6 +12792,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #endif /* OPENSSL_EXTRA || WOLFSSL_EXTRA || WOLFSSL_WPAS_SMALL */ /* return true if connection established */ + /* this works for TLS and DTLS */ int wolfSSL_is_init_finished(const WOLFSSL* ssl) { if (ssl == NULL) @@ -12713,63 +12910,6 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #if !defined(NO_CERTS) && (defined(OPENSSL_EXTRA) || \ defined(WOLFSSL_WPAS_SMALL)) -#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) - /** - * Implemented in a similar way that ngx_ssl_ocsp_validate does it when - * SSL_get0_verified_chain is not available. - * @param ssl WOLFSSL object to extract certs from - * @return Stack of verified certs - */ - WOLF_STACK_OF(WOLFSSL_X509) *wolfSSL_get0_verified_chain(const WOLFSSL *ssl) - { - WOLF_STACK_OF(WOLFSSL_X509)* chain = NULL; - WOLFSSL_X509_STORE_CTX* storeCtx = NULL; - WOLFSSL_X509* peerCert = NULL; - - WOLFSSL_ENTER("wolfSSL_get0_verified_chain"); - - if (ssl == NULL || ssl->ctx == NULL) { - WOLFSSL_MSG("Bad parameter"); - return NULL; - } - - peerCert = wolfSSL_get_peer_certificate((WOLFSSL*)ssl); - if (peerCert == NULL) { - WOLFSSL_MSG("wolfSSL_get_peer_certificate error"); - return NULL; - } - /* wolfSSL_get_peer_certificate returns a copy. We want the internal - * member so that we don't have to worry about free'ing it. We call - * wolfSSL_get_peer_certificate so that we don't have to worry about - * setting up the internal pointer. */ - wolfSSL_X509_free(peerCert); - peerCert = (WOLFSSL_X509*)&ssl->peerCert; - chain = wolfSSL_get_peer_cert_chain(ssl); - if (chain == NULL) { - WOLFSSL_MSG("wolfSSL_get_peer_cert_chain error"); - return NULL; - } - storeCtx = wolfSSL_X509_STORE_CTX_new(); - if (storeCtx == NULL) { - WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_new error"); - return NULL; - } - if (wolfSSL_X509_STORE_CTX_init(storeCtx, SSL_STORE(ssl), - peerCert, chain) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init error"); - wolfSSL_X509_STORE_CTX_free(storeCtx); - return NULL; - } - if (wolfSSL_X509_verify_cert(storeCtx) <= 0) { - WOLFSSL_MSG("wolfSSL_X509_verify_cert error"); - wolfSSL_X509_STORE_CTX_free(storeCtx); - return NULL; - } - wolfSSL_X509_STORE_CTX_free(storeCtx); - return chain; - } -#endif /* SESSION_CERTS && OPENSSL_EXTRA */ - WOLFSSL_X509_STORE* wolfSSL_CTX_get_cert_store(const WOLFSSL_CTX* ctx) { if (ctx == NULL) { @@ -12937,7 +13077,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) { WOLFSSL_ENTER("wolfSSL_ERR_get_error"); #ifdef WOLFSSL_HAVE_ERROR_QUEUE - return wc_GetErrorNodeErr(); + return (unsigned long)wc_GetErrorNodeErr(); #else return (unsigned long)(0 - NOT_COMPILED_IN); #endif @@ -13008,7 +13148,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl) do { ret = wc_PeekErrorNode(0, &file, &reason, &line); if (ret >= 0) { - const char* r = wolfSSL_ERR_reason_error_string(0 - ret); + const char* r = wolfSSL_ERR_reason_error_string( + (unsigned long)(0 - ret)); if (XSNPRINTF(buf, sizeof(buf), "error:%d:wolfSSL library:%s:%s:%d\n", ret, r, file, line) @@ -14353,12 +14494,13 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_get_peer_cert_chain(const WOLFSSL* ssl) /* Try to populate if NULL or empty */ if (ssl->peerCertChain == NULL || - wolfSSL_sk_X509_num(ssl->peerCertChain) == 0) + wolfSSL_sk_X509_num(ssl->peerCertChain) == 0) { wolfSSL_set_peer_cert_chain((WOLFSSL*) ssl); + } return ssl->peerCertChain; } -#ifndef WOLFSSL_QT + static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm, WOLFSSL_X509 *x); /** @@ -14366,84 +14508,66 @@ static int x509GetIssuerFromCM(WOLFSSL_X509 **issuer, WOLFSSL_CERT_MANAGER* cm, * @param cm The cert manager that is queried for the issuer * @param x This cert's issuer will be queried in cm * @param sk The issuer is pushed onto this stack - * @return WOLFSSL_SUCCESS on success - * WOLFSSL_FAILURE on no issuer found + * @return 0 on success or no issuer found * WOLFSSL_FATAL_ERROR on a fatal error */ static int PushCAx509Chain(WOLFSSL_CERT_MANAGER* cm, WOLFSSL_X509 *x, WOLFSSL_STACK* sk) { - WOLFSSL_X509* issuer[MAX_CHAIN_DEPTH]; int i; - int push = 1; - int ret = WOLFSSL_SUCCESS; - for (i = 0; i < MAX_CHAIN_DEPTH; i++) { - if (x509GetIssuerFromCM(&issuer[i], cm, x) - != WOLFSSL_SUCCESS) + WOLFSSL_X509* issuer = NULL; + if (x509GetIssuerFromCM(&issuer, cm, x) != WOLFSSL_SUCCESS) break; - x = issuer[i]; - } - if (i == 0) /* No further chain found */ - return WOLFSSL_FAILURE; - i--; - for (; i >= 0; i--) { - if (push) { - if (wolfSSL_sk_X509_push(sk, issuer[i]) <= 0) { - wolfSSL_X509_free(issuer[i]); - ret = WOLFSSL_FATAL_ERROR; - push = 0; /* Free the rest of the unpushed certs */ - } - } - else { - wolfSSL_X509_free(issuer[i]); + if (wolfSSL_sk_X509_push(sk, issuer) <= 0) { + wolfSSL_X509_free(issuer); + issuer = NULL; + return WOLFSSL_FATAL_ERROR; } + x = issuer; } - return ret; + return 0; } -#endif /* !WOLFSSL_QT */ + /* Builds up and creates a stack of peer certificates for ssl->peerCertChain - based off of the ssl session chain. Attempts to place CA certificates - at the bottom of the stack. Returns stack of WOLFSSL_X509 certs or - NULL on failure */ -WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl) + or ssl->verifiedChain based off of the ssl session chain. Attempts to place + CA certificates at the bottom of the stack for a verified chain. Returns + stack of WOLFSSL_X509 certs or NULL on failure */ +static WOLF_STACK_OF(WOLFSSL_X509)* CreatePeerCertChain(const WOLFSSL* ssl, + int verifiedFlag) { WOLFSSL_STACK* sk; WOLFSSL_X509* x509; int i = 0; - int ret; + int err; WOLFSSL_ENTER("wolfSSL_set_peer_cert_chain"); if ((ssl == NULL) || (ssl->session->chain.count == 0)) return NULL; sk = wolfSSL_sk_X509_new_null(); - i = ssl->session->chain.count-1; - for (; i >= 0; i--) { + for (i = 0; i < ssl->session->chain.count; i++) { x509 = wolfSSL_X509_new_ex(ssl->heap); if (x509 == NULL) { WOLFSSL_MSG("Error Creating X509"); wolfSSL_sk_X509_pop_free(sk, NULL); return NULL; } - ret = DecodeToX509(x509, ssl->session->chain.certs[i].buffer, + err = DecodeToX509(x509, ssl->session->chain.certs[i].buffer, ssl->session->chain.certs[i].length); -#if !defined(WOLFSSL_QT) - if (ret == 0 && i == ssl->session->chain.count-1) { - /* On the last element in the chain try to add the CA chain - * first if we have one for this cert */ + if (err == 0 && wolfSSL_sk_X509_push(sk, x509) <= 0) + err = WOLFSSL_FATAL_ERROR; + if (err == 0 && i == ssl->session->chain.count-1 && verifiedFlag) { + /* On the last element in the verified chain try to add the CA chain + * if we have one for this cert */ SSL_CM_WARNING(ssl); - if (PushCAx509Chain(SSL_CM(ssl), x509, sk) - == WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR)) { - ret = WOLFSSL_FATAL_ERROR; - } + err = PushCAx509Chain(SSL_CM(ssl), x509, sk); } -#endif - - if (ret != 0 || wolfSSL_sk_X509_push(sk, x509) <= 0) { + if (err != 0) { WOLFSSL_MSG("Error decoding cert"); wolfSSL_X509_free(x509); + x509 = NULL; wolfSSL_sk_X509_pop_free(sk, NULL); return NULL; } @@ -14452,18 +14576,98 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl) if (sk == NULL) { WOLFSSL_MSG("Null session chain"); } -#if defined(OPENSSL_ALL) - else if (ssl->options.side == WOLFSSL_SERVER_END) { - /* to be compliant with openssl - first element is kept as peer cert on server side.*/ - wolfSSL_sk_X509_pop(sk); + return sk; +} + + +/* Builds up and creates a stack of peer certificates for ssl->peerCertChain + returns the stack on success and NULL on failure */ +WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_set_peer_cert_chain(WOLFSSL* ssl) +{ + WOLFSSL_STACK* sk; + + WOLFSSL_ENTER("wolfSSL_set_peer_cert_chain"); + if ((ssl == NULL) || (ssl->session->chain.count == 0)) + return NULL; + + sk = CreatePeerCertChain(ssl, 0); + + if (sk != NULL) { + if (ssl->options.side == WOLFSSL_SERVER_END) { + if (ssl->session->peer) + wolfSSL_X509_free(ssl->session->peer); + + ssl->session->peer = wolfSSL_sk_X509_shift(sk); + ssl->session->peerVerifyRet = ssl->peerVerifyRet; + } + if (ssl->peerCertChain != NULL) + wolfSSL_sk_X509_pop_free(ssl->peerCertChain, NULL); + /* This is Free'd when ssl is Free'd */ + ssl->peerCertChain = sk; + } + return sk; +} + + +/** + * Implemented in a similar way that ngx_ssl_ocsp_validate does it when + * SSL_get0_verified_chain is not available. + * @param ssl WOLFSSL object to extract certs from + * @return Stack of verified certs + */ +WOLF_STACK_OF(WOLFSSL_X509) *wolfSSL_get0_verified_chain(const WOLFSSL *ssl) +{ + WOLF_STACK_OF(WOLFSSL_X509)* chain = NULL; + WOLFSSL_X509_STORE_CTX* storeCtx = NULL; + WOLFSSL_X509* peerCert = NULL; + + WOLFSSL_ENTER("wolfSSL_get0_verified_chain"); + + if (ssl == NULL || ssl->ctx == NULL) { + WOLFSSL_MSG("Bad parameter"); + return NULL; + } + + peerCert = wolfSSL_get_peer_certificate((WOLFSSL*)ssl); + if (peerCert == NULL) { + WOLFSSL_MSG("wolfSSL_get_peer_certificate error"); + return NULL; + } + /* wolfSSL_get_peer_certificate returns a copy. We want the internal + * member so that we don't have to worry about free'ing it. We call + * wolfSSL_get_peer_certificate so that we don't have to worry about + * setting up the internal pointer. */ + wolfSSL_X509_free(peerCert); + peerCert = (WOLFSSL_X509*)&ssl->peerCert; + chain = CreatePeerCertChain((WOLFSSL*)ssl, 1); + if (chain == NULL) { + WOLFSSL_MSG("wolfSSL_get_peer_cert_chain error"); + return NULL; + } + + if (ssl->verifiedChain != NULL) { + wolfSSL_sk_X509_pop_free(ssl->verifiedChain, NULL); + } + ((WOLFSSL*)ssl)->verifiedChain = chain; + + storeCtx = wolfSSL_X509_STORE_CTX_new(); + if (storeCtx == NULL) { + WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_new error"); + return NULL; + } + if (wolfSSL_X509_STORE_CTX_init(storeCtx, SSL_STORE(ssl), + peerCert, chain) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("wolfSSL_X509_STORE_CTX_init error"); + wolfSSL_X509_STORE_CTX_free(storeCtx); + return NULL; + } + if (wolfSSL_X509_verify_cert(storeCtx) <= 0) { + WOLFSSL_MSG("wolfSSL_X509_verify_cert error"); + wolfSSL_X509_STORE_CTX_free(storeCtx); + return NULL; } -#endif - if (ssl->peerCertChain != NULL) - wolfSSL_sk_X509_pop_free(ssl->peerCertChain, NULL); - /* This is Free'd when ssl is Free'd */ - ssl->peerCertChain = sk; - return sk; + wolfSSL_X509_STORE_CTX_free(storeCtx); + return chain; } #endif /* SESSION_CERTS && OPENSSL_EXTRA */ @@ -14541,7 +14745,14 @@ int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) { WOLFSSL_ENTER("wolfSSL_sk_push"); - return wolfSSL_sk_insert(sk, data, 0); + return wolfSSL_sk_insert(sk, data, -1); +} + +void* wolfSSL_sk_pop(WOLFSSL_STACK* sk) +{ + WOLFSSL_ENTER("wolfSSL_sk_pop"); + + return wolfSSL_sk_pop_node(sk, -1); } /* return number of elements on success 0 on fail */ @@ -14715,10 +14926,8 @@ int wolfSSL_sk_insert(WOLFSSL_STACK *sk, const void *data, int idx) { /* insert node into stack. not using sk since we return sk->num after */ WOLFSSL_STACK* prev_node = sk; - while (idx != 0 && prev_node->next != NULL) { + while (--idx != 0 && prev_node->next != NULL) prev_node = prev_node->next; - idx--; - } node->next = prev_node->next; prev_node->next = node; } @@ -14726,6 +14935,93 @@ int wolfSSL_sk_insert(WOLFSSL_STACK *sk, const void *data, int idx) return (int)sk->num; } +void* wolfSSL_sk_pop_node(WOLFSSL_STACK* sk, int idx) +{ + void* ret = NULL; + WOLFSSL_STACK* tmp = NULL; + + if (!sk) + return NULL; + if (sk->num == 0) + return NULL; + + sk->num--; + if (idx == 0 || sk->next == NULL) { + switch (sk->type) { + case STACK_TYPE_CIPHER: + /* Can't return cipher type */ + break; + case STACK_TYPE_X509: + case STACK_TYPE_GEN_NAME: + case STACK_TYPE_BIO: + case STACK_TYPE_OBJ: + case STACK_TYPE_STRING: + case STACK_TYPE_ACCESS_DESCRIPTION: + case STACK_TYPE_X509_EXT: + case STACK_TYPE_X509_REQ_ATTR: + case STACK_TYPE_NULL: + case STACK_TYPE_X509_NAME: + case STACK_TYPE_X509_NAME_ENTRY: + case STACK_TYPE_CONF_VALUE: + case STACK_TYPE_X509_INFO: + case STACK_TYPE_BY_DIR_entry: + case STACK_TYPE_BY_DIR_hash: + case STACK_TYPE_X509_OBJ: + case STACK_TYPE_DIST_POINT: + case STACK_TYPE_X509_CRL: + default: + ret = sk->data.generic; + sk->data.generic = NULL; + break; + } + if (sk->next) { + tmp = sk->next; + sk->next = tmp->next; + XMEMCPY(&sk->data, &tmp->data, sizeof(sk->data)); + wolfSSL_sk_free_node(tmp); + } + return ret; + } + + { + WOLFSSL_STACK* prev_node = sk; + tmp = sk->next; + while (--idx != 0 && tmp->next != NULL) { + prev_node = tmp; + tmp = tmp->next; + } + prev_node->next = tmp->next; + switch (sk->type) { + case STACK_TYPE_CIPHER: + /* Can't return cipher type */ + break; + case STACK_TYPE_X509: + case STACK_TYPE_GEN_NAME: + case STACK_TYPE_BIO: + case STACK_TYPE_OBJ: + case STACK_TYPE_STRING: + case STACK_TYPE_ACCESS_DESCRIPTION: + case STACK_TYPE_X509_EXT: + case STACK_TYPE_X509_REQ_ATTR: + case STACK_TYPE_NULL: + case STACK_TYPE_X509_NAME: + case STACK_TYPE_X509_NAME_ENTRY: + case STACK_TYPE_CONF_VALUE: + case STACK_TYPE_X509_INFO: + case STACK_TYPE_BY_DIR_entry: + case STACK_TYPE_BY_DIR_hash: + case STACK_TYPE_X509_OBJ: + case STACK_TYPE_DIST_POINT: + case STACK_TYPE_X509_CRL: + default: + ret = tmp->data.generic; + break; + } + wolfSSL_sk_free_node(tmp); + } + return ret; +} + #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ #ifdef OPENSSL_EXTRA @@ -14857,9 +15153,9 @@ WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl) } #ifndef WOLFSSL_X509_STORE_CERTS ssl->ourCert = wolfSSL_X509_d2i_ex(NULL, - ssl->buffers.certificate->buffer, - ssl->buffers.certificate->length, - ssl->heap); + ssl->buffers.certificate->buffer, + (int)ssl->buffers.certificate->length, + ssl->heap); #endif } return ssl->ourCert; @@ -14873,9 +15169,9 @@ WOLFSSL_X509* wolfSSL_get_certificate(WOLFSSL* ssl) } #ifndef WOLFSSL_X509_STORE_CERTS ssl->ctx->ourCert = wolfSSL_X509_d2i_ex(NULL, - ssl->ctx->certificate->buffer, - ssl->ctx->certificate->length, - ssl->heap); + ssl->ctx->certificate->buffer, + (int)ssl->ctx->certificate->length, + ssl->heap); #endif ssl->ctx->ownOurCert = 1; } @@ -14897,7 +15193,8 @@ WOLFSSL_X509* wolfSSL_CTX_get0_certificate(WOLFSSL_CTX* ctx) #ifndef WOLFSSL_X509_STORE_CERTS ctx->ourCert = wolfSSL_X509_d2i_ex(NULL, ctx->certificate->buffer, - ctx->certificate->length, ctx->heap); + (int)ctx->certificate->length, + ctx->heap); #endif ctx->ownOurCert = 1; } @@ -15172,7 +15469,7 @@ WOLFSSL_STACK* wolfSSL_sk_new_cipher(void) return sk; } -/* return 1 on success 0 on fail */ +/* returns the number of elements in stack on success, 0 on fail */ int wolfSSL_sk_CIPHER_push(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk, WOLFSSL_CIPHER* cipher) { @@ -15276,72 +15573,103 @@ const char* wolfSSL_get_curve_name(WOLFSSL* ssl) if (ssl == NULL) return NULL; -#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_KYBER) +#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_HAVE_MLKEM) /* Check for post-quantum groups. Return now because we do not want the ECC * check to override this result in the case of a hybrid. */ if (IsAtLeastTLSv1_3(ssl->version)) { switch (ssl->namedGroup) { #ifndef WOLFSSL_NO_ML_KEM -#ifdef HAVE_LIBOQS - case WOLFSSL_ML_KEM_512: - return "ML_KEM_512"; - case WOLFSSL_ML_KEM_768: - return "ML_KEM_768"; - case WOLFSSL_ML_KEM_1024: - return "ML_KEM_1024"; - case WOLFSSL_P256_ML_KEM_512: - return "P256_ML_KEM_512"; - case WOLFSSL_P384_ML_KEM_768: - return "P384_ML_KEM_768"; - case WOLFSSL_P521_ML_KEM_1024: - return "P521_ML_KEM_1024"; -#elif defined(WOLFSSL_WC_KYBER) +#if defined(WOLFSSL_WC_MLKEM) #ifndef WOLFSSL_NO_ML_KEM_512 case WOLFSSL_ML_KEM_512: return "ML_KEM_512"; case WOLFSSL_P256_ML_KEM_512: return "P256_ML_KEM_512"; + #ifdef HAVE_CURVE25519 + case WOLFSSL_X25519_ML_KEM_512: + return "X25519_ML_KEM_512"; + #endif #endif #ifndef WOLFSSL_NO_ML_KEM_768 case WOLFSSL_ML_KEM_768: return "ML_KEM_768"; case WOLFSSL_P384_ML_KEM_768: return "P384_ML_KEM_768"; + case WOLFSSL_P256_ML_KEM_768: + return "P256_ML_KEM_768"; + #ifdef HAVE_CURVE25519 + case WOLFSSL_X25519_ML_KEM_768: + return "X25519_ML_KEM_768"; + #endif + #ifdef HAVE_CURVE448 + case WOLFSSL_X448_ML_KEM_768: + return "X448_ML_KEM_768"; + #endif #endif #ifndef WOLFSSL_NO_ML_KEM_1024 case WOLFSSL_ML_KEM_1024: return "ML_KEM_1024"; case WOLFSSL_P521_ML_KEM_1024: return "P521_ML_KEM_1024"; + case WOLFSSL_P384_ML_KEM_1024: + return "P384_ML_KEM_1024"; #endif -#endif -#endif -#ifdef WOLFSSL_KYBER_ORIGINAL -#ifdef HAVE_LIBOQS - case WOLFSSL_KYBER_LEVEL1: - return "KYBER_LEVEL1"; - case WOLFSSL_KYBER_LEVEL3: - return "KYBER_LEVEL3"; - case WOLFSSL_KYBER_LEVEL5: - return "KYBER_LEVEL5"; - case WOLFSSL_P256_KYBER_LEVEL1: - return "P256_KYBER_LEVEL1"; - case WOLFSSL_P384_KYBER_LEVEL3: - return "P384_KYBER_LEVEL3"; - case WOLFSSL_P521_KYBER_LEVEL5: - return "P521_KYBER_LEVEL5"; -#elif defined(WOLFSSL_WC_KYBER) +#elif defined(HAVE_LIBOQS) + case WOLFSSL_ML_KEM_512: + return "ML_KEM_512"; + case WOLFSSL_ML_KEM_768: + return "ML_KEM_768"; + case WOLFSSL_ML_KEM_1024: + return "ML_KEM_1024"; + case WOLFSSL_P256_ML_KEM_512: + return "P256_ML_KEM_512"; + case WOLFSSL_P384_ML_KEM_768: + return "P384_ML_KEM_768"; + case WOLFSSL_P256_ML_KEM_768: + return "P256_ML_KEM_768"; + case WOLFSSL_P521_ML_KEM_1024: + return "P521_ML_KEM_1024"; + case WOLFSSL_P384_ML_KEM_1024: + return "P384_ML_KEM_1024"; + #ifdef HAVE_CURVE25519 + case WOLFSSL_X25519_ML_KEM_512: + return "X25519_ML_KEM_512"; + case WOLFSSL_X25519_ML_KEM_768: + return "X25519_ML_KEM_768"; + #endif + #ifdef HAVE_CURVE448 + case WOLFSSL_X448_ML_KEM_768: + return "X448_ML_KEM_768"; + #endif +#endif /* WOLFSSL_WC_MLKEM */ +#endif /* WOLFSSL_NO_ML_KEM */ +#ifdef WOLFSSL_MLKEM_KYBER +#if defined(WOLFSSL_WC_MLKEM) #ifndef WOLFSSL_NO_KYBER512 case WOLFSSL_KYBER_LEVEL1: return "KYBER_LEVEL1"; case WOLFSSL_P256_KYBER_LEVEL1: return "P256_KYBER_LEVEL1"; + #ifdef HAVE_CURVE25519 + case WOLFSSL_X25519_KYBER_LEVEL1: + return "X25519_KYBER_LEVEL1"; + #endif #endif #ifndef WOLFSSL_NO_KYBER768 case WOLFSSL_KYBER_LEVEL3: return "KYBER_LEVEL3"; case WOLFSSL_P384_KYBER_LEVEL3: return "P384_KYBER_LEVEL3"; + case WOLFSSL_P256_KYBER_LEVEL3: + return "P256_KYBER_LEVEL3"; + #ifdef HAVE_CURVE25519 + case WOLFSSL_X25519_KYBER_LEVEL3: + return "X25519_KYBER_LEVEL3"; + #endif + #ifdef HAVE_CURVE448 + case WOLFSSL_X448_KYBER_LEVEL3: + return "X448_KYBER_LEVEL3"; + #endif #endif #ifndef WOLFSSL_NO_KYBER1024 case WOLFSSL_KYBER_LEVEL5: @@ -15349,11 +15677,36 @@ const char* wolfSSL_get_curve_name(WOLFSSL* ssl) case WOLFSSL_P521_KYBER_LEVEL5: return "P521_KYBER_LEVEL5"; #endif -#endif -#endif +#elif defined (HAVE_LIBOQS) + case WOLFSSL_KYBER_LEVEL1: + return "KYBER_LEVEL1"; + case WOLFSSL_KYBER_LEVEL3: + return "KYBER_LEVEL3"; + case WOLFSSL_KYBER_LEVEL5: + return "KYBER_LEVEL5"; + case WOLFSSL_P256_KYBER_LEVEL1: + return "P256_KYBER_LEVEL1"; + case WOLFSSL_P384_KYBER_LEVEL3: + return "P384_KYBER_LEVEL3"; + case WOLFSSL_P256_KYBER_LEVEL3: + return "P256_KYBER_LEVEL3"; + case WOLFSSL_P521_KYBER_LEVEL5: + return "P521_KYBER_LEVEL5"; + #ifdef HAVE_CURVE25519 + case WOLFSSL_X25519_KYBER_LEVEL1: + return "X25519_KYBER_LEVEL1"; + case WOLFSSL_X25519_KYBER_LEVEL3: + return "X25519_KYBER_LEVEL3"; + #endif + #ifdef HAVE_CURVE448 + case WOLFSSL_X448_KYBER_LEVEL3: + return "X448_KYBER_LEVEL3"; + #endif +#endif /* WOLFSSL_WC_MLKEM */ +#endif /* WOLFSSL_MLKEM_KYBER */ } } -#endif /* WOLFSSL_TLS13 && WOLFSSL_HAVE_KYBER */ +#endif /* WOLFSSL_TLS13 && WOLFSSL_HAVE_MLKEM */ #ifdef HAVE_FFDHE if (ssl->namedGroup != 0) { @@ -15640,42 +15993,42 @@ int wolfSSL_sk_CIPHER_description(WOLFSSL_CIPHER* cipher) /* Build up the string by copying onto the end. */ - XSTRNCPY(dp, name, len); + XSTRNCPY(dp, name, (size_t)len); dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp); len -= strLen; dp += strLen; - XSTRNCPY(dp, " ", len); + XSTRNCPY(dp, " ", (size_t)len); dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp); len -= strLen; dp += strLen; - XSTRNCPY(dp, protocol, len); + XSTRNCPY(dp, protocol, (size_t)len); dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp); len -= strLen; dp += strLen; - XSTRNCPY(dp, " Kx=", len); + XSTRNCPY(dp, " Kx=", (size_t)len); dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp); len -= strLen; dp += strLen; - XSTRNCPY(dp, keaStr, len); + XSTRNCPY(dp, keaStr, (size_t)len); dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp); len -= strLen; dp += strLen; - XSTRNCPY(dp, " Au=", len); + XSTRNCPY(dp, " Au=", (size_t)len); dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp); len -= strLen; dp += strLen; - XSTRNCPY(dp, authStr, len); + XSTRNCPY(dp, authStr, (size_t)len); dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp); len -= strLen; dp += strLen; - XSTRNCPY(dp, " Enc=", len); + XSTRNCPY(dp, " Enc=", (size_t)len); dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp); len -= strLen; dp += strLen; - XSTRNCPY(dp, encStr, len); + XSTRNCPY(dp, encStr, (size_t)len); dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp); len -= strLen; dp += strLen; - XSTRNCPY(dp, " Mac=", len); + XSTRNCPY(dp, " Mac=", (size_t)len); dp[len-1] = '\0'; strLen = (int)XSTRLEN(dp); - len -= strLen; dp += strLen; - XSTRNCPY(dp, macStr, len); + len -= strLen; dp += (size_t)strLen; + XSTRNCPY(dp, macStr, (size_t)len); dp[len-1] = '\0'; return WOLFSSL_SUCCESS; @@ -15933,7 +16286,7 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, */ if (cipher->in_stack == TRUE) { wolfSSL_sk_CIPHER_description((WOLFSSL_CIPHER*)cipher); - XSTRNCPY(in,cipher->description,len); + XSTRNCPY(in,cipher->description,(size_t)len); return ret; } #endif @@ -15946,32 +16299,32 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, macStr = wolfssl_mac_to_string(cipher->ssl->specs.mac_algorithm); /* Build up the string by copying onto the end. */ - XSTRNCPY(in, wolfSSL_CIPHER_get_name(cipher), len); + XSTRNCPY(in, wolfSSL_CIPHER_get_name(cipher), (size_t)len); in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen; - XSTRNCPY(in, " ", len); + XSTRNCPY(in, " ", (size_t)len); in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen; - XSTRNCPY(in, wolfSSL_get_version(cipher->ssl), len); + XSTRNCPY(in, wolfSSL_get_version(cipher->ssl), (size_t)len); in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen; - XSTRNCPY(in, " Kx=", len); + XSTRNCPY(in, " Kx=", (size_t)len); in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen; - XSTRNCPY(in, keaStr, len); + XSTRNCPY(in, keaStr, (size_t)len); in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen; - XSTRNCPY(in, " Au=", len); + XSTRNCPY(in, " Au=", (size_t)len); in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen; - XSTRNCPY(in, authStr, len); + XSTRNCPY(in, authStr, (size_t)len); in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen; - XSTRNCPY(in, " Enc=", len); + XSTRNCPY(in, " Enc=", (size_t)len); in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen; - XSTRNCPY(in, encStr, len); + XSTRNCPY(in, encStr, (size_t)len); in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen; - XSTRNCPY(in, " Mac=", len); + XSTRNCPY(in, " Mac=", (size_t)len); in[len-1] = '\0'; strLen = XSTRLEN(in); len -= (int)strLen; in += strLen; - XSTRNCPY(in, macStr, len); + XSTRNCPY(in, macStr, (size_t)len); in[len-1] = '\0'; return ret; @@ -17101,8 +17454,8 @@ long wolfSSL_clear_options(WOLFSSL* ssl, long opt) WOLFSSL_ENTER("wolfSSL_clear_options"); if(ssl == NULL) return WOLFSSL_FAILURE; - ssl->options.mask &= ~opt; - return ssl->options.mask; + ssl->options.mask &= (unsigned long)~opt; + return (long)ssl->options.mask; } #ifdef HAVE_PK_CALLBACKS @@ -17256,7 +17609,7 @@ void wolfSSL_ERR_load_SSL_strings(void) } #endif -#ifdef HAVE_OCSP +#if defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) long wolfSSL_get_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char **resp) { if (s == NULL || resp == NULL) @@ -17272,12 +17625,13 @@ long wolfSSL_set_tlsext_status_ocsp_resp(WOLFSSL *s, unsigned char *resp, if (s == NULL) return WOLFSSL_FAILURE; + XFREE(s->ocspResp, NULL, 0); s->ocspResp = resp; s->ocspRespSz = len; return WOLFSSL_SUCCESS; } -#endif /* HAVE_OCSP */ +#endif /* defined(HAVE_OCSP) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) */ #ifdef HAVE_MAX_FRAGMENT #if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_TLS) @@ -17367,7 +17721,7 @@ long wolfSSL_get_verify_result(const WOLFSSL *ssl) return WOLFSSL_FAILURE; } - return ssl->peerVerifyRet; + return (long)ssl->peerVerifyRet; } #endif @@ -17633,6 +17987,33 @@ static void wolfSSL_CIPHER_copy(WOLFSSL_CIPHER* in, WOLFSSL_CIPHER* out) *out = *in; } + +#if defined(OPENSSL_ALL) +static WOLFSSL_X509_OBJECT* wolfSSL_X509_OBJECT_dup(WOLFSSL_X509_OBJECT* obj) +{ + WOLFSSL_X509_OBJECT* ret = NULL; + if (obj) { + ret = wolfSSL_X509_OBJECT_new(); + if (ret) { + ret->type = obj->type; + switch (ret->type) { + case WOLFSSL_X509_LU_NONE: + break; + case WOLFSSL_X509_LU_X509: + ret->data.x509 = wolfSSL_X509_dup(obj->data.x509); + break; + case WOLFSSL_X509_LU_CRL: + #if defined(HAVE_CRL) + ret->data.crl = wolfSSL_X509_CRL_dup(obj->data.crl); + #endif + break; + } + } + } + return ret; +} +#endif /* OPENSSL_ALL */ + WOLFSSL_STACK* wolfSSL_sk_dup(WOLFSSL_STACK* sk) { @@ -17695,6 +18076,17 @@ WOLFSSL_STACK* wolfSSL_sk_dup(WOLFSSL_STACK* sk) goto error; } break; + case STACK_TYPE_X509_OBJ: + #if defined(OPENSSL_ALL) + if (!sk->data.x509_obj) + break; + cur->data.x509_obj = wolfSSL_X509_OBJECT_dup(sk->data.x509_obj); + if (!cur->data.x509_obj) { + WOLFSSL_MSG("wolfSSL_X509_OBJECT_dup error"); + goto error; + } + break; + #endif case STACK_TYPE_BIO: case STACK_TYPE_STRING: case STACK_TYPE_ACCESS_DESCRIPTION: @@ -17707,7 +18099,6 @@ WOLFSSL_STACK* wolfSSL_sk_dup(WOLFSSL_STACK* sk) case STACK_TYPE_X509_INFO: case STACK_TYPE_BY_DIR_entry: case STACK_TYPE_BY_DIR_hash: - case STACK_TYPE_X509_OBJ: case STACK_TYPE_DIST_POINT: case STACK_TYPE_X509_CRL: default: @@ -17766,7 +18157,7 @@ void wolfSSL_sk_free(WOLFSSL_STACK* sk) while (sk != NULL) { WOLFSSL_STACK* next = sk->next; - XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); + wolfSSL_sk_free_node(sk); sk = next; } } @@ -17780,7 +18171,7 @@ void wolfSSL_sk_GENERIC_pop_free(WOLFSSL_STACK* sk, wolfSSL_sk_pop_free(sk, (wolfSSL_sk_freefunc)f); } -/* return 1 on success 0 on fail */ +/* returns the number of elements in stack on success, 0 on fail */ int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK* sk, void* generic) { WOLFSSL_ENTER("wolfSSL_sk_GENERIC_push"); @@ -17801,34 +18192,11 @@ void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk) */ void* wolfssl_sk_pop_type(WOLFSSL_STACK* sk, WOLF_STACK_TYPE type) { - WOLFSSL_STACK* node; void* data = NULL; /* Check we have a stack passed in of the right type. */ - if ((sk != NULL) && (sk->type == type)) { - /* Get the next node to become the new first node. */ - node = sk->next; - /* Get the ASN.1 OBJECT_ID object in the first node. */ - data = sk->data.generic; - - /* Check whether there is a next node. */ - if (node != NULL) { - /* Move content out of next node into current node. */ - sk->data.obj = node->data.obj; - sk->next = node->next; - /* Dispose of node. */ - XFREE(node, NULL, DYNAMIC_TYPE_ASN1); - } - else { - /* No more nodes - clear out data. */ - sk->data.obj = NULL; - } - - /* Decrement count as long as we thought we had nodes. */ - if (sk->num > 0) { - sk->num -= 1; - } - } + if ((sk != NULL) && (sk->type == type)) + data = wolfSSL_sk_pop(sk); return data; } @@ -17952,7 +18320,7 @@ void wolfSSL_sk_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, if (sk->type != STACK_TYPE_CIPHER) func(sk->data.generic); } - XFREE(sk, NULL, DYNAMIC_TYPE_OPENSSL); + XFREE(sk, sk->heap, DYNAMIC_TYPE_OPENSSL); sk = next; } } @@ -18044,7 +18412,7 @@ int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname) if (sz > (long)sizeof(staticBuffer)) { WOLFSSL_MSG("Getting dynamic buffer"); - myBuffer = (byte*)XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE); + myBuffer = (byte*)XMALLOC((size_t)sz, ctx->heap, DYNAMIC_TYPE_FILE); dynamic = 1; } @@ -18183,6 +18551,9 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = { #ifdef WOLFSSL_MD2 { WC_NID_md2, MD2h, oidHashType, "MD2", "md2"}, #endif + #ifndef NO_MD4 + { WC_NID_md4, MD4h, oidHashType, "MD4", "md4"}, + #endif #ifndef NO_MD5 { WC_NID_md5, MD5h, oidHashType, "MD5", "md5"}, #endif @@ -18350,12 +18721,20 @@ const WOLFSSL_ObjectInfo wolfssl_object_info[] = { "Falcon Level 5"}, #endif /* HAVE_FALCON */ #ifdef HAVE_DILITHIUM + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT { CTC_DILITHIUM_LEVEL2, DILITHIUM_LEVEL2k, oidKeyType, "Dilithium Level 2", "Dilithium Level 2"}, { CTC_DILITHIUM_LEVEL3, DILITHIUM_LEVEL3k, oidKeyType, "Dilithium Level 3", "Dilithium Level 3"}, { CTC_DILITHIUM_LEVEL5, DILITHIUM_LEVEL5k, oidKeyType, "Dilithium Level 5", "Dilithium Level 5"}, + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ + { CTC_ML_DSA_LEVEL2, ML_DSA_LEVEL2k, oidKeyType, + "ML-DSA 44", "ML-DSA 44"}, + { CTC_ML_DSA_LEVEL3, ML_DSA_LEVEL3k, oidKeyType, + "ML-DSA 65", "ML-DSA 65"}, + { CTC_ML_DSA_LEVEL5, ML_DSA_LEVEL5k, oidKeyType, + "ML-DSA 87", "ML-DSA 87"}, #endif /* HAVE_DILITHIUM */ /* oidCurveType */ @@ -18738,13 +19117,13 @@ static int SaToNid(byte sa, int* nid) *nid = CTC_FALCON_LEVEL5; break; case dilithium_level2_sa_algo: - *nid = CTC_DILITHIUM_LEVEL2; + *nid = CTC_ML_DSA_LEVEL2; break; case dilithium_level3_sa_algo: - *nid = CTC_DILITHIUM_LEVEL3; + *nid = CTC_ML_DSA_LEVEL3; break; case dilithium_level5_sa_algo: - *nid = CTC_DILITHIUM_LEVEL5; + *nid = CTC_ML_DSA_LEVEL5; break; case sm2_sa_algo: *nid = WC_NID_sm2; @@ -18923,7 +19302,7 @@ WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN* chain, int idx) #endif { InitDecodedCert(cert, chain->certs[idx].buffer, - chain->certs[idx].length, NULL); + (word32)chain->certs[idx].length, NULL); if ((ret = ParseCertRelative(cert, CERT_TYPE, 0, NULL, NULL)) != 0) { WOLFSSL_MSG("Failed to parse cert"); @@ -18985,10 +19364,11 @@ int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx, /* Null output buffer return size needed in outLen */ if(!buf) { - if(Base64_Encode(chain->certs[idx].buffer, chain->certs[idx].length, + if(Base64_Encode(chain->certs[idx].buffer, + (word32)chain->certs[idx].length, NULL, &szNeeded) != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) return WOLFSSL_FAILURE; - *outLen = szNeeded + headerLen + footerLen; + *outLen = (int)szNeeded + headerLen + footerLen; return WC_NO_ERR_TRACE(LENGTH_ONLY_E); } @@ -18997,7 +19377,7 @@ int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx, return BAD_FUNC_ARG; /* header */ - if (XMEMCPY(buf, header, headerLen) == NULL) + if (XMEMCPY(buf, header, (size_t)headerLen) == NULL) return WOLFSSL_FATAL_ERROR; i = headerLen; @@ -19005,14 +19385,15 @@ int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN* chain, int idx, /* body */ *outLen = inLen; /* input to Base64_Encode */ if ( (err = Base64_Encode(chain->certs[idx].buffer, - chain->certs[idx].length, buf + i, (word32*)outLen)) < 0) + (word32)chain->certs[idx].length, buf + i, + (word32*)outLen)) < 0) return err; i += *outLen; /* footer */ if ( (i + footerLen) > inLen) return BAD_FUNC_ARG; - if (XMEMCPY(buf + i, footer, footerLen) == NULL) + if (XMEMCPY(buf + i, footer, (size_t)footerLen) == NULL) return WOLFSSL_FATAL_ERROR; *outLen += headerLen + footerLen; @@ -19453,6 +19834,29 @@ void* wolfSSL_GetGenMasterSecretCtx(WOLFSSL* ssl) return NULL; } +/* callback for extended master secret generation */ +void wolfSSL_CTX_SetGenExtMasterSecretCb(WOLFSSL_CTX* ctx, + CallbackGenExtMasterSecret cb) +{ + if (ctx) + ctx->GenExtMasterCb = cb; +} +/* Set extended master secret generation callback context */ +void wolfSSL_SetGenExtMasterSecretCtx(WOLFSSL* ssl, void *ctx) +{ + if (ssl) + ssl->GenExtMasterCtx = ctx; +} +/* Get extended master secret generation callback context */ +void* wolfSSL_GetGenExtMasterSecretCtx(WOLFSSL* ssl) +{ + if (ssl) + return ssl->GenExtMasterCtx; + + return NULL; +} + + /* callback for session key generation */ void wolfSSL_CTX_SetGenSessionKeyCb(WOLFSSL_CTX* ctx, CallbackGenSessionKey cb) { @@ -19732,7 +20136,7 @@ void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl) obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA; } else { - obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA; + obj->dynamic &= (unsigned char)~WOLFSSL_ASN1_DYNAMIC_DATA; } } XMEMCPY((byte*)obj->obj, objBuf, obj->objSz); @@ -19847,7 +20251,7 @@ void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl) bufSz = bufLen - 1; } if (bufSz) { - XMEMCPY(buf, name, bufSz); + XMEMCPY(buf, name, (size_t)bufSz); } else if (a->type == WOLFSSL_GEN_DNS || a->type == WOLFSSL_GEN_EMAIL || a->type == WOLFSSL_GEN_URI) { @@ -19858,7 +20262,7 @@ void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl) if ((desc = oid_translate_num_to_str(buf))) { bufSz = (int)XSTRLEN(desc); bufSz = (int)min((word32)bufSz,(word32) bufLen - 1); - XMEMCPY(buf, desc, bufSz); + XMEMCPY(buf, desc, (size_t)bufSz); } } else { @@ -20014,19 +20418,21 @@ void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl) if (o->nid > 0) return o->nid; - if ((ret = GetObjectId(o->obj, &idx, &oid, o->grp, o->objSz)) < 0) { + if ((ret = GetObjectId(o->obj, &idx, &oid, + (word32)o->grp, o->objSz)) < 0) { if (ret == WC_NO_ERR_TRACE(ASN_OBJECT_ID_E)) { /* Put ASN object tag in front and try again */ - int len = SetObjectId(o->objSz, NULL) + o->objSz; - byte* buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER); + int len = SetObjectId((int)o->objSz, NULL) + (int)o->objSz; + byte* buf = (byte*)XMALLOC((size_t)len, NULL, + DYNAMIC_TYPE_TMP_BUFFER); if (!buf) { WOLFSSL_MSG("malloc error"); return WOLFSSL_FATAL_ERROR; } - idx = SetObjectId(o->objSz, buf); + idx = (word32)SetObjectId((int)o->objSz, buf); XMEMCPY(buf + idx, o->obj, o->objSz); idx = 0; - ret = GetObjectId(buf, &idx, &oid, o->grp, len); + ret = GetObjectId(buf, &idx, &oid, (word32)o->grp, (word32)len); XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (ret < 0) { WOLFSSL_MSG("Issue getting OID of object"); @@ -20165,13 +20571,13 @@ void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl) /* try as a short name */ len = (int)XSTRLEN(s); if ((int)XSTRLEN(wolfssl_object_info[i].sName) == len && - XSTRNCMP(wolfssl_object_info[i].sName, s, len) == 0) { + XSTRNCMP(wolfssl_object_info[i].sName, s, (word32)len) == 0) { return wolfssl_object_info[i].nid; } /* try as a long name */ if ((int)XSTRLEN(wolfssl_object_info[i].lName) == len && - XSTRNCMP(wolfssl_object_info[i].lName, s, len) == 0) { + XSTRNCMP(wolfssl_object_info[i].lName, s, (word32)len) == 0) { return wolfssl_object_info[i].nid; } } @@ -20226,7 +20632,7 @@ void* wolfSSL_GetHKDFExtractCtx(WOLFSSL* ssl) obj->dynamic |= WOLFSSL_ASN1_DYNAMIC_DATA; i = SetObjectId((int)outSz, (byte*)obj->obj); XMEMCPY((byte*)obj->obj + i, out, outSz); - obj->objSz = i + outSz; + obj->objSz = (word32)i + outSz; return obj; } @@ -20304,7 +20710,7 @@ unsigned long wolfSSL_ERR_peek_last_error_line(const char **file, int *line) return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE; #endif #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON) - if (ret == WC_NO_ERR_TRACE(ASN1_R_HEADER_TOO_LONG)) { + if (ret == ASN1_R_HEADER_TOO_LONG) { return (ERR_LIB_ASN1 << 24) | ASN1_R_HEADER_TOO_LONG; } #endif @@ -20756,6 +21162,7 @@ long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt) WOLFSSL_MSG("Error adding certificate to context"); /* Decrease reference count on failure */ wolfSSL_X509_free(x509); + x509 = NULL; } } } @@ -20912,7 +21319,8 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO* bio, return NULL; } - mem = (unsigned char*)XMALLOC(memSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); + mem = (unsigned char*)XMALLOC((size_t)memSz, bio->heap, + DYNAMIC_TYPE_TMP_BUFFER); if (mem == NULL) { WOLFSSL_MSG("Malloc failure"); return NULL; @@ -20937,7 +21345,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO* bio, int i; int j = 0; - extraBioMem = (unsigned char *)XMALLOC(extraBioMemSz, NULL, + extraBioMem = (unsigned char *)XMALLOC((size_t)extraBioMemSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (extraBioMem == NULL) { WOLFSSL_MSG("Malloc failure"); @@ -21018,10 +21426,7 @@ void wolfSSL_print_all_errors_fp(XFILE fp) /* Note: This is a huge section of API's - through * wolfSSL_X509_OBJECT_get0_X509_CRL */ -#if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && \ - (defined(HAVE_STUNNEL) || defined(WOLFSSL_NGINX) || \ - defined(HAVE_LIGHTY) || defined(WOLFSSL_HAPROXY) || \ - defined(WOLFSSL_OPENSSH) || defined(HAVE_SBLIM_SFCB))) +#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) #if defined(USE_WOLFSSL_MEMORY) && !defined(WOLFSSL_DEBUG_MEMORY) && \ !defined(WOLFSSL_STATIC_MEMORY) @@ -21189,6 +21594,7 @@ int wolfSSL_set_tlsext_host_name(WOLFSSL* ssl, const char* host_name) return ret; } +#ifndef NO_WOLFSSL_SERVER /* May be called by server to get the requested accepted name and by the client * to get the requested name. */ const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type) @@ -21200,6 +21606,8 @@ const char * wolfSSL_get_servername(WOLFSSL* ssl, byte type) !wolfSSL_is_server(ssl)); return (const char *)serverName; } +#endif + #endif /* HAVE_SNI */ WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx) @@ -21430,9 +21838,7 @@ void wolfSSL_THREADID_set_numeric(void* id, unsigned long val) } #endif -#endif /* OPENSSL_ALL || (OPENSSL_EXTRA && (HAVE_STUNNEL || WOLFSSL_NGINX || - * HAVE_LIGHTY || WOLFSSL_HAPROXY || WOLFSSL_OPENSSH || - * HAVE_SBLIM_SFCB)) */ +#endif /* OPENSSL_ALL || OPENSSL_EXTRA */ #ifdef HAVE_SNI @@ -21480,7 +21886,7 @@ unsigned long wolfSSL_ERR_peek_last_error(void) if (ret == -WC_NO_ERR_TRACE(ASN_NO_PEM_HEADER)) return (WOLFSSL_ERR_LIB_PEM << 24) | -WC_NO_ERR_TRACE(WOLFSSL_PEM_R_NO_START_LINE_E); #if defined(WOLFSSL_PYTHON) - if (ret == WC_NO_ERR_TRACE(ASN1_R_HEADER_TOO_LONG)) + if (ret == ASN1_R_HEADER_TOO_LONG) return (WOLFSSL_ERR_LIB_ASN1 << 24) | -WC_NO_ERR_TRACE(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E); #endif return (unsigned long)ret; @@ -21692,7 +22098,7 @@ unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line, return (WOLFSSL_ERR_LIB_SSL << 24) | -WC_NO_ERR_TRACE(PARSE_ERROR) /* SSL_R_HTTP_REQUEST */; #endif #if defined(OPENSSL_ALL) && defined(WOLFSSL_PYTHON) - else if (err == WC_NO_ERR_TRACE(ASN1_R_HEADER_TOO_LONG)) + else if (err == ASN1_R_HEADER_TOO_LONG) return (WOLFSSL_ERR_LIB_ASN1 << 24) | -WC_NO_ERR_TRACE(WOLFSSL_ASN1_R_HEADER_TOO_LONG_E); #endif return err; @@ -21869,6 +22275,83 @@ WOLF_STACK_OF(WOLFSSL_CIPHER) *wolfSSL_get_ciphers_compat(const WOLFSSL *ssl) return ssl->suitesStack; } #endif /* OPENSSL_EXTRA || OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ +#ifdef OPENSSL_ALL +/* returned pointer is to an internal element in WOLFSSL struct and should not + * be free'd. It gets free'd when the WOLFSSL struct is free'd. */ +WOLF_STACK_OF(WOLFSSL_CIPHER)* wolfSSL_get_client_ciphers(WOLFSSL* ssl) +{ + WOLF_STACK_OF(WOLFSSL_CIPHER)* ret = NULL; + const CipherSuiteInfo* cipher_names = GetCipherNames(); + int cipherSz = GetCipherNamesSize(); + const Suites* suites; + + WOLFSSL_ENTER("wolfSSL_get_client_ciphers"); + + if (ssl == NULL) { + return NULL; + } + + /* return NULL if is client side */ + if (wolfSSL_is_server(ssl) == 0) { + return NULL; + } + + suites = ssl->clSuites; + if (suites == NULL) { + WOLFSSL_MSG("No client suites stored"); + } + else if (ssl->clSuitesStack != NULL) { + ret = ssl->clSuitesStack; + } + else { /* generate cipher suites stack if not already done */ + int i; + int j; + + ret = wolfSSL_sk_new_node(ssl->heap); + if (ret != NULL) { + ret->type = STACK_TYPE_CIPHER; + + /* higher priority of cipher suite will be on top of stack */ + for (i = suites->suiteSz - 2; i >= 0; i -= 2) { + WOLFSSL_CIPHER cipher; + + /* A couple of suites are placeholders for special options, + * skip those. */ + if (SCSV_Check(suites->suites[i], suites->suites[i+1]) + || sslCipherMinMaxCheck(ssl, suites->suites[i], + suites->suites[i+1])) { + continue; + } + + cipher.cipherSuite0 = suites->suites[i]; + cipher.cipherSuite = suites->suites[i+1]; + cipher.ssl = ssl; + for (j = 0; j < cipherSz; j++) { + if (cipher_names[j].cipherSuite0 == + cipher.cipherSuite0 && + cipher_names[j].cipherSuite == + cipher.cipherSuite) { + cipher.offset = (unsigned long)j; + break; + } + } + + /* in_stack is checked in wolfSSL_CIPHER_description */ + cipher.in_stack = 1; + + if (wolfSSL_sk_CIPHER_push(ret, &cipher) <= 0) { + WOLFSSL_MSG("Error pushing client cipher onto stack"); + wolfSSL_sk_CIPHER_free(ret); + ret = NULL; + break; + } + } + } + ssl->clSuitesStack = ret; + } + return ret; +} +#endif /* OPENSSL_ALL */ #if defined(OPENSSL_EXTRA) || defined(HAVE_SECRET_CALLBACK) long wolfSSL_SSL_CTX_get_timeout(const WOLFSSL_CTX *ctx) @@ -22514,7 +22997,7 @@ int wolfSSL_sk_WOLFSSL_STRING_num(WOLF_STACK_OF(WOLFSSL_STRING)* strings) void wolfSSL_get0_alpn_selected(const WOLFSSL *ssl, const unsigned char **data, unsigned int *len) { - word16 nameLen; + word16 nameLen = 0; if (ssl != NULL && data != NULL && len != NULL) { TLSX_ALPN_GetRequest(ssl->extensions, (void **)data, &nameLen); @@ -22676,31 +23159,52 @@ const WOLF_EC_NIST_NAME kNistCurves[] = { #ifdef HAVE_CURVE448 {CURVE_NAME("X448"), WC_NID_X448, WOLFSSL_ECC_X448}, #endif -#ifdef WOLFSSL_HAVE_KYBER +#ifdef WOLFSSL_HAVE_MLKEM #ifndef WOLFSSL_NO_ML_KEM {CURVE_NAME("ML_KEM_512"), WOLFSSL_ML_KEM_512, WOLFSSL_ML_KEM_512}, {CURVE_NAME("ML_KEM_768"), WOLFSSL_ML_KEM_768, WOLFSSL_ML_KEM_768}, {CURVE_NAME("ML_KEM_1024"), WOLFSSL_ML_KEM_1024, WOLFSSL_ML_KEM_1024}, -#if (defined(WOLFSSL_WC_KYBER) || defined(HAVE_LIBOQS)) && defined(HAVE_ECC) +#if (defined(WOLFSSL_WC_MLKEM) || defined(HAVE_LIBOQS)) && defined(HAVE_ECC) {CURVE_NAME("P256_ML_KEM_512"), WOLFSSL_P256_ML_KEM_512, WOLFSSL_P256_ML_KEM_512}, {CURVE_NAME("P384_ML_KEM_768"), WOLFSSL_P384_ML_KEM_768, WOLFSSL_P384_ML_KEM_768}, + {CURVE_NAME("P256_ML_KEM_768"), WOLFSSL_P256_ML_KEM_768, + WOLFSSL_P256_ML_KEM_768}, {CURVE_NAME("P521_ML_KEM_1024"), WOLFSSL_P521_ML_KEM_1024, WOLFSSL_P521_ML_KEM_1024}, + {CURVE_NAME("P384_ML_KEM_1024"), WOLFSSL_P384_ML_KEM_1024, + WOLFSSL_P384_ML_KEM_1024}, + {CURVE_NAME("X25519_ML_KEM_512"), WOLFSSL_X25519_ML_KEM_512, + WOLFSSL_X25519_ML_KEM_512}, + {CURVE_NAME("X448_ML_KEM_768"), WOLFSSL_X448_ML_KEM_768, + WOLFSSL_X448_ML_KEM_768}, + {CURVE_NAME("X25519_ML_KEM_768"), WOLFSSL_X25519_ML_KEM_768, + WOLFSSL_X25519_ML_KEM_768}, #endif #endif /* !WOLFSSL_NO_ML_KEM */ -#ifdef WOLFSSL_KYBER_ORIGINAL +#ifdef WOLFSSL_MLKEM_KYBER {CURVE_NAME("KYBER_LEVEL1"), WOLFSSL_KYBER_LEVEL1, WOLFSSL_KYBER_LEVEL1}, {CURVE_NAME("KYBER_LEVEL3"), WOLFSSL_KYBER_LEVEL3, WOLFSSL_KYBER_LEVEL3}, {CURVE_NAME("KYBER_LEVEL5"), WOLFSSL_KYBER_LEVEL5, WOLFSSL_KYBER_LEVEL5}, -#if (defined(WOLFSSL_WC_KYBER) || defined(HAVE_LIBOQS)) && defined(HAVE_ECC) - {CURVE_NAME("P256_KYBER_LEVEL1"), WOLFSSL_P256_KYBER_LEVEL1, WOLFSSL_P256_KYBER_LEVEL1}, - {CURVE_NAME("P384_KYBER_LEVEL3"), WOLFSSL_P384_KYBER_LEVEL3, WOLFSSL_P384_KYBER_LEVEL3}, - {CURVE_NAME("P521_KYBER_LEVEL5"), WOLFSSL_P521_KYBER_LEVEL5, WOLFSSL_P521_KYBER_LEVEL5}, -#endif -#endif /* WOLFSSL_KYBER_ORIGINAL */ -#endif /* WOLFSSL_HAVE_KYBER */ +#if (defined(WOLFSSL_WC_MLKEM) || defined(HAVE_LIBOQS)) && defined(HAVE_ECC) + {CURVE_NAME("P256_KYBER_LEVEL1"), WOLFSSL_P256_KYBER_LEVEL1, + WOLFSSL_P256_KYBER_LEVEL1}, + {CURVE_NAME("P384_KYBER_LEVEL3"), WOLFSSL_P384_KYBER_LEVEL3, + WOLFSSL_P384_KYBER_LEVEL3}, + {CURVE_NAME("P256_KYBER_LEVEL3"), WOLFSSL_P256_KYBER_LEVEL3, + WOLFSSL_P256_KYBER_LEVEL3}, + {CURVE_NAME("P521_KYBER_LEVEL5"), WOLFSSL_P521_KYBER_LEVEL5, + WOLFSSL_P521_KYBER_LEVEL5}, + {CURVE_NAME("X25519_KYBER_LEVEL1"), WOLFSSL_X25519_KYBER_LEVEL1, + WOLFSSL_X25519_KYBER_LEVEL1}, + {CURVE_NAME("X448_KYBER_LEVEL3"), WOLFSSL_X448_KYBER_LEVEL3, + WOLFSSL_X448_KYBER_LEVEL3}, + {CURVE_NAME("X25519_KYBER_LEVEL3"), WOLFSSL_X25519_KYBER_LEVEL3, + WOLFSSL_X25519_KYBER_LEVEL3}, +#endif +#endif /* WOLFSSL_MLKEM_KYBER */ +#endif /* WOLFSSL_HAVE_MLKEM */ #ifdef WOLFSSL_SM2 {CURVE_NAME("SM2"), WC_NID_sm2, WOLFSSL_ECC_SM2P256V1}, #endif @@ -22750,13 +23254,13 @@ int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names, if (len > MAX_CURVE_NAME_SZ - 1) goto leave; - XMEMCPY(name, names + start, len); + XMEMCPY(name, names + start, (size_t)len); name[len] = 0; curve = WOLFSSL_NAMED_GROUP_INVALID; for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) { if (len == nist_name->name_len && - XSTRNCMP(name, nist_name->name, len) == 0) { + XSTRNCMP(name, nist_name->name, (size_t)len) == 0) { curve = nist_name->curve; break; } @@ -22779,7 +23283,7 @@ int set_curves_list(WOLFSSL* ssl, WOLFSSL_CTX *ctx, const char* names, goto leave; } - curve = GetCurveByOID(eccSet->oidSum); + curve = GetCurveByOID((int)eccSet->oidSum); #else WOLFSSL_MSG("API not present to search farther using name"); goto leave; @@ -23910,7 +24414,7 @@ static int bio_get_data(WOLFSSL_BIO* bio, byte** data) ret = wolfSSL_BIO_get_len(bio); if (ret > 0) { - mem = (byte*)XMALLOC(ret, bio->heap, DYNAMIC_TYPE_OPENSSL); + mem = (byte*)XMALLOC((size_t)ret, bio->heap, DYNAMIC_TYPE_OPENSSL); if (mem == NULL) { WOLFSSL_MSG("Memory error"); ret = MEMORY_E; @@ -24003,7 +24507,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_AutoPrivateKey(WOLFSSL_EVP_PKEY** pkey, */ ret = GetSequence(der, &idx, &len, keyLen); if (ret >= 0) { - word32 end = idx + len; + word32 end = idx + (word32)len; while (ret >= 0 && idx < end) { /* Skip type */ idx++; @@ -24011,10 +24515,10 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_AutoPrivateKey(WOLFSSL_EVP_PKEY** pkey, len = 0; ret = GetLength(der, &idx, &len, keyLen); if (ret >= 0) { - if (idx + len > end) + if (idx + (word32)len > end) ret = ASN_PARSE_E; else { - idx += len; + idx += (word32)len; cnt++; } } @@ -24836,8 +25340,18 @@ int wolfSSL_BUF_MEM_grow_ex(WOLFSSL_BUF_MEM* buf, size_t len, /* expand size, to handle growth */ mx = (len_int + 3) / 3 * 4; +#ifdef WOLFSSL_NO_REALLOC + tmp = (char*)XMALLOC(mx, NULL, DYNAMIC_TYPE_OPENSSL); + if (tmp != NULL && buf->data != NULL) { + XMEMCPY(tmp, buf->data, len_int); + XFREE(buf->data, NULL, DYNAMIC_TYPE_OPENSSL); + buf->data = NULL; + } +#else /* use realloc */ tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL); +#endif + if (tmp == NULL) { return 0; /* ERR_R_MALLOC_FAILURE; */ } @@ -24879,7 +25393,18 @@ int wolfSSL_BUF_MEM_resize(WOLFSSL_BUF_MEM* buf, size_t len) mx = ((int)len + 3) / 3 * 4; /* We want to shrink the internal buffer */ +#ifdef WOLFSSL_NO_REALLOC + tmp = (char*)XMALLOC(mx, NULL, DYNAMIC_TYPE_OPENSSL); + if (tmp != NULL && buf->data != NULL) + { + XMEMCPY(tmp, buf->data, len); + XFREE(buf->data,NULL,DYNAMIC_TYPE_OPENSSL); + buf->data = NULL; + } +#else tmp = (char*)XREALLOC(buf->data, mx, NULL, DYNAMIC_TYPE_OPENSSL); +#endif + if (tmp == NULL) return 0; diff --git a/src/src/ssl_asn1.c b/src/src/ssl_asn1.c index 5ebad81..535c672 100644 --- a/src/src/ssl_asn1.c +++ b/src/src/ssl_asn1.c @@ -1,6 +1,6 @@ /* ssl_asn1.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,13 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include - #include +#include #ifndef WC_NO_RNG #include #endif @@ -797,9 +793,18 @@ static int wolfssl_asn1_bit_string_grow(WOLFSSL_ASN1_BIT_STRING* bitStr, int ret = 1; byte* tmp; +#ifdef WOLFSSL_NO_REALLOC + tmp = (byte*)XMALLOC((size_t)len, NULL, DYNAMIC_TYPE_OPENSSL); + if (tmp != NULL && bitStr->data != NULL) { + XMEMCPY(tmp, bitStr->data, bitStr->length); + XFREE(bitStr->data, NULL, DYNAMIC_TYPE_OPENSSL); + bitStr->data = NULL; + } +#else /* Realloc to length required. */ tmp = (byte*)XREALLOC(bitStr->data, (size_t)len, NULL, DYNAMIC_TYPE_OPENSSL); +#endif if (tmp == NULL) { ret = 0; } @@ -1084,36 +1089,36 @@ static int wolfssl_asn1_integer_require_len(WOLFSSL_ASN1_INTEGER* a, int len, */ WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_dup(const WOLFSSL_ASN1_INTEGER* src) { - WOLFSSL_ASN1_INTEGER* dup = NULL; + WOLFSSL_ASN1_INTEGER* dst = NULL; WOLFSSL_ENTER("wolfSSL_ASN1_INTEGER_dup"); /* Check for object to duplicate. */ if (src != NULL) { /* Create a new ASN.1 INTEGER object to be copied into. */ - dup = wolfSSL_ASN1_INTEGER_new(); + dst = wolfSSL_ASN1_INTEGER_new(); } /* Check for object to copy into. */ - if (dup != NULL) { + if (dst != NULL) { /* Copy simple fields. */ - dup->length = src->length; - dup->negative = src->negative; - dup->type = src->type; + dst->length = src->length; + dst->negative = src->negative; + dst->type = src->type; if (!src->isDynamic) { /* Copy over data from/to fixed buffer. */ - XMEMCPY(dup->intData, src->intData, WOLFSSL_ASN1_INTEGER_MAX); + XMEMCPY(dst->intData, src->intData, WOLFSSL_ASN1_INTEGER_MAX); } - else if (wolfssl_asn1_integer_require_len(dup, src->length, 0) == 0) { - wolfSSL_ASN1_INTEGER_free(dup); - dup = NULL; + else if (wolfssl_asn1_integer_require_len(dst, src->length, 0) == 0) { + wolfSSL_ASN1_INTEGER_free(dst); + dst = NULL; } else { - XMEMCPY(dup->data, src->data, (size_t)src->length); + XMEMCPY(dst->data, src->data, (size_t)src->length); } } - return dup; + return dst; } #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ @@ -3814,7 +3819,6 @@ static int wolfssl_asn1_time_to_secs(const WOLFSSL_ASN1_TIME* t, * @param [in] from ASN.1 TIME object as start time. * @param [in] to ASN.1 TIME object as end time. * @return 1 on success. - * @return 0 when days or secs is NULL. * @return 0 when conversion of time fails. */ int wolfSSL_ASN1_TIME_diff(int *days, int *secs, const WOLFSSL_ASN1_TIME *from, @@ -3824,21 +3828,15 @@ int wolfSSL_ASN1_TIME_diff(int *days, int *secs, const WOLFSSL_ASN1_TIME *from, WOLFSSL_ENTER("wolfSSL_ASN1_TIME_diff"); - /* Validate parameters. */ - if (days == NULL) { - WOLFSSL_MSG("days is NULL"); - ret = 0; - } - if ((ret == 1) && (secs == NULL)) { - WOLFSSL_MSG("secs is NULL"); - ret = 0; - } - - if ((ret == 1) && ((from == NULL) && (to == NULL))) { - *days = 0; - *secs = 0; + if ((from == NULL) && (to == NULL)) { + if (days != NULL) { + *days = 0; + } + if (secs != NULL) { + *secs = 0; + } } - else if (ret == 1) { + else { const long long SECS_PER_DAY = 24 * 60 * 60; long long fromSecs; long long toSecs = 0; @@ -3849,8 +3847,13 @@ int wolfSSL_ASN1_TIME_diff(int *days, int *secs, const WOLFSSL_ASN1_TIME *from, } if (ret == 1) { long long diffSecs = toSecs - fromSecs; - *days = (int) (diffSecs / SECS_PER_DAY); - *secs = (int) (diffSecs - ((long long)*days * SECS_PER_DAY)); + if (days != NULL) { + *days = (int) (diffSecs / SECS_PER_DAY); + } + if (secs != NULL) { + *secs = (int) (diffSecs - + ((long long)(diffSecs / SECS_PER_DAY) * SECS_PER_DAY)); + } } } diff --git a/src/src/ssl_bn.c b/src/src/ssl_bn.c index 1c05b14..0d947a8 100644 --- a/src/src/ssl_bn.c +++ b/src/src/ssl_bn.c @@ -1,6 +1,6 @@ /* ssl_bn.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #include #ifndef WC_NO_RNG @@ -1273,43 +1269,29 @@ int wolfSSL_BN_is_word(const WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w) * Word operation APIs. ******************************************************************************/ -/* Add/subtract a word to/from a big number. - * - * Internal function for adding/subtracting an unsigned long from a - * WOLFSSL_BIGNUM. To add, pass "sub" as 0. To subtract, pass it as 1. +enum BN_WORD_OP { + BN_WORD_ADD = 0, + BN_WORD_SUB = 1, + BN_WORD_MUL = 2, + BN_WORD_DIV = 3, + BN_WORD_MOD = 4 +}; + +/* Helper function for word operations. * - * @param [in, out] bn Big number to operate on. - * @param [in] w Word to operate with. - * @param [in] sub Indicates whether operation to perform is a subtract. + * @param [in, out] bn Big number to operate on. + * @param [in] w Word to operate with. + * @param [in] op Operation to perform. See BN_WORD_OP for valid values. + * @param [out] mod_res Result of the modulo operation. * @return 1 on success. - * @return 0 in failure. + * @return 0 on failure. */ -static int wolfssl_bn_add_word_int(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w, - int sub) +static int bn_word_helper(const WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w, + enum BN_WORD_OP op, WOLFSSL_BN_ULONG* mod_res) { int ret = 1; -#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT) -#ifdef WOLFSSL_SMALL_STACK - mp_int* w_mp = NULL; -#else - mp_int w_mp[1]; -#endif /* WOLFSSL_SMALL_STACK */ -#endif -#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT) -#ifdef WOLFSSL_SMALL_STACK - /* Allocate temporary MP integer. */ - w_mp = (mp_int*)XMALLOC(sizeof(*w_mp), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (w_mp == NULL) { - ret = 0; - } - else -#endif /* WOLFSSL_SMALL_STACK */ - { - /* Clear out MP integer so it can be freed. */ - XMEMSET(w_mp, 0, sizeof(*w_mp)); - } -#endif + WOLFSSL_ENTER("bn_word_helper"); /* Validate parameters. */ if (ret == 1 && BN_IS_NULL(bn)) { @@ -1318,60 +1300,108 @@ static int wolfssl_bn_add_word_int(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w, } if (ret == 1) { - int rc = 0; + int rc = MP_OKAY; #if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT) + /* When input 'w' is greater than what can be stored in one digit */ if (w > (WOLFSSL_BN_ULONG)MP_MASK) { - /* Initialize temporary MP integer. */ - if (mp_init(w_mp) != MP_OKAY) { + DECL_MP_INT_SIZE_DYN(w_mp, sizeof(WOLFSSL_BN_ULONG) * CHAR_BIT, + sizeof(WOLFSSL_BN_ULONG) * CHAR_BIT); + NEW_MP_INT_SIZE(w_mp, sizeof(WOLFSSL_BN_ULONG) * CHAR_BIT, NULL, + DYNAMIC_TYPE_TMP_BUFFER); +#ifdef MP_INT_SIZE_CHECK_NULL + if (w_mp == NULL) { + WOLFSSL_MSG("NEW_MP_INT_SIZE error"); ret = 0; } - /* Set value into temporary MP integer. */ - if ((ret == 1) && (mp_set_int(w_mp, w) != MP_OKAY)) { +#endif + if (ret == 1 && mp_set_int(w_mp, w) != MP_OKAY) { + WOLFSSL_MSG("mp_set_int error"); ret = 0; } if (ret == 1) { - if (sub) { - /* Subtract as MP integer. */ - rc = mp_sub((mp_int *)bn->internal, w_mp, - (mp_int *)bn->internal); - } - else { - /* Add as MP integer. */ - rc = mp_add((mp_int *)bn->internal, w_mp, - (mp_int *)bn->internal); - } - if (rc != MP_OKAY) { - WOLFSSL_MSG("mp_add/sub error"); - ret = 0; + switch (op) { + case BN_WORD_ADD: + rc = mp_add((mp_int*)bn->internal, w_mp, + (mp_int*)bn->internal); + break; + case BN_WORD_SUB: + rc = mp_sub((mp_int*)bn->internal, w_mp, + (mp_int*)bn->internal); + break; + case BN_WORD_MUL: + rc = mp_mul((mp_int*)bn->internal, w_mp, + (mp_int*)bn->internal); + break; + case BN_WORD_DIV: + rc = mp_div((mp_int*)bn->internal, w_mp, + (mp_int*)bn->internal, NULL); + break; + case BN_WORD_MOD: + rc = mp_mod((mp_int*) bn->internal, w_mp, + w_mp); + if (rc == MP_OKAY && mod_res != NULL) + *mod_res = wolfssl_bn_get_word_1(w_mp); + break; + default: + rc = WOLFSSL_NOT_IMPLEMENTED; + break; } } + FREE_MP_INT_SIZE(w_mp, NULL, DYNAMIC_TYPE_RSA); } else #endif { - if (sub) { - /* Subtract word from MP integer. */ - rc = mp_sub_d((mp_int*)bn->internal, (mp_digit)w, - (mp_int*)bn->internal); - } - else { - /* Add word from MP integer. */ - rc = mp_add_d((mp_int*)bn->internal, (mp_digit)w, - (mp_int*)bn->internal); - } - if (rc != MP_OKAY) { - WOLFSSL_MSG("mp_add/sub_d error"); - ret = 0; + switch (op) { + case BN_WORD_ADD: + rc = mp_add_d((mp_int*)bn->internal, (mp_digit)w, + (mp_int*)bn->internal); + break; + case BN_WORD_SUB: + rc = mp_sub_d((mp_int*)bn->internal, (mp_digit)w, + (mp_int*)bn->internal); + break; + case BN_WORD_MUL: + rc = mp_mul_d((mp_int*)bn->internal, (mp_digit)w, + (mp_int*)bn->internal); + break; + case BN_WORD_DIV: +#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) +/* copied from sp_int.h */ +#if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \ + defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \ + defined(WC_MP_TO_RADIX) + rc = mp_div_d((mp_int*)bn->internal, (mp_digit)w, + (mp_int*)bn->internal, NULL); +#else + rc = WOLFSSL_NOT_IMPLEMENTED; +#endif +#else + rc = WOLFSSL_NOT_IMPLEMENTED; +#endif + break; + case BN_WORD_MOD: + { + mp_digit _mod_res; + rc = mp_mod_d((mp_int*) bn->internal, (mp_digit) w, + &_mod_res); + if (rc == MP_OKAY && mod_res != NULL) + *mod_res = (WOLFSSL_BN_ULONG)_mod_res; + } + break; + default: + rc = WOLFSSL_NOT_IMPLEMENTED; + break; } } + if (ret == 1 && rc != MP_OKAY) { + WOLFSSL_MSG("mp word operation error or not implemented"); + ret = 0; + } } -#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT) - mp_free(w_mp); -#ifdef WOLFSSL_SMALL_STACK - XFREE(w_mp, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif /* WOLFSSL_SMALL_STACK */ -#endif + WOLFSSL_LEAVE("bn_word_helper", ret); + return ret; } @@ -1390,7 +1420,7 @@ int wolfSSL_BN_add_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w) WOLFSSL_ENTER("wolfSSL_BN_add_word"); - ret = wolfssl_bn_add_word_int(bn, w, 0); + ret = bn_word_helper(bn, w, BN_WORD_ADD, NULL); WOLFSSL_LEAVE("wolfSSL_BN_add_word", ret); @@ -1412,7 +1442,7 @@ int wolfSSL_BN_sub_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w) WOLFSSL_ENTER("wolfSSL_BN_sub_word"); - ret = wolfssl_bn_add_word_int(bn, w, 1); + ret = bn_word_helper(bn, w, BN_WORD_SUB, NULL); WOLFSSL_LEAVE("wolfSSL_BN_sub_word", ret); @@ -1421,79 +1451,27 @@ int wolfSSL_BN_sub_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w) int wolfSSL_BN_mul_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w) { - int ret = 1; -#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT) -#ifdef WOLFSSL_SMALL_STACK - mp_int* w_mp = NULL; -#else - mp_int w_mp[1]; -#endif /* WOLFSSL_SMALL_STACK */ -#endif + int ret; WOLFSSL_ENTER("wolfSSL_BN_mul_word"); -#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT) -#ifdef WOLFSSL_SMALL_STACK - /* Allocate temporary MP integer. */ - w_mp = (mp_int*)XMALLOC(sizeof(*w_mp), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (w_mp == NULL) { - ret = 0; - } - else -#endif /* WOLFSSL_SMALL_STACK */ - { - /* Clear out MP integer so it can be freed. */ - XMEMSET(w_mp, 0, sizeof(*w_mp)); - } -#endif + ret = bn_word_helper(bn, w, BN_WORD_MUL, NULL); - /* Validate parameters. */ - if (ret == 1 && BN_IS_NULL(bn)) { - WOLFSSL_MSG("bn NULL error"); - ret = 0; - } + WOLFSSL_LEAVE("wolfSSL_BN_mul_word", ret); - if (ret == 1) { - int rc = 0; -#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT) - if (w > (WOLFSSL_BN_ULONG)MP_MASK) { - /* Initialize temporary MP integer. */ - if (mp_init(w_mp) != MP_OKAY) { - ret = 0; - } - /* Set value into temporary MP integer. */ - if ((ret == 1) && (mp_set_int(w_mp, w) != MP_OKAY)) { - ret = 0; - } - if (ret == 1) { - rc = mp_mul((mp_int*)bn->internal, w_mp, - (mp_int*)bn->internal); - if (rc != MP_OKAY) { - WOLFSSL_MSG("mp_mul error"); - ret = 0; - } - } - } - else -#endif - { - rc = mp_mul_d((mp_int*)bn->internal, (mp_digit)w, - (mp_int*)bn->internal); - if (rc != MP_OKAY) { - WOLFSSL_MSG("mp_mul_d error"); - ret = 0; - } - } - } + return ret; +} -#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT) - mp_free(w_mp); -#ifdef WOLFSSL_SMALL_STACK - XFREE(w_mp, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif /* WOLFSSL_SMALL_STACK */ -#endif - WOLFSSL_LEAVE("wolfSSL_BN_mul_word", ret); +int wolfSSL_BN_div_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w) +{ + int ret; + + WOLFSSL_ENTER("wolfSSL_BN_div_word"); + + ret = bn_word_helper(bn, w, BN_WORD_DIV, NULL); + + WOLFSSL_LEAVE("wolfSSL_BN_div_word", ret); return ret; } @@ -1510,70 +1488,16 @@ int wolfSSL_BN_mul_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w) WOLFSSL_BN_ULONG wolfSSL_BN_mod_word(const WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w) { - WOLFSSL_BN_ULONG ret = 0; + int ret; + WOLFSSL_BN_ULONG res = 0; WOLFSSL_ENTER("wolfSSL_BN_mod_word"); - /* Validate parameters. */ - if (BN_IS_NULL(bn)) { - WOLFSSL_MSG("bn NULL error"); - ret = (WOLFSSL_BN_ULONG)-1; - } - -#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT) - if ((ret == 0) && (w > (WOLFSSL_BN_ULONG)MP_MASK)) { - /* TODO: small stack */ - mp_int w_mp; - mp_int r_mp; - - /* Memset MP integers to be safe to free. */ - XMEMSET(&w_mp, 0, sizeof(w_mp)); - XMEMSET(&r_mp, 0, sizeof(r_mp)); - - /* Initialize MP integer to hold word. */ - if (mp_init(&w_mp) != MP_OKAY) { - ret = (WOLFSSL_BN_ULONG)-1; - } - /* Initialize MP integer to hold result word. */ - if ((ret == 0) && (mp_init(&r_mp) != MP_OKAY)) { - ret = (WOLFSSL_BN_ULONG)-1; - } - /* Set modulus word into MP integer. */ - if ((ret == 0) && (mp_set_int(&w_mp, w) != MP_OKAY)) { - ret = (WOLFSSL_BN_ULONG)-1; - } - /* Calculate modulus result. */ - if ((ret == 0) && (mp_mod((mp_int *)bn->internal, &w_mp, &r_mp) != - MP_OKAY)) { - WOLFSSL_MSG("mp_mod error"); - ret = (WOLFSSL_BN_ULONG)-1; - } - if (ret == 0) { - /* Get modulus result into an unsigned long. */ - ret = wolfssl_bn_get_word_1(&r_mp); - } - - /* Dispose of dynamically allocated data. */ - mp_free(&r_mp); - mp_free(&w_mp); - } - else -#endif - if (ret == 0) { - mp_digit mp_ret; + ret = bn_word_helper(bn, w, BN_WORD_MOD, &res); - /* Calculate modulus result using wolfCrypt. */ - if (mp_mod_d((mp_int*)bn->internal, (mp_digit)w, &mp_ret) != MP_OKAY) { - WOLFSSL_MSG("mp_add_d error"); - ret = (WOLFSSL_BN_ULONG)-1; - } - else { - /* Return result. */ - ret = (WOLFSSL_BN_ULONG)mp_ret; - } - } + WOLFSSL_LEAVE("wolfSSL_BN_mod_word", ret); - return ret; + return ret == 1 ? res : (WOLFSSL_BN_ULONG)-1; } #endif /* WOLFSSL_KEY_GEN && (!NO_RSA || !NO_DH || !NO_DSA) */ @@ -2434,27 +2358,38 @@ int wolfSSL_BN_print_fp(XFILE fp, const WOLFSSL_BIGNUM *bn) } #endif /* !NO_FILESYSTEM && XFPRINTF */ +#ifndef NO_WOLFSSL_BN_CTX /******************************************************************************* * BN_CTX APIs ******************************************************************************/ -/* Allocate and return a new BN context object. - * - * BN context not needed for operations. +/* Create a new BN context object. * - * @return Pointer to dummy object. + * @return BN context object on success. + * @return NULL on failure. */ WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void) { - /* wolfcrypt doesn't need BN context. */ - static int ctx; + WOLFSSL_BN_CTX* ctx = NULL; + WOLFSSL_ENTER("wolfSSL_BN_CTX_new"); - return (WOLFSSL_BN_CTX*)&ctx; + ctx = (WOLFSSL_BN_CTX*)XMALLOC(sizeof(WOLFSSL_BN_CTX), NULL, + DYNAMIC_TYPE_OPENSSL); + if (ctx != NULL) { + XMEMSET(ctx, 0, sizeof(WOLFSSL_BN_CTX)); + } + + return ctx; } -/* Initialize a BN context object. + +#ifndef NO_WOLFSSL_STUB +/* deprecated * - * BN context not needed for operations. + * Initialize a BN context object. + * This function was removed in OpenSSL 1.1.0 and later. + * Keeping a stub function here for older applications that have BN_CTX_init() + * calls. * * @param [in] ctx Dummy BN context. */ @@ -2462,37 +2397,59 @@ void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX* ctx) { (void)ctx; WOLFSSL_ENTER("wolfSSL_BN_CTX_init"); + WOLFSSL_STUB("wolfSSL_BN_CTX_init"); + WOLFSSL_MSG("wolfSSL_BN_CTX_init is deprecated"); } +#endif /* Free a BN context object. * - * BN context not needed for operations. - * - * @param [in] ctx Dummy BN context. + * @param [in] ctx BN context object. */ void wolfSSL_BN_CTX_free(WOLFSSL_BN_CTX* ctx) { - (void)ctx; WOLFSSL_ENTER("wolfSSL_BN_CTX_free"); - /* Don't do anything since using dummy, static BN context. */ + if (ctx != NULL) { + while (ctx->list != NULL) { + struct WOLFSSL_BN_CTX_LIST* tmp = ctx->list; + ctx->list = ctx->list->next; + wolfSSL_BN_free(tmp->bn); + XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); + } + XFREE(ctx, NULL, DYNAMIC_TYPE_OPENSSL); + } } -/* Get a big number based on the BN context. +/* Get a big number from the BN context. * - * @param [in] ctx BN context. Not used. + * @param [in] ctx BN context object. * @return Big number on success. * @return NULL on failure. */ WOLFSSL_BIGNUM *wolfSSL_BN_CTX_get(WOLFSSL_BN_CTX *ctx) { - /* ctx is not used - returning a new big number. */ - (void)ctx; + WOLFSSL_BIGNUM* bn = NULL; WOLFSSL_ENTER("wolfSSL_BN_CTX_get"); + if (ctx != NULL) { + struct WOLFSSL_BN_CTX_LIST* node = (struct WOLFSSL_BN_CTX_LIST*)XMALLOC( + sizeof(struct WOLFSSL_BN_CTX_LIST), NULL, DYNAMIC_TYPE_OPENSSL); + if (node != NULL) { + XMEMSET(node, 0, sizeof(struct WOLFSSL_BN_CTX_LIST)); + bn = node->bn = wolfSSL_BN_new(); + if (node->bn != NULL) { + node->next = ctx->list; + ctx->list = node; + } + else { + XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL); + node = NULL; + } + } + } - /* Return a new big number. */ - return wolfSSL_BN_new(); + return bn; } #ifndef NO_WOLFSSL_STUB @@ -2512,6 +2469,75 @@ void wolfSSL_BN_CTX_start(WOLFSSL_BN_CTX *ctx) } #endif +#endif /* NO_WOLFSSL_BN_CTX */ + +/******************************************************************************* + * BN_MONT_CTX APIs + ******************************************************************************/ + +WOLFSSL_BN_MONT_CTX* wolfSSL_BN_MONT_CTX_new(void) +{ + /* wolfcrypt doesn't need BN MONT context. */ + static int mont; + WOLFSSL_ENTER("wolfSSL_BN_MONT_CTX_new"); + return (WOLFSSL_BN_MONT_CTX*)&mont; +} + +void wolfSSL_BN_MONT_CTX_free(WOLFSSL_BN_MONT_CTX *mont) +{ + (void)mont; + WOLFSSL_ENTER("wolfSSL_BN_MONT_CTX_free"); + /* Don't do anything since using dummy, static BN context. */ +} + +int wolfSSL_BN_MONT_CTX_set(WOLFSSL_BN_MONT_CTX *mont, + const WOLFSSL_BIGNUM *mod, WOLFSSL_BN_CTX *ctx) +{ + (void) mont; + (void) mod; + (void) ctx; + WOLFSSL_ENTER("wolfSSL_BN_MONT_CTX_set"); + return WOLFSSL_SUCCESS; +} + +/* Calculate r = a ^ p % m. + * + * @param [out] r Big number to store the result. + * @param [in] a Base as an unsigned long. + * @param [in] p Exponent as a big number. + * @param [in] m Modulus as a big number. + * @param [in] ctx BN context object. Unused. + * @param [in] mont Montgomery context object. Unused. + * + * @return 1 on success. + * @return 0 on failure. + */ +int wolfSSL_BN_mod_exp_mont_word(WOLFSSL_BIGNUM *r, WOLFSSL_BN_ULONG a, + const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, WOLFSSL_BN_CTX *ctx, + WOLFSSL_BN_MONT_CTX *mont) +{ + WOLFSSL_BIGNUM* tmp = NULL; + int ret = WOLFSSL_SUCCESS; + + (void)mont; + WOLFSSL_ENTER("wolfSSL_BN_mod_exp_mont_word"); + + if (ret == WOLFSSL_SUCCESS && (tmp = wolfSSL_BN_new()) == NULL) { + WOLFSSL_MSG("wolfSSL_BN_new failed"); + ret = WOLFSSL_FAILURE; + } + if (ret == WOLFSSL_SUCCESS && (wolfSSL_BN_set_word(tmp, (unsigned long)a)) + == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) { + WOLFSSL_MSG("wolfSSL_BN_set_word failed"); + ret = WOLFSSL_FAILURE; + } + if (ret == WOLFSSL_SUCCESS) + ret = wolfSSL_BN_mod_exp(r, tmp, p, m, ctx); + + wolfSSL_BN_free(tmp); + return ret; +} + #endif /* OPENSSL_EXTRA */ #endif /* !WOLFSSL_SSL_BN_INCLUDED */ diff --git a/src/src/ssl_certman.c b/src/src/ssl_certman.c index 6d18db5..df88acd 100644 --- a/src/src/ssl_certman.c +++ b/src/src/ssl_certman.c @@ -1,6 +1,6 @@ /* ssl_certman.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #include @@ -401,6 +397,7 @@ WOLFSSL_STACK* wolfSSL_CertManagerGetCerts(WOLFSSL_CERT_MANAGER* cm) /* Decode certificate. */ if ((!err) && (wolfSSL_sk_X509_push(sk, x509) <= 0)) { wolfSSL_X509_free(x509); + x509 = NULL; err = 1; } } diff --git a/src/src/ssl_crypto.c b/src/src/ssl_crypto.c index f2ff781..4744304 100644 --- a/src/src/ssl_crypto.c +++ b/src/src/ssl_crypto.c @@ -1,6 +1,6 @@ /* ssl_crypto.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifndef WOLFSSL_SSL_CRYPTO_INCLUDED #ifndef WOLFSSL_IGNORE_FILE_WARN @@ -2543,21 +2538,23 @@ WOLFSSL_DES_LONG wolfSSL_DES_cbc_cksum(const unsigned char* in, if ((!err) && (dataSz % DES_BLOCK_SIZE)) { /* Allocate a buffer big enough to hold padded input. */ dataSz += DES_BLOCK_SIZE - (dataSz % DES_BLOCK_SIZE); - data = (unsigned char*)XMALLOC(dataSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + data = (unsigned char*)XMALLOC((size_t)dataSz, NULL, + DYNAMIC_TYPE_TMP_BUFFER); if (data == NULL) { WOLFSSL_MSG("Issue creating temporary buffer"); err = 1; } else { /* Copy input and pad with 0s. */ - XMEMCPY(data, in, length); - XMEMSET(data + length, 0, dataSz - length); + XMEMCPY(data, in, (size_t)length); + XMEMSET(data + length, 0, (size_t)(dataSz - length)); } } if (!err) { /* Allocate buffer to hold encrypted data. */ - tmp = (unsigned char*)XMALLOC(dataSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + tmp = (unsigned char*)XMALLOC((size_t)dataSz, NULL, + DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) { WOLFSSL_MSG("Issue creating temporary buffer"); err = 1; @@ -2637,7 +2634,7 @@ void wolfSSL_DES_cbc_encrypt(const unsigned char* input, unsigned char* output, if (lb_sz != 0) { /* Create a 0 padded block from remaining bytes. */ XMEMSET(lastBlock, 0, DES_BLOCK_SIZE); - XMEMCPY(lastBlock, input + len, lb_sz); + XMEMCPY(lastBlock, input + len, (size_t)lb_sz); /* Encrypt last block into output. */ wc_Des_CbcEncrypt(des, output + len, lastBlock, (word32)DES_BLOCK_SIZE); @@ -2651,7 +2648,7 @@ void wolfSSL_DES_cbc_encrypt(const unsigned char* input, unsigned char* output, wc_Des_CbcDecrypt(des, lastBlock, input + len, (word32)DES_BLOCK_SIZE); /* Copy out the required amount of the decrypted block. */ - XMEMCPY(output + len, lastBlock, lb_sz); + XMEMCPY(output + len, lastBlock, (size_t)lb_sz); } } } @@ -2775,7 +2772,7 @@ void wolfSSL_DES_ede3_cbc_encrypt(const unsigned char* input, if (lb_sz != 0) { /* Create a 0 padded block from remaining bytes. */ XMEMSET(lastBlock, 0, DES_BLOCK_SIZE); - XMEMCPY(lastBlock, input + len, lb_sz); + XMEMCPY(lastBlock, input + len, (size_t)lb_sz); /* Encrypt last block into output. */ ret = wc_Des3_CbcEncrypt(des3, output + len, lastBlock, (word32)DES_BLOCK_SIZE); @@ -2825,7 +2822,7 @@ void wolfSSL_DES_ede3_cbc_encrypt(const unsigned char* input, (void)ret; #endif /* Copy out the required amount of the decrypted block. */ - XMEMCPY(output + len, lastBlock, lb_sz); + XMEMCPY(output + len, lastBlock, (size_t)lb_sz); } } } @@ -2940,7 +2937,7 @@ static int wolfssl_aes_set_key(const unsigned char *key, const int bits, return WOLFSSL_FATAL_ERROR; } - if (wc_AesSetKey((Aes*)aes, key, ((bits)/8), NULL, enc) != 0) { + if (wc_AesSetKey((Aes*)aes, key, (word32)((bits)/8), NULL, enc) != 0) { WOLFSSL_MSG("Error in setting AES key"); return WOLFSSL_FATAL_ERROR; } diff --git a/src/src/ssl_load.c b/src/src/ssl_load.c index 004cb65..24c8af1 100644 --- a/src/src/ssl_load.c +++ b/src/src/ssl_load.c @@ -1,6 +1,6 @@ /* ssl_load.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include /* * WOLFSSL_SYS_CA_CERTS @@ -35,8 +30,10 @@ #ifdef WOLFSSL_SYS_CA_CERTS #ifdef _WIN32 + #define _WINSOCKAPI_ /* block inclusion of winsock.h header file */ #include #include + #undef _WINSOCKAPI_ /* undefine it for MINGW winsock2.h header file */ /* mingw gcc does not support pragma comment, and the * linking with crypt32 is handled in configure.ac */ @@ -132,7 +129,7 @@ static int DataToDerBuffer(const unsigned char* buff, word32 len, int format, /* Data in buffer has PEM format - extract DER data. */ if (format == WOLFSSL_FILETYPE_PEM) { #ifdef WOLFSSL_PEM_TO_DER - ret = PemToDer(buff, len, type, der, heap, info, algId); + ret = PemToDer(buff, (long)(len), type, der, heap, info, algId); if (ret != 0) { FreeDer(der); } @@ -949,6 +946,9 @@ static int ProcessBufferTryDecodeDilithium(WOLFSSL_CTX* ctx, WOLFSSL* ssl, int ret; word32 idx; dilithium_key* key; + int keyFormatTemp = 0; + int keyTypeTemp; + int keySizeTemp; /* Allocate a Dilithium key to parse into. */ key = (dilithium_key*)XMALLOC(sizeof(dilithium_key), heap, @@ -959,74 +959,74 @@ static int ProcessBufferTryDecodeDilithium(WOLFSSL_CTX* ctx, WOLFSSL* ssl, /* Initialize Dilithium key. */ ret = wc_dilithium_init(key); - if (ret == 0) { - /* Set up key to parse the format specified. */ - if ((*keyFormat == DILITHIUM_LEVEL2k) || ((*keyFormat == 0) && - ((der->length == DILITHIUM_LEVEL2_KEY_SIZE) || - (der->length == DILITHIUM_LEVEL2_PRV_KEY_SIZE)))) { - ret = wc_dilithium_set_level(key, 2); - } - else if ((*keyFormat == DILITHIUM_LEVEL3k) || ((*keyFormat == 0) && - ((der->length == DILITHIUM_LEVEL3_KEY_SIZE) || - (der->length == DILITHIUM_LEVEL3_PRV_KEY_SIZE)))) { - ret = wc_dilithium_set_level(key, 3); - } - else if ((*keyFormat == DILITHIUM_LEVEL5k) || ((*keyFormat == 0) && - ((der->length == DILITHIUM_LEVEL5_KEY_SIZE) || - (der->length == DILITHIUM_LEVEL5_PRV_KEY_SIZE)))) { - ret = wc_dilithium_set_level(key, 5); - } - else { - wc_dilithium_free(key); - ret = ALGO_ID_E; - } - } - if (ret == 0) { /* Decode as a Dilithium private key. */ idx = 0; ret = wc_Dilithium_PrivateKeyDecode(der->buffer, &idx, key, der->length); if (ret == 0) { - /* Get the minimum Dilithium key size from SSL or SSL context - * object. */ - int minKeySz = ssl ? ssl->options.minDilithiumKeySz : - ctx->minDilithiumKeySz; - - /* Format is known. */ - if (*keyFormat == DILITHIUM_LEVEL2k) { - *keyType = dilithium_level2_sa_algo; - *keySize = DILITHIUM_LEVEL2_KEY_SIZE; - } - else if (*keyFormat == DILITHIUM_LEVEL3k) { - *keyType = dilithium_level3_sa_algo; - *keySize = DILITHIUM_LEVEL3_KEY_SIZE; + ret = dilithium_get_oid_sum(key, &keyFormatTemp); + if (ret == 0) { + /* Format is known. */ + #if defined(WOLFSSL_DILITHIUM_FIPS204_DRAFT) + if (keyFormatTemp == DILITHIUM_LEVEL2k) { + keyTypeTemp = dilithium_level2_sa_algo; + keySizeTemp = DILITHIUM_LEVEL2_KEY_SIZE; + } + else if (keyFormatTemp == DILITHIUM_LEVEL3k) { + keyTypeTemp = dilithium_level3_sa_algo; + keySizeTemp = DILITHIUM_LEVEL3_KEY_SIZE; + } + else if (keyFormatTemp == DILITHIUM_LEVEL5k) { + keyTypeTemp = dilithium_level5_sa_algo; + keySizeTemp = DILITHIUM_LEVEL5_KEY_SIZE; + } + else + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ + if (keyFormatTemp == ML_DSA_LEVEL2k) { + keyTypeTemp = dilithium_level2_sa_algo; + keySizeTemp = ML_DSA_LEVEL2_KEY_SIZE; + } + else if (keyFormatTemp == ML_DSA_LEVEL3k) { + keyTypeTemp = dilithium_level3_sa_algo; + keySizeTemp = ML_DSA_LEVEL3_KEY_SIZE; + } + else if (keyFormatTemp == ML_DSA_LEVEL5k) { + keyTypeTemp = dilithium_level5_sa_algo; + keySizeTemp = ML_DSA_LEVEL5_KEY_SIZE; + } + else { + ret = ALGO_ID_E; + } } - else if (*keyFormat == DILITHIUM_LEVEL5k) { - *keyType = dilithium_level5_sa_algo; - *keySize = DILITHIUM_LEVEL5_KEY_SIZE; + + if (ret == 0) { + /* Get the minimum Dilithium key size from SSL or SSL context + * object. */ + int minKeySz = ssl ? ssl->options.minDilithiumKeySz : + ctx->minDilithiumKeySz; + + /* Check that the size of the Dilithium key is enough. */ + if (keySizeTemp < minKeySz) { + WOLFSSL_MSG("Dilithium private key too small"); + ret = DILITHIUM_KEY_SIZE_E; + } } - /* Check that the size of the Dilithium key is enough. */ - if (*keySize < minKeySz) { - WOLFSSL_MSG("Dilithium private key too small"); - ret = DILITHIUM_KEY_SIZE_E; + if (ret == 0) { + *keyFormat = keyFormatTemp; + *keyType = keyTypeTemp; + *keySize = keySizeTemp; } } - /* Not a Dilithium key but check whether we know what it is. */ else if (*keyFormat == 0) { WOLFSSL_MSG("Not a Dilithium key"); - /* Format unknown so keep trying. */ + /* Unknown format wasn't dilithium, so keep trying other formats. */ ret = 0; } /* Free dynamically allocated data in key. */ wc_dilithium_free(key); } - else if ((ret == WC_NO_ERR_TRACE(ALGO_ID_E)) && (*keyFormat == 0)) { - WOLFSSL_MSG("Not a Dilithium key"); - /* Format unknown so keep trying. */ - ret = 0; - } /* Dispose of allocated key. */ XFREE(key, heap, DYNAMIC_TYPE_DILITHIUM); @@ -1057,6 +1057,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, int devId = wolfSSL_CTX_GetDevId(ctx, ssl); byte* keyType = NULL; int* keySz = NULL; + int matchAnyKey = 0; (void)heap; (void)devId; @@ -1108,8 +1109,19 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, ret = ProcessBufferTryDecodeRsa(ctx, ssl, der, keyFormat, heap, devId, keyType, keySz); #endif + matchAnyKey = 1; } -#endif +#ifdef WC_RSA_PSS + if((ret == 0) && (*keyFormat == RSAPSSk)) { + /* + Require logic to verify that the der is RSAPSSk (when *keyFormat == RSAPSSK), + and to detect that the der is RSAPSSk (when *keyFormat == 0). + */ + + matchAnyKey = 1; + } +#endif /* WC_RSA_PSS */ +#endif /* NO_RSA */ #ifdef HAVE_ECC /* Try ECC if key format is ECDSA or SM2, or yet unknown. */ if ((ret == 0) && ((*keyFormat == 0) || (*keyFormat == ECDSAk) @@ -1119,6 +1131,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, )) { ret = ProcessBufferTryDecodeEcc(ctx, ssl, der, keyFormat, heap, devId, keyType, keySz); + matchAnyKey = 1; } #endif /* HAVE_ECC */ #if defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) @@ -1126,6 +1139,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, if ((ret == 0) && ((*keyFormat == 0 || *keyFormat == ED25519k))) { ret = ProcessBufferTryDecodeEd25519(ctx, ssl, der, keyFormat, heap, devId, keyType, keySz); + matchAnyKey = 1; } #endif /* HAVE_ED25519 && HAVE_ED25519_KEY_IMPORT */ #if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) @@ -1133,6 +1147,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, if ((ret == 0) && ((*keyFormat == 0 || *keyFormat == ED448k))) { ret = ProcessBufferTryDecodeEd448(ctx, ssl, der, keyFormat, heap, devId, keyType, keySz); + matchAnyKey = 1; } #endif /* HAVE_ED448 && HAVE_ED448_KEY_IMPORT */ #if defined(HAVE_FALCON) @@ -1141,22 +1156,33 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, (*keyFormat == FALCON_LEVEL5k))) { ret = ProcessBufferTryDecodeFalcon(ctx, ssl, der, keyFormat, heap, keyType, keySz); + matchAnyKey = 1; } #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_SIGN) && \ !defined(WOLFSSL_DILITHIUM_NO_ASN1) /* Try Falcon if key format is Dilithium level 2k, 3k or 5k or yet unknown. */ - if ((ret == 0) && ((*keyFormat == 0) || (*keyFormat == DILITHIUM_LEVEL2k) || - (*keyFormat == DILITHIUM_LEVEL3k) || - (*keyFormat == DILITHIUM_LEVEL5k))) { + if ((ret == 0) && + ((*keyFormat == 0) || + (*keyFormat == ML_DSA_LEVEL2k) || + (*keyFormat == ML_DSA_LEVEL3k) || + (*keyFormat == ML_DSA_LEVEL5k) + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT + || (*keyFormat == DILITHIUM_LEVEL2k) + || (*keyFormat == DILITHIUM_LEVEL3k) + || (*keyFormat == DILITHIUM_LEVEL5k) + #endif + )) { ret = ProcessBufferTryDecodeDilithium(ctx, ssl, der, keyFormat, heap, keyType, keySz); + matchAnyKey = 1; } #endif /* HAVE_DILITHIUM */ /* Check we know the format. */ - if ((ret == 0) && (*keyFormat == 0)) { + if ((ret == 0) && + ((*keyFormat == 0) || ((*keyFormat != 0) && (matchAnyKey == 0)))) { WOLFSSL_MSG("Not a supported key type"); /* Not supported key format. */ ret = WOLFSSL_BAD_FILE; @@ -1213,7 +1239,7 @@ static int ProcessBufferPrivPkcs8Dec(EncryptedInfo* info, DerBuffer* der, } if (ret >= 0) { /* Zero out encrypted data not overwritten. */ - ForceZero(der->buffer + ret, der->length - ret); + ForceZero(der->buffer + ret, der->length - (word32)ret); /* Set decrypted data length. */ der->length = (word32)ret; } @@ -1461,9 +1487,14 @@ static void wolfssl_set_have_from_key_oid(WOLFSSL_CTX* ctx, WOLFSSL* ssl, break; #endif /* HAVE_FALCON */ #ifdef HAVE_DILITHIUM + case ML_DSA_LEVEL2k: + case ML_DSA_LEVEL3k: + case ML_DSA_LEVEL5k: + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT case DILITHIUM_LEVEL2k: case DILITHIUM_LEVEL3k: case DILITHIUM_LEVEL5k: + #endif if (ssl != NULL) { ssl->options.haveDilithiumSig = 1; } @@ -1532,9 +1563,14 @@ static void ProcessBufferCertSetHave(WOLFSSL_CTX* ctx, WOLFSSL* ssl, break; #endif #ifdef HAVE_DILITHIUM + case CTC_ML_DSA_LEVEL2: + case CTC_ML_DSA_LEVEL3: + case CTC_ML_DSA_LEVEL5: + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT case CTC_DILITHIUM_LEVEL2: case CTC_DILITHIUM_LEVEL3: case CTC_DILITHIUM_LEVEL5: + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ WOLFSSL_MSG("Dilithium cert signature"); if (ssl) { ssl->options.haveDilithiumSig = 1; @@ -1705,6 +1741,7 @@ static int ProcessBufferCertPublicKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl, break; #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT case DILITHIUM_LEVEL2k: keyType = dilithium_level2_sa_algo; /* Dilithium is fixed key size */ @@ -1735,6 +1772,37 @@ static int ProcessBufferCertPublicKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DILITHIUM_KEY_SIZE_E); } break; + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ + case ML_DSA_LEVEL2k: + keyType = dilithium_level2_sa_algo; + /* Dilithium is fixed key size */ + keySz = ML_DSA_LEVEL2_KEY_SIZE; + if (checkKeySz) { + ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz : + ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz, + DILITHIUM_KEY_SIZE_E); + } + break; + case ML_DSA_LEVEL3k: + keyType = dilithium_level3_sa_algo; + /* Dilithium is fixed key size */ + keySz = ML_DSA_LEVEL3_KEY_SIZE; + if (checkKeySz) { + ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz : + ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz, + DILITHIUM_KEY_SIZE_E); + } + break; + case ML_DSA_LEVEL5k: + keyType = dilithium_level5_sa_algo; + /* Dilithium is fixed key size */ + keySz = ML_DSA_LEVEL5_KEY_SIZE; + if (checkKeySz) { + ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz : + ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz, + DILITHIUM_KEY_SIZE_E); + } + break; #endif /* HAVE_DILITHIUM */ default: @@ -1894,6 +1962,7 @@ static int ProcessBufferCertAltPublicKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl, break; #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT case DILITHIUM_LEVEL2k: keyType = dilithium_level2_sa_algo; /* Dilithium is fixed key size */ @@ -1924,6 +1993,37 @@ static int ProcessBufferCertAltPublicKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DILITHIUM_KEY_SIZE_E); } break; + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ + case ML_DSA_LEVEL2k: + keyType = dilithium_level2_sa_algo; + /* Dilithium is fixed key size */ + keySz = ML_DSA_LEVEL2_KEY_SIZE; + if (checkKeySz) { + ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz : + ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz, + DILITHIUM_KEY_SIZE_E); + } + break; + case ML_DSA_LEVEL3k: + keyType = dilithium_level3_sa_algo; + /* Dilithium is fixed key size */ + keySz = ML_DSA_LEVEL3_KEY_SIZE; + if (checkKeySz) { + ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz : + ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz, + DILITHIUM_KEY_SIZE_E); + } + break; + case ML_DSA_LEVEL5k: + keyType = dilithium_level5_sa_algo; + /* Dilithium is fixed key size */ + keySz = ML_DSA_LEVEL5_KEY_SIZE; + if (checkKeySz) { + ret = CHECK_KEY_SZ(ssl ? ssl->options.minDilithiumKeySz : + ctx->minDilithiumKeySz, DILITHIUM_MAX_KEY_SIZE, keySz, + DILITHIUM_KEY_SIZE_E); + } + break; #endif /* HAVE_DILITHIUM */ default: @@ -2803,7 +2903,7 @@ int wolfSSL_CTX_load_verify_locations_ex(WOLFSSL_CTX* ctx, const char* file, } if (file != NULL) { - /* Load the PEM formatted CA file. */ + /* Load the PEM formatted CA file */ ret = ProcessFile(ctx, file, WOLFSSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL, verify); #ifndef NO_WOLFSSL_DIR @@ -4739,6 +4839,7 @@ long wolfSSL_CTX_add_extra_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509) if (ret == 1) { /* On success WOLFSSL_X509 memory is responsibility of SSL context. */ wolfSSL_X509_free(x509); + x509 = NULL; } WOLFSSL_LEAVE("wolfSSL_CTX_add_extra_chain_cert", ret); @@ -4832,6 +4933,7 @@ int wolfSSL_CTX_add0_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509) if (ret == 1) { /* Down reference or free original now as we own certificate. */ wolfSSL_X509_free(x509); + x509 = NULL; } return ret; @@ -4890,6 +4992,7 @@ int wolfSSL_CTX_add1_chain_cert(WOLFSSL_CTX* ctx, WOLFSSL_X509* x509) if (ret != 1) { /* Decrease reference count on error as we didn't store it. */ wolfSSL_X509_free(x509); + x509 = NULL; } } @@ -4953,6 +5056,7 @@ int wolfSSL_add0_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509) if (ret != 1) { /* Free it now on error. */ wolfSSL_X509_free(x509); + x509 = NULL; } } } @@ -4985,6 +5089,7 @@ int wolfSSL_add1_chain_cert(WOLFSSL* ssl, WOLFSSL_X509* x509) if ((ret = wolfSSL_add0_chain_cert(ssl, x509)) != 1) { /* Decrease reference count on error as not stored. */ wolfSSL_X509_free(x509); + x509 = NULL; } } @@ -5113,7 +5218,8 @@ int wolfSSL_CTX_use_RSAPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL_RSA* rsa) if (ret == 1) { /* Allocate memory to hold DER encoding.. */ - der = (unsigned char*)XMALLOC(derSize, NULL, DYNAMIC_TYPE_TMP_BUFFER); + der = (unsigned char*)XMALLOC((size_t)derSize, NULL, + DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { WOLFSSL_MSG("Malloc failure"); ret = MEMORY_E; @@ -5355,8 +5461,8 @@ int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz, } if (ret == 1) { /* Copy p and g into allocated buffers. */ - XMEMCPY(pAlloc, p, pSz); - XMEMCPY(gAlloc, g, gSz); + XMEMCPY(pAlloc, p, (size_t)pSz); + XMEMCPY(gAlloc, g, (size_t)gSz); /* Set the buffers into SSL. */ ret = wolfssl_set_tmp_dh(ssl, pAlloc, pSz, gAlloc, gSz); } @@ -5514,8 +5620,8 @@ int wolfSSL_CTX_SetTmpDH(WOLFSSL_CTX* ctx, const unsigned char* p, int pSz, if (ret == 1) { /* Copy p and g into allocated buffers. */ - XMEMCPY(pAlloc, p, pSz); - XMEMCPY(gAlloc, g, gSz); + XMEMCPY(pAlloc, p, (size_t)pSz); + XMEMCPY(gAlloc, g, (size_t)gSz); /* Set the buffers into SSL context. */ ret = wolfssl_ctx_set_tmp_dh(ctx, pAlloc, pSz, gAlloc, gSz); } @@ -5567,8 +5673,8 @@ long wolfSSL_set_tmp_dh(WOLFSSL *ssl, WOLFSSL_DH *dh) if (ret == 1) { /* Allocate buffers for p and g to be assigned into SSL. */ - p = (byte*)XMALLOC(pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); - g = (byte*)XMALLOC(gSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + p = (byte*)XMALLOC((size_t)pSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + g = (byte*)XMALLOC((size_t)gSz, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); if ((p == NULL) || (g == NULL)) { ret = MEMORY_E; } @@ -5633,8 +5739,8 @@ long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX* ctx, WOLFSSL_DH* dh) if (ret == 1) { /* Allocate buffers for p and g to be assigned into SSL. */ - p = (byte*)XMALLOC(pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY); - g = (byte*)XMALLOC(gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY); + p = (byte*)XMALLOC((size_t)pSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY); + g = (byte*)XMALLOC((size_t)gSz, ctx->heap, DYNAMIC_TYPE_PUBLIC_KEY); if ((p == NULL) || (g == NULL)) { ret = MEMORY_E; } diff --git a/src/src/ssl_misc.c b/src/src/ssl_misc.c index 9a5f4b0..56a71e8 100644 --- a/src/src/ssl_misc.c +++ b/src/src/ssl_misc.c @@ -1,6 +1,6 @@ /* ssl_misc.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,13 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include -#include -#include +#include #if !defined(WOLFSSL_SSL_MISC_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN diff --git a/src/src/ssl_p7p12.c b/src/src/ssl_p7p12.c index 12ef33c..00395c9 100644 --- a/src/src/ssl_p7p12.c +++ b/src/src/ssl_p7p12.c @@ -1,6 +1,6 @@ /* ssl_p7p12.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if defined(OPENSSL_EXTRA) && (defined(HAVE_FIPS) || defined(HAVE_SELFTEST)) #include @@ -231,6 +227,7 @@ WOLFSSL_STACK* wolfSSL_PKCS7_to_stack(PKCS7* pkcs7) if (x509) { if (wolfSSL_sk_X509_push(ret, x509) <= 0) { wolfSSL_X509_free(x509); + x509 = NULL; WOLFSSL_MSG("wolfSSL_sk_X509_push error"); goto error; } @@ -1180,6 +1177,8 @@ PKCS7* wolfSSL_SMIME_read_PKCS7(WOLFSSL_BIO* in, DYNAMIC_TYPE_PKCS7); if (canonSection == NULL) { goto error; + } else { + XMEMSET(canonSection, 0, (word32)canonSize); } lineLen = wolfSSL_BIO_gets(in, section, remainLen); @@ -1912,12 +1911,14 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, WOLFSSL_MSG("Issue with parsing certificate"); FreeDecodedCert(DeCert); wolfSSL_X509_free(x509); + x509 = NULL; } else { if (CopyDecodedToX509(x509, DeCert) != 0) { WOLFSSL_MSG("Failed to copy decoded cert"); FreeDecodedCert(DeCert); wolfSSL_X509_free(x509); + x509 = NULL; wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL; XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY); XFREE(certData, heap, DYNAMIC_TYPE_PKCS); @@ -1937,6 +1938,7 @@ int wolfSSL_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, if (wolfSSL_sk_X509_push(*ca, x509) <= 0) { WOLFSSL_MSG("Failed to push x509 onto stack"); wolfSSL_X509_free(x509); + x509 = NULL; wolfSSL_sk_X509_pop_free(*ca, NULL); *ca = NULL; XFREE(pk, heap, DYNAMIC_TYPE_PUBLIC_KEY); XFREE(certData, heap, DYNAMIC_TYPE_PKCS); diff --git a/src/src/ssl_sess.c b/src/src/ssl_sess.c index 1471b9d..c5e0e68 100644 --- a/src/src/ssl_sess.c +++ b/src/src/ssl_sess.c @@ -1,6 +1,6 @@ /* ssl_sess.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if !defined(WOLFSSL_SSL_SESS_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN @@ -375,7 +370,7 @@ int wolfSSL_SetServerID(WOLFSSL* ssl, const byte* id, int len, int newSession) WOLFSSL_MSG("Valid ServerID not cached already"); ssl->session->idLen = (word16)len; - XMEMCPY(ssl->session->serverID, id, len); + XMEMCPY(ssl->session->serverID, id, (size_t)len); } #ifdef HAVE_EXT_CACHE else { @@ -1457,6 +1452,7 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output) #if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) if (peer != NULL) { wolfSSL_X509_free(peer); + peer = NULL; } #endif @@ -1819,7 +1815,7 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession, ticLen = addSession->ticketLen; /* Alloc Memory here to avoid syscalls during lock */ if (ticLen > SESSION_TICKET_LEN) { - ticBuff = (byte*)XMALLOC(ticLen, NULL, + ticBuff = (byte*)XMALLOC((size_t)ticLen, NULL, DYNAMIC_TYPE_SESSION_TICK); if (ticBuff == NULL) { return MEMORY_E; @@ -1978,7 +1974,7 @@ int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession, /* Copy in the certs from the session */ addSession->chain.count = cacheSession->chain.count; XMEMCPY(addSession->chain.certs, cacheSession->chain.certs, - sizeof(x509_buffer) * cacheSession->chain.count); + sizeof(x509_buffer) * (size_t)cacheSession->chain.count); } #endif /* SESSION_CERTS */ #if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) @@ -2669,7 +2665,8 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) unsigned char *data; if (*p == NULL) - *p = (unsigned char*)XMALLOC(size, NULL, DYNAMIC_TYPE_OPENSSL); + *p = (unsigned char*)XMALLOC((size_t)size, NULL, + DYNAMIC_TYPE_OPENSSL); if (*p == NULL) return 0; data = *p; @@ -2693,7 +2690,7 @@ int wolfSSL_i2d_SSL_SESSION(WOLFSSL_SESSION* sess, unsigned char** p) c16toa((word16)sess->chain.certs[i].length, data + idx); idx += OPAQUE16_LEN; XMEMCPY(data + idx, sess->chain.certs[i].buffer, - sess->chain.certs[i].length); + (size_t)sess->chain.certs[i].length); idx += sess->chain.certs[i].length; } #endif @@ -3524,7 +3521,7 @@ int wolfSSL_SESSION_get_master_key(const WOLFSSL_SESSION* ses, size = outSz; } - XMEMCPY(out, ses->masterSecret, size); + XMEMCPY(out, ses->masterSecret, (size_t)size); return size; } @@ -3538,6 +3535,10 @@ int wolfSSL_SESSION_get_master_key_length(const WOLFSSL_SESSION* ses) #ifdef WOLFSSL_EARLY_DATA unsigned int wolfSSL_SESSION_get_max_early_data(const WOLFSSL_SESSION *session) { + if (session == NULL) { + return BAD_FUNC_ARG; + } + return session->maxEarlyDataSz; } #endif /* WOLFSSL_EARLY_DATA */ @@ -3565,7 +3566,16 @@ void SetupSession(WOLFSSL* ssl) session->side = (byte)ssl->options.side; if (!IsAtLeastTLSv1_3(ssl->version) && ssl->arrays != NULL) XMEMCPY(session->masterSecret, ssl->arrays->masterSecret, SECRET_LEN); - session->haveEMS = ssl->options.haveEMS; + /* RFC8446 Appendix D. + * implementations which support both TLS 1.3 and earlier versions SHOULD + * indicate the use of the Extended Master Secret extension in their APIs + * whenever TLS 1.3 is used. + * Set haveEMS so that we send the extension in subsequent connections that + * offer downgrades. */ + if (IsAtLeastTLSv1_3(ssl->version)) + session->haveEMS = 1; + else + session->haveEMS = ssl->options.haveEMS; #ifdef WOLFSSL_SESSION_ID_CTX /* If using compatibility layer then check for and copy over session context * id. */ @@ -3757,7 +3767,7 @@ static int wolfSSL_DupSessionEx(const WOLFSSL_SESSION* input, word16 ticLenAlloc = 0; byte *ticBuff = NULL; #endif - const size_t copyOffset = OFFSETOF(WOLFSSL_SESSION, heap) + + const size_t copyOffset = WC_OFFSETOF(WOLFSSL_SESSION, heap) + sizeof(input->heap); int ret = WOLFSSL_SUCCESS; @@ -4096,7 +4106,7 @@ void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session) ForceZero(session->sessionID, ID_LEN); if (session->type == WOLFSSL_SESSION_TYPE_HEAP) { - XFREE(session, session->heap, DYNAMIC_TYPE_SESSION); + XFREE(session, session->heap, DYNAMIC_TYPE_SESSION); /* // NOLINT(clang-analyzer-unix.Malloc) */ } } diff --git a/src/src/tls.c b/src/src/tls.c index 0e5f43b..6ad21c9 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -1,6 +1,6 @@ /* tls.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,13 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifndef WOLFCRYPT_ONLY @@ -48,12 +42,12 @@ #ifdef HAVE_CURVE448 #include #endif -#ifdef WOLFSSL_HAVE_KYBER - #include -#ifdef WOLFSSL_WC_KYBER - #include +#ifdef WOLFSSL_HAVE_MLKEM + #include +#ifdef WOLFSSL_WC_MLKEM + #include #elif defined(HAVE_LIBOQS) - #include + #include #endif #endif @@ -645,12 +639,24 @@ int MakeTlsMasterSecret(WOLFSSL* ssl) XMEMSET(handshake_hash, 0, HSHASH_SZ); ret = BuildTlsHandshakeHash(ssl, handshake_hash, &hashSz); if (ret == 0) { - ret = _MakeTlsExtendedMasterSecret( - ssl->arrays->masterSecret, SECRET_LEN, - ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz, - handshake_hash, hashSz, - IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm, - ssl->heap, ssl->devId); + #if !defined(NO_CERTS) && defined(HAVE_PK_CALLBACKS) + ret = PROTOCOLCB_UNAVAILABLE; + if (ssl->ctx->GenExtMasterCb) { + void* ctx = wolfSSL_GetGenExtMasterSecretCtx(ssl); + ret = ssl->ctx->GenExtMasterCb(ssl, handshake_hash, hashSz, + ctx); + } + if (!ssl->ctx->GenExtMasterCb || + ret == WC_NO_ERR_TRACE(PROTOCOLCB_UNAVAILABLE)) + #endif /* (HAVE_SECRET_CALLBACK) && (HAVE_EXT_SECRET_CALLBACK) */ + { + ret = _MakeTlsExtendedMasterSecret( + ssl->arrays->masterSecret, SECRET_LEN, + ssl->arrays->preMasterSecret, ssl->arrays->preMasterSz, + handshake_hash, hashSz, + IsAtLeastTLSv1_2(ssl), ssl->specs.mac_algorithm, + ssl->heap, ssl->devId); + } ForceZero(handshake_hash, hashSz); } @@ -1024,7 +1030,7 @@ static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in, if (ret != 0) return ret; - XMEMSET(hmac->innerHash, 0, macLen); + XMEMSET(hmac->innerHash, 0, (size_t)macLen); if (safeBlocks > 0) { ret = Hmac_HashUpdate(hmac, header, headerSz); @@ -1039,7 +1045,7 @@ static int Hmac_UpdateFinal_CT(Hmac* hmac, byte* digest, const byte* in, else safeBlocks = 0; - XMEMSET(digest, 0, macLen); + XMEMSET(digest, 0, (size_t)macLen); k = (unsigned int)(safeBlocks * blockSz); for (i = safeBlocks; i < blocks; i++) { unsigned char hashBlock[WC_MAX_BLOCK_SIZE]; @@ -1190,8 +1196,8 @@ static int Hmac_UpdateFinal(Hmac* hmac, byte* digest, const byte* in, ret = wc_HmacUpdate(hmac, header, headerSz); if (ret == 0) { /* Fill the rest of the block with any available data. */ - word32 currSz = ctMaskLT((int)msgSz, blockSz) & msgSz; - currSz |= ctMaskGTE((int)msgSz, blockSz) & blockSz; + word32 currSz = ctMaskLT((int)msgSz, (int)blockSz) & msgSz; + currSz |= ctMaskGTE((int)msgSz, (int)blockSz) & blockSz; currSz -= WOLFSSL_TLS_HMAC_INNER_SZ; currSz &= ~(0 - (currSz >> 31)); ret = wc_HmacUpdate(hmac, in, currSz); @@ -1338,7 +1344,7 @@ int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz, #ifdef HAVE_BLAKE2 if (wolfSSL_GetHmacType(ssl) == WC_HASH_TYPE_BLAKE2B) { ret = Hmac_UpdateFinal(&hmac, digest, in, - sz + hashSz + padSz + 1, myInner, innerSz); + sz + hashSz + (word32)padSz + 1, myInner, innerSz); } else #endif @@ -1349,8 +1355,9 @@ int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz, } #else - ret = Hmac_UpdateFinal(&hmac, digest, in, sz + hashSz + padSz + 1, - myInner, innerSz); + ret = Hmac_UpdateFinal(&hmac, digest, in, sz + hashSz + + (word32)(padSz) + 1, + myInner, innerSz); #endif } else { @@ -2964,7 +2971,10 @@ static int TLSX_TCA_VerifyParse(WOLFSSL* ssl, byte isRequest) (void)ssl; if (!isRequest) { - #ifndef NO_WOLFSSL_CLIENT + /* RFC 6066 section 6 states that the server responding + * to trusted_ca_keys is optional. Do not error out unless + * opted into with the define WOLFSSL_REQUIRE_TCA. */ + #if !defined(NO_WOLFSSL_CLIENT) && defined(WOLFSSL_REQUIRE_TCA) TLSX* extension = TLSX_Find(ssl->extensions, TLSX_TRUSTED_CA_KEYS); if (extension && !extension->resp) { @@ -2972,7 +2982,9 @@ static int TLSX_TCA_VerifyParse(WOLFSSL* ssl, byte isRequest) WOLFSSL_ERROR_VERBOSE(TCA_ABSENT_ERROR); return TCA_ABSENT_ERROR; } - #endif /* NO_WOLFSSL_CLIENT */ + #else + WOLFSSL_MSG("No response received for trusted_ca_keys. Continuing."); + #endif /* !NO_WOLFSSL_CLIENT && WOLFSSL_REQUIRE_TCA */ } return 0; @@ -3226,6 +3238,14 @@ word16 TLSX_CSR_GetSize_ex(CertificateStatusRequest* csr, byte isRequest, #endif #if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) if (!isRequest && IsAtLeastTLSv1_3(csr->ssl->version)) { +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + if (csr->ssl != NULL && SSL_CM(csr->ssl) != NULL && + SSL_CM(csr->ssl)->ocsp_stapling != NULL && + SSL_CM(csr->ssl)->ocsp_stapling->statusCb != NULL && + idx == 0) { + return OPAQUE8_LEN + OPAQUE24_LEN + csr->ssl->ocspRespSz; + } +#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ return (word16)(OPAQUE8_LEN + OPAQUE24_LEN + csr->responses[idx].length); } @@ -3235,6 +3255,70 @@ word16 TLSX_CSR_GetSize_ex(CertificateStatusRequest* csr, byte isRequest, return size; } +#if (defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER)) && \ +(defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) +static int TLSX_CSR_SetResponseWithStatusCB(WOLFSSL *ssl) +{ + void *ioCtx = NULL; + WOLFSSL_OCSP *ocsp; + int ret; + + if (ssl == NULL || SSL_CM(ssl) == NULL) + return BAD_FUNC_ARG; + ocsp = SSL_CM(ssl)->ocsp_stapling; + if (ocsp == NULL || ocsp->statusCb == NULL) + return BAD_FUNC_ARG; + ioCtx = (ssl->ocspIOCtx != NULL) ? ssl->ocspIOCtx : ocsp->cm->ocspIOCtx; + ret = ocsp->statusCb(ssl, ioCtx); + switch (ret) { + case SSL_TLSEXT_ERR_OK: + if (ssl->ocspRespSz > 0) { + /* ack the extension, status cb provided the response in + * ssl->ocspResp */ + TLSX_SetResponse(ssl, TLSX_STATUS_REQUEST); + ssl->status_request = WOLFSSL_CSR_OCSP; + } + ret = 0; + break; + case SSL_TLSEXT_ERR_NOACK: + /* suppressing as not critical */ + ret = 0; + break; + case SSL_TLSEXT_ERR_ALERT_FATAL: + default: + ret = WOLFSSL_FATAL_ERROR; + break; + } + return ret; +} + +static int TLSX_CSR_WriteWithStatusCB(CertificateStatusRequest* csr, + byte* output) +{ + WOLFSSL *ssl = csr->ssl; + WOLFSSL_OCSP *ocsp; + word16 offset = 0; + byte *response; + int respSz; + + if (ssl == NULL || SSL_CM(ssl) == NULL) + return BAD_FUNC_ARG; + ocsp = SSL_CM(ssl)->ocsp_stapling; + if (ocsp == NULL || ocsp->statusCb == NULL) + return BAD_FUNC_ARG; + response = ssl->ocspResp; + respSz = ssl->ocspRespSz; + if (response == NULL || respSz == 0) + return BAD_FUNC_ARG; + output[offset++] = WOLFSSL_CSR_OCSP; + c32to24(respSz, output + offset); + offset += OPAQUE24_LEN; + XMEMCPY(output + offset, response, respSz); + return offset + respSz; +} +#endif /* (TLS13 && !NO_WOLFSLL_SERVER) && (OPENSSL_ALL || WOLFSSL_NGINX || +WOLFSSL_HAPROXY) */ + static word16 TLSX_CSR_GetSize(CertificateStatusRequest* csr, byte isRequest) { return TLSX_CSR_GetSize_ex(csr, isRequest, 0); @@ -3287,6 +3371,14 @@ int TLSX_CSR_Write_ex(CertificateStatusRequest* csr, byte* output, #if defined(WOLFSSL_TLS13) && !defined(NO_WOLFSSL_SERVER) if (!isRequest && IsAtLeastTLSv1_3(csr->ssl->version)) { word16 offset = 0; +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + if (csr->ssl != NULL && SSL_CM(csr->ssl) != NULL && + SSL_CM(csr->ssl)->ocsp_stapling != NULL && + SSL_CM(csr->ssl)->ocsp_stapling->statusCb != NULL && + idx == 0) { + return TLSX_CSR_WriteWithStatusCB(csr, output); + } +#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ output[offset++] = csr->status_type; c32to24(csr->responses[idx].length, output + offset); offset += OPAQUE24_LEN; @@ -3451,7 +3543,7 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, const byte* input, word16 length, if (request) { XMEMCPY(request->nonce, csr->request.ocsp[0].nonce, - csr->request.ocsp[0].nonceSz); + (size_t)csr->request.ocsp[0].nonceSz); request->nonceSz = csr->request.ocsp[0].nonceSz; } } @@ -3562,7 +3654,13 @@ static int TLSX_CSR_Parse(WOLFSSL* ssl, const byte* input, word16 length, #if defined(WOLFSSL_TLS13) if (ssl->options.tls1_3) { - +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + if (ssl != NULL && SSL_CM(ssl) != NULL && + SSL_CM(ssl)->ocsp_stapling != NULL && + SSL_CM(ssl)->ocsp_stapling->statusCb != NULL) { + return TLSX_CSR_SetResponseWithStatusCB(ssl); +} +#endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ if (ssl->buffers.certificate == NULL) { WOLFSSL_MSG("Certificate buffer not set!"); return BUFFER_ERROR; @@ -3655,14 +3753,14 @@ int TLSX_CSR_InitRequest_ex(TLSX* extensions, DecodedCert* cert, csr->requests--; } /* preserve nonce */ - XMEMCPY(nonce, request->nonce, nonceSz); + XMEMCPY(nonce, csr->request.ocsp->nonce, (size_t)nonceSz); if (req_cnt < MAX_CERT_EXTENSIONS) { if ((ret = InitOcspRequest(request, cert, 0, heap)) != 0) return ret; /* restore nonce */ - XMEMCPY(request->nonce, nonce, nonceSz); + XMEMCPY(csr->request.ocsp->nonce, nonce, (size_t)nonceSz); request->nonceSz = nonceSz; csr->requests++; } @@ -3977,7 +4075,7 @@ static int TLSX_CSR2_Parse(WOLFSSL* ssl, const byte* input, word16 length, if (request) { XMEMCPY(request->nonce, csr2->request.ocsp[0].nonce, - csr2->request.ocsp[0].nonceSz); + (size_t)csr2->request.ocsp[0].nonceSz); request->nonceSz = csr2->request.ocsp[0].nonceSz; @@ -4059,6 +4157,14 @@ static int TLSX_CSR2_Parse(WOLFSSL* ssl, const byte* input, word16 length, continue; } +#if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) + /* OpenSSL status CB supports only CERTIFICATE STATUS REQ V1 */ + if (ssl != NULL && SSL_CM(ssl) != NULL && + SSL_CM(ssl)->ocsp_stapling != NULL && + SSL_CM(ssl)->ocsp_stapling->statusCb != NULL) { + return 0; + } +#endif /* if using status_request and already sending it, remove it * and prefer to use the v2 version */ #ifdef HAVE_CERTIFICATE_STATUS_REQUEST @@ -4189,7 +4295,8 @@ int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert, byte isPeer, int nonceSz = csr2->request.ocsp[0].nonceSz; /* preserve nonce, replicating nonce of ocsp[0] */ - XMEMCPY(nonce, csr2->request.ocsp[0].nonce, nonceSz); + XMEMCPY(nonce, csr2->request.ocsp[0].nonce, + (size_t)nonceSz); if ((ret = InitOcspRequest( &csr2->request.ocsp[csr2->requests], cert, @@ -4198,7 +4305,7 @@ int TLSX_CSR2_InitRequests(TLSX* extensions, DecodedCert* cert, byte isPeer, /* restore nonce */ XMEMCPY(csr2->request.ocsp[csr2->requests].nonce, - nonce, nonceSz); + nonce, (size_t)nonceSz); csr2->request.ocsp[csr2->requests].nonceSz = nonceSz; csr2->requests++; } @@ -4316,6 +4423,11 @@ int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type, CertificateStatusRequestItemV2* last = (CertificateStatusRequestItemV2*)extension->data; + if (last == NULL) { + XFREE(csr2, heap, DYNAMIC_TYPE_TLSX); + return BAD_FUNC_ARG; + } + for (; last->next; last = last->next); last->next = csr2; @@ -4349,7 +4461,7 @@ int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type, #ifdef HAVE_SUPPORTED_CURVES #if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448) \ - && !defined(HAVE_FFDHE) && !defined(WOLFSSL_HAVE_KYBER) + && !defined(HAVE_FFDHE) && !defined(WOLFSSL_HAVE_MLKEM) #error Elliptic Curves Extension requires Elliptic Curve Cryptography or liboqs groups. \ Use --enable-ecc and/or --enable-liboqs in the configure script or \ define HAVE_ECC. Alternatively use FFDHE for DH cipher suites. @@ -4809,7 +4921,7 @@ static int tlsx_ffdhe_find_group(WOLFSSL* ssl, SupportedCurve* clientGroup, const DhParams* params = NULL; for (; serverGroup != NULL; serverGroup = serverGroup->next) { - if (!WOLFSSL_NAMED_GROUP_IS_FFHDE(serverGroup->name)) + if (!WOLFSSL_NAMED_GROUP_IS_FFDHE(serverGroup->name)) continue; for (group = clientGroup; group != NULL; group = group->next) { @@ -4886,7 +4998,7 @@ static int tlsx_ffdhe_find_group(WOLFSSL* ssl, SupportedCurve* clientGroup, word32 p_len; for (; serverGroup != NULL; serverGroup = serverGroup->next) { - if (!WOLFSSL_NAMED_GROUP_IS_FFHDE(serverGroup->name)) + if (!WOLFSSL_NAMED_GROUP_IS_FFDHE(serverGroup->name)) continue; for (group = clientGroup; group != NULL; group = group->next) { @@ -4990,7 +5102,7 @@ int TLSX_SupportedFFDHE_Set(WOLFSSL* ssl) return 0; clientGroup = (SupportedCurve*)extension->data; for (group = clientGroup; group != NULL; group = group->next) { - if (WOLFSSL_NAMED_GROUP_IS_FFHDE(group->name)) { + if (WOLFSSL_NAMED_GROUP_IS_FFDHE(group->name)) { found = 1; break; } @@ -7675,6 +7787,7 @@ static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse) if (ret == 0) { /* setting "key" means okay to call wc_curve25519_free */ key = (curve25519_key*)kse->key; + kse->keyLen = CURVE25519_KEYSIZE; #ifdef WOLFSSL_STATIC_EPHEMERAL ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_CURVE25519, kse->key); @@ -7760,6 +7873,7 @@ static int TLSX_KeyShare_GenX448Key(WOLFSSL *ssl, KeyShareEntry* kse) ret = wc_curve448_init((curve448_key*)kse->key); if (ret == 0) { key = (curve448_key*)kse->key; + kse->keyLen = CURVE448_KEY_SIZE; #ifdef WOLFSSL_STATIC_EPHEMERAL ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_CURVE448, kse->key); @@ -7899,7 +8013,7 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) #ifdef WOLFSSL_STATIC_EPHEMERAL ret = wolfSSL_StaticEphemeralKeyLoad(ssl, WC_PK_TYPE_ECDH, kse->key); - if (ret != 0) + if (ret != 0 || eccKey->dp->id != curveId) #endif { /* set curve info for EccMakeKey "peer" info */ @@ -7977,8 +8091,24 @@ static int TLSX_KeyShare_GenEccKey(WOLFSSL *ssl, KeyShareEntry* kse) return ret; } -#ifdef WOLFSSL_HAVE_KYBER -static int kyber_id2type(int id, int *type) +#ifdef WOLFSSL_HAVE_MLKEM +#if defined(WOLFSSL_MLKEM_CACHE_A) && \ + !defined(WOLFSSL_TLSX_PQC_MLKEM_STORE_PRIV_KEY) + /* Store KyberKey object rather than private key bytes in key share entry. + * Improves performance at cost of more dynamic memory being used. */ + #define WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ +#endif +#if defined(WOLFSSL_TLSX_PQC_MLKEM_STORE_PRIV_KEY) && \ + defined(WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ) + #error "Choose WOLFSSL_TLSX_PQC_MLKEM_STORE_PRIV_KEY or " + "WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ" +#endif + +#if !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) || \ + !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) || \ + (!defined(WOLFSSL_MLKEM_NO_DECAPSULATE) && \ + !defined(WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ)) +static int mlkem_id2type(int id, int *type) { int ret = 0; @@ -8000,7 +8130,7 @@ static int kyber_id2type(int id, int *type) break; #endif #endif -#ifdef WOLFSSL_KYBER_ORIGINAL +#ifdef WOLFSSL_MLKEM_KYBER #ifdef WOLFSSL_KYBER512 case WOLFSSL_KYBER_LEVEL1: *type = KYBER512; @@ -8024,82 +8154,92 @@ static int kyber_id2type(int id, int *type) return ret; } +#endif +/* Structures and objects needed for hybrid key exchanges using both classic + * ECDHE and PQC KEM key material. */ typedef struct PqcHybridMapping { int hybrid; int ecc; int pqc; + int pqc_first; } PqcHybridMapping; static const PqcHybridMapping pqc_hybrid_mapping[] = { #ifndef WOLFSSL_NO_ML_KEM - {.hybrid = WOLFSSL_P256_ML_KEM_512, .ecc = WOLFSSL_ECC_SECP256R1, - .pqc = WOLFSSL_ML_KEM_512}, - {.hybrid = WOLFSSL_P384_ML_KEM_768, .ecc = WOLFSSL_ECC_SECP384R1, - .pqc = WOLFSSL_ML_KEM_768}, - {.hybrid = WOLFSSL_P521_ML_KEM_1024, .ecc = WOLFSSL_ECC_SECP521R1, - .pqc = WOLFSSL_ML_KEM_1024}, -#endif -#ifdef WOLFSSL_KYBER_ORIGINAL - {.hybrid = WOLFSSL_P256_KYBER_LEVEL1, .ecc = WOLFSSL_ECC_SECP256R1, - .pqc = WOLFSSL_KYBER_LEVEL1}, - {.hybrid = WOLFSSL_P384_KYBER_LEVEL3, .ecc = WOLFSSL_ECC_SECP384R1, - .pqc = WOLFSSL_KYBER_LEVEL3}, - {.hybrid = WOLFSSL_P521_KYBER_LEVEL5, .ecc = WOLFSSL_ECC_SECP521R1, - .pqc = WOLFSSL_KYBER_LEVEL5}, -#endif - {.hybrid = 0, .ecc = 0, .pqc = 0} + {WOLFSSL_P256_ML_KEM_512, WOLFSSL_ECC_SECP256R1, WOLFSSL_ML_KEM_512, 0}, + {WOLFSSL_P384_ML_KEM_768, WOLFSSL_ECC_SECP384R1, WOLFSSL_ML_KEM_768, 0}, + {WOLFSSL_P256_ML_KEM_768, WOLFSSL_ECC_SECP256R1, WOLFSSL_ML_KEM_768, 0}, + {WOLFSSL_P521_ML_KEM_1024, WOLFSSL_ECC_SECP521R1, WOLFSSL_ML_KEM_1024, 0}, + {WOLFSSL_P384_ML_KEM_1024, WOLFSSL_ECC_SECP384R1, WOLFSSL_ML_KEM_1024, 0}, +#ifdef HAVE_CURVE25519 + {WOLFSSL_X25519_ML_KEM_512, WOLFSSL_ECC_X25519, WOLFSSL_ML_KEM_512, 1}, + {WOLFSSL_X25519_ML_KEM_768, WOLFSSL_ECC_X25519, WOLFSSL_ML_KEM_768, 1}, +#endif +#ifdef HAVE_CURVE448 + {WOLFSSL_X448_ML_KEM_768, WOLFSSL_ECC_X448, WOLFSSL_ML_KEM_768, 1}, +#endif +#endif /* WOLFSSL_NO_ML_KEM */ +#ifdef WOLFSSL_MLKEM_KYBER + {WOLFSSL_P256_KYBER_LEVEL1, WOLFSSL_ECC_SECP256R1, WOLFSSL_KYBER_LEVEL1, 0}, + {WOLFSSL_P384_KYBER_LEVEL3, WOLFSSL_ECC_SECP384R1, WOLFSSL_KYBER_LEVEL3, 0}, + {WOLFSSL_P256_KYBER_LEVEL3, WOLFSSL_ECC_SECP256R1, WOLFSSL_KYBER_LEVEL3, 0}, + {WOLFSSL_P521_KYBER_LEVEL5, WOLFSSL_ECC_SECP521R1, WOLFSSL_KYBER_LEVEL5, 0}, +#ifdef HAVE_CURVE25519 + {WOLFSSL_X25519_KYBER_LEVEL1, WOLFSSL_ECC_X25519, WOLFSSL_KYBER_LEVEL1, 0}, + {WOLFSSL_X25519_KYBER_LEVEL3, WOLFSSL_ECC_X25519, WOLFSSL_KYBER_LEVEL3, 0}, +#endif +#ifdef HAVE_CURVE448 + {WOLFSSL_X448_KYBER_LEVEL3, WOLFSSL_ECC_X448, WOLFSSL_KYBER_LEVEL3, 0}, +#endif +#endif /* WOLFSSL_MLKEM_KYBER */ + {0, 0, 0, 0} }; -/* This will map an ecc-pqs hybrid group into its ecc group and pqc kem group. - * If it cannot find a mapping then *pqc is set to group. ecc is optional. */ -static void findEccPqc(int *ecc, int *pqc, int group) +/* Map an ecc-pqc hybrid group into its ecc group and pqc kem group. */ +static void findEccPqc(int *ecc, int *pqc, int *pqc_first, int group) { int i; - if (pqc == NULL) { - return; - } - *pqc = 0; - if (ecc != NULL) { + if (pqc != NULL) + *pqc = 0; + if (ecc != NULL) *ecc = 0; - } + if (pqc_first != NULL) + *pqc_first = 0; for (i = 0; pqc_hybrid_mapping[i].hybrid != 0; i++) { if (pqc_hybrid_mapping[i].hybrid == group) { - *pqc = pqc_hybrid_mapping[i].pqc; - if (ecc != NULL) { + if (pqc != NULL) + *pqc = pqc_hybrid_mapping[i].pqc; + if (ecc != NULL) *ecc = pqc_hybrid_mapping[i].ecc; - } + if (pqc_first != NULL) + *pqc_first = pqc_hybrid_mapping[i].pqc_first; break; } } - - if (*pqc == 0) { - /* It is not a hybrid, so maybe its simple. */ - *pqc = group; - } } -/* Create a key share entry using liboqs parameters group. +#ifndef WOLFSSL_MLKEM_NO_MAKE_KEY +/* Create a key share entry using pqc parameters group on the client side. * Generates a key pair. * * ssl The SSL/TLS object. * kse The key share entry object. * returns 0 on success, otherwise failure. */ -static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse) +static int TLSX_KeyShare_GenPqcKeyClient(WOLFSSL *ssl, KeyShareEntry* kse) { int ret = 0; int type = 0; +#ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ KyberKey kem[1]; - byte* pubKey = NULL; byte* privKey = NULL; - KeyShareEntry *ecc_kse = NULL; - int oqs_group = 0; - int ecc_group = 0; word32 privSz = 0; - word32 pubSz = 0; +#else + KyberKey* kem = NULL; +#endif /* This gets called twice. Once during parsing of the key share and once * during the population of the extension. No need to do work the second @@ -8108,13 +8248,14 @@ static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse) return ret; } - findEccPqc(&ecc_group, &oqs_group, kse->group); - ret = kyber_id2type(oqs_group, &type); + /* Get the type of key we need from the key share group. */ + ret = mlkem_id2type(kse->group, &type); if (ret == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) { WOLFSSL_MSG("Invalid Kyber algorithm specified."); ret = BAD_FUNC_ARG; } +#ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ if (ret == 0) { ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId); if (ret != 0) { @@ -8123,75 +8264,222 @@ static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse) } if (ret == 0) { - ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap, - DYNAMIC_TYPE_TLSX); - if (ecc_kse == NULL) { - WOLFSSL_MSG("ecc_kse memory allocation failure"); + ret = wc_KyberKey_PrivateKeySize(kem, &privSz); + } + if (ret == 0) { + ret = wc_KyberKey_PublicKeySize(kem, &kse->pubKeyLen); + } + + if (ret == 0) { + privKey = (byte*)XMALLOC(privSz, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); + if (privKey == NULL) { + WOLFSSL_MSG("privkey memory allocation failure"); + ret = MEMORY_ERROR; + } + } +#else + if (ret == 0) { + /* Allocate a Kyber key to hold private key. */ + kem = (KyberKey*)XMALLOC(sizeof(KyberKey), ssl->heap, + DYNAMIC_TYPE_PRIVATE_KEY); + if (kem == NULL) { + WOLFSSL_MSG("KEM memory allocation failure"); ret = MEMORY_ERROR; } } + if (ret == 0) { + ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId); + if (ret != 0) { + WOLFSSL_MSG("Failed to initialize Kyber Key."); + } + } + if (ret == 0) { + ret = wc_KyberKey_PublicKeySize(kem, &kse->pubKeyLen); + } +#endif if (ret == 0) { - XMEMSET(ecc_kse, 0, sizeof(*ecc_kse)); + kse->pubKey = (byte*)XMALLOC(kse->pubKeyLen, ssl->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (kse->pubKey == NULL) { + WOLFSSL_MSG("pubkey memory allocation failure"); + ret = MEMORY_ERROR; + } + } - ret = wc_KyberKey_PrivateKeySize(kem, &privSz); + if (ret == 0) { + ret = wc_KyberKey_MakeKey(kem, ssl->rng); + if (ret != 0) { + WOLFSSL_MSG("Kyber keygen failure"); + } } if (ret == 0) { - ret = wc_KyberKey_PublicKeySize(kem, &pubSz); + ret = wc_KyberKey_EncodePublicKey(kem, kse->pubKey, + kse->pubKeyLen); } - if (ret == 0 && ecc_group != 0) { - ecc_kse->group = ecc_group; - ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse); - /* If fail, no error message, TLSX_KeyShare_GenEccKey will do it. */ +#ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ + if (ret == 0) { + ret = wc_KyberKey_EncodePrivateKey(kem, privKey, privSz); + } +#endif + +#ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("Public Kyber Key"); + WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen ); +#endif + + if (ret != 0) { + /* Data owned by key share entry otherwise. */ + wc_KyberKey_Free(kem); + XFREE(kse->pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + kse->pubKey = NULL; + #ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ + XFREE(privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); + #else + XFREE(kem, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); + kse->key = NULL; + #endif + } + else { + #ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ + wc_KyberKey_Free(kem); + kse->privKey = (byte*)privKey; + kse->privKeyLen = privSz; + #else + kse->key = kem; + #endif + } + + return ret; +} + +/* Create a key share entry using both ecdhe and pqc parameters groups. + * Generates two key pairs on the client side. + * + * ssl The SSL/TLS object. + * kse The key share entry object. + * returns 0 on success, otherwise failure. + */ +static int TLSX_KeyShare_GenPqcHybridKeyClient(WOLFSSL *ssl, KeyShareEntry* kse) +{ + int ret = 0; + KeyShareEntry *ecc_kse = NULL; + KeyShareEntry *pqc_kse = NULL; + int pqc_group = 0; + int ecc_group = 0; + int pqc_first = 0; + + /* This gets called twice. Once during parsing of the key share and once + * during the population of the extension. No need to do work the second + * time. Just return success if its already been done. */ + if (kse->pubKey != NULL) { + return ret; + } + + /* Determine the ECC and PQC group of the hybrid combination */ + findEccPqc(&ecc_group, &pqc_group, &pqc_first, kse->group); + if (ecc_group == 0 || pqc_group == 0) { + WOLFSSL_MSG("Invalid hybrid group"); + ret = BAD_FUNC_ARG; } if (ret == 0) { - pubKey = (byte*)XMALLOC(ecc_kse->pubKeyLen + pubSz, ssl->heap, - DYNAMIC_TYPE_PUBLIC_KEY); - if (pubKey == NULL) { - WOLFSSL_MSG("pubkey memory allocation failure"); + ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap, + DYNAMIC_TYPE_TLSX); + if (ecc_kse == NULL) { + WOLFSSL_MSG("kse memory allocation failure"); ret = MEMORY_ERROR; } + else { + XMEMSET(ecc_kse, 0, sizeof(*ecc_kse)); + } } - if (ret == 0) { - privKey = (byte*)XMALLOC(privSz, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); - if (privKey == NULL) { - WOLFSSL_MSG("privkey memory allocation failure"); + pqc_kse = (KeyShareEntry*)XMALLOC(sizeof(*pqc_kse), ssl->heap, + DYNAMIC_TYPE_TLSX); + if (pqc_kse == NULL) { + WOLFSSL_MSG("kse memory allocation failure"); ret = MEMORY_ERROR; } + else { + XMEMSET(pqc_kse, 0, sizeof(*pqc_kse)); + } } + /* Generate ECC key share part */ if (ret == 0) { - ret = wc_KyberKey_MakeKey(kem, ssl->rng); - if (ret != 0) { - WOLFSSL_MSG("Kyber keygen failure"); + ecc_kse->group = ecc_group; + #ifdef HAVE_CURVE25519 + if (ecc_group == WOLFSSL_ECC_X25519) { + ret = TLSX_KeyShare_GenX25519Key(ssl, ecc_kse); + } + else + #endif + #ifdef HAVE_CURVE448 + if (ecc_group == WOLFSSL_ECC_X448) { + ret = TLSX_KeyShare_GenX448Key(ssl, ecc_kse); + } + else + #endif + { + ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse); } + /* No error message, TLSX_KeyShare_Gen*Key will do it. */ } + + /* Generate PQC key share part */ if (ret == 0) { - ret = wc_KyberKey_EncodePublicKey(kem, pubKey + ecc_kse->pubKeyLen, - pubSz); + pqc_kse->group = pqc_group; + ret = TLSX_KeyShare_GenPqcKeyClient(ssl, pqc_kse); + /* No error message, TLSX_KeyShare_GenPqcKeyClient will do it. */ } + + /* Allocate memory for combined public key */ if (ret == 0) { - ret = wc_KyberKey_EncodePrivateKey(kem, privKey, privSz); + kse->pubKey = (byte*)XMALLOC(ecc_kse->pubKeyLen + pqc_kse->pubKeyLen, + ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + if (kse->pubKey == NULL) { + WOLFSSL_MSG("pubkey memory allocation failure"); + ret = MEMORY_ERROR; + } } + + /* Create combined public key. The order of classic/pqc key material is + * indicated by the pqc_first variable. */ if (ret == 0) { - if (ecc_kse->pubKeyLen > 0) - XMEMCPY(pubKey, ecc_kse->pubKey, ecc_kse->pubKeyLen); - kse->pubKey = pubKey; - kse->pubKeyLen = ecc_kse->pubKeyLen + pubSz; - pubKey = NULL; - - /* Note we are saving the OQS private key and ECC private key - * separately. That's because the ECC private key is not simply a - * buffer. Its is an ecc_key struct. Typically do not need the private - * key size, but will need to zero it out upon freeing. */ - kse->privKey = privKey; - privKey = NULL; - kse->privKeyLen = privSz; + if (pqc_first) { + XMEMCPY(kse->pubKey, pqc_kse->pubKey, pqc_kse->pubKeyLen); + XMEMCPY(kse->pubKey + pqc_kse->pubKeyLen, ecc_kse->pubKey, + ecc_kse->pubKeyLen); + } + else { + XMEMCPY(kse->pubKey, ecc_kse->pubKey, ecc_kse->pubKeyLen); + XMEMCPY(kse->pubKey + ecc_kse->pubKeyLen, pqc_kse->pubKey, + pqc_kse->pubKeyLen); + } + kse->pubKeyLen = ecc_kse->pubKeyLen + pqc_kse->pubKeyLen; + } + /* Store the private keys. + * Note we are saving the PQC private key and ECC private key + * separately. That's because the ECC private key is not simply a + * buffer. Its is an ecc_key struct. */ + if (ret == 0) { + #ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ + /* PQC private key is an encoded byte array */ + kse->privKey = pqc_kse->privKey; + kse->privKeyLen = pqc_kse->privKeyLen; + pqc_kse->privKey = NULL; + #else + /* PQC private key is a pointer to KyberKey object */ + kse->privKey = (byte*)pqc_kse->key; + kse->privKeyLen = 0; + pqc_kse->key = NULL; + #endif + /* ECC private key is a pointer to ecc_key object */ kse->key = ecc_kse->key; + kse->keyLen = ecc_kse->keyLen; ecc_kse->key = NULL; } @@ -8200,14 +8488,13 @@ static int TLSX_KeyShare_GenPqcKey(WOLFSSL *ssl, KeyShareEntry* kse) WOLFSSL_BUFFER(kse->pubKey, kse->pubKeyLen ); #endif - wc_KyberKey_Free(kem); TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap); - XFREE(pubKey, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); - XFREE(privKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); + TLSX_KeyShare_FreeAll(pqc_kse, ssl->heap); return ret; } -#endif /* WOLFSSL_HAVE_KYBER */ +#endif /* !WOLFSSL_MLKEM_NO_MAKE_KEY */ +#endif /* WOLFSSL_HAVE_MLKEM */ /* Generate a secret/key using the key share entry. * @@ -8218,15 +8505,17 @@ int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse) { int ret; /* Named FFDHE groups have a bit set to identify them. */ - if (WOLFSSL_NAMED_GROUP_IS_FFHDE(kse->group)) + if (WOLFSSL_NAMED_GROUP_IS_FFDHE(kse->group)) ret = TLSX_KeyShare_GenDhKey(ssl, kse); else if (kse->group == WOLFSSL_ECC_X25519) ret = TLSX_KeyShare_GenX25519Key(ssl, kse); else if (kse->group == WOLFSSL_ECC_X448) ret = TLSX_KeyShare_GenX448Key(ssl, kse); -#ifdef WOLFSSL_HAVE_KYBER +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_MAKE_KEY) else if (WOLFSSL_NAMED_GROUP_IS_PQC(kse->group)) - ret = TLSX_KeyShare_GenPqcKey(ssl, kse); + ret = TLSX_KeyShare_GenPqcKeyClient(ssl, kse); + else if (WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(kse->group)) + ret = TLSX_KeyShare_GenPqcHybridKeyClient(ssl, kse); #endif else ret = TLSX_KeyShare_GenEccKey(ssl, kse); @@ -8247,7 +8536,7 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap) while ((current = list) != NULL) { list = current->next; - if (WOLFSSL_NAMED_GROUP_IS_FFHDE(current->group)) { + if (WOLFSSL_NAMED_GROUP_IS_FFDHE(current->group)) { #ifndef NO_DH wc_FreeDhKey((DhKey*)current->key); #endif @@ -8262,17 +8551,43 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap) wc_curve448_free((curve448_key*)current->key); #endif } -#ifdef WOLFSSL_HAVE_KYBER +#ifdef WOLFSSL_HAVE_MLKEM else if (WOLFSSL_NAMED_GROUP_IS_PQC(current->group)) { - if (current->key != NULL) { - ForceZero((byte*)current->key, current->keyLen); + wc_KyberKey_Free((KyberKey*)current->key); + #ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ + if (current->privKey != NULL) { + ForceZero(current->privKey, current->privKeyLen); } - XFREE(current->pubKey, heap, DYNAMIC_TYPE_PUBLIC_KEY); - current->pubKey = NULL; + #endif + } + else if (WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(current->group)) { + int ecc_group = 0; + findEccPqc(&ecc_group, NULL, NULL, current->group); + + /* Free PQC private key */ + #ifdef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ + wc_KyberKey_Free((KyberKey*)current->privKey); + #else if (current->privKey != NULL) { ForceZero(current->privKey, current->privKeyLen); - XFREE(current->privKey, heap, DYNAMIC_TYPE_PRIVATE_KEY); - current->privKey = NULL; + } + #endif + + /* Free ECC private key */ + if (ecc_group == WOLFSSL_ECC_X25519) { + #ifdef HAVE_CURVE25519 + wc_curve25519_free((curve25519_key*)current->key); + #endif + } + else if (ecc_group == WOLFSSL_ECC_X448) { + #ifdef HAVE_CURVE448 + wc_curve448_free((curve448_key*)current->key); + #endif + } + else { + #ifdef HAVE_ECC + wc_ecc_free((ecc_key*)current->key); + #endif } } #endif @@ -8282,7 +8597,7 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap) #endif } XFREE(current->key, heap, DYNAMIC_TYPE_PRIVATE_KEY); - #if !defined(NO_DH) && (!defined(NO_CERTS) || !defined(NO_PSK)) + #if !defined(NO_DH) || defined(WOLFSSL_HAVE_MLKEM) XFREE(current->privKey, heap, DYNAMIC_TYPE_PRIVATE_KEY); #endif XFREE(current->pubKey, heap, DYNAMIC_TYPE_PUBLIC_KEY); @@ -8508,10 +8823,15 @@ static int TLSX_KeyShare_ProcessDh(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) * * ssl The SSL/TLS object. * keyShareEntry The key share entry object to use to calculate shared secret. + * ssOutput The destination buffer for the shared secret. + * ssOutSz The size of the generated shared secret. + * * returns 0 on success and other values indicate failure. */ -static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl, - KeyShareEntry* keyShareEntry) +static int TLSX_KeyShare_ProcessX25519_ex(WOLFSSL* ssl, + KeyShareEntry* keyShareEntry, + unsigned char* ssOutput, + word32* ssOutSz) { int ret; @@ -8560,11 +8880,13 @@ static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl, if (ret == 0) { ssl->ecdhCurveOID = ECC_X25519_OID; - + #ifdef WOLFSSL_CURVE25519_BLINDING + ret = wc_curve25519_set_rng(key, ssl->rng); + } + if (ret == 0) { + #endif ret = wc_curve25519_shared_secret_ex(key, peerX25519Key, - ssl->arrays->preMasterSecret, - &ssl->arrays->preMasterSz, - EC25519_LITTLE_ENDIAN); + ssOutput, ssOutSz, EC25519_LITTLE_ENDIAN); } wc_curve25519_free(peerX25519Key); @@ -8572,9 +8894,13 @@ static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl, wc_curve25519_free((curve25519_key*)keyShareEntry->key); XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); keyShareEntry->key = NULL; + XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + keyShareEntry->ke = NULL; #else (void)ssl; (void)keyShareEntry; + (void)ssOutput; + (void)ssOutSz; ret = PEER_KEY_ERROR; WOLFSSL_ERROR_VERBOSE(ret); @@ -8583,13 +8909,33 @@ static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl, return ret; } +/* Process the X25519 key share extension on the client side. + * + * ssl The SSL/TLS object. + * keyShareEntry The key share entry object to use to calculate shared secret. + * + * returns 0 on success and other values indicate failure. + */ +static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl, + KeyShareEntry* keyShareEntry) +{ + return TLSX_KeyShare_ProcessX25519_ex(ssl, keyShareEntry, + ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz); +} + /* Process the X448 key share extension on the client side. * * ssl The SSL/TLS object. * keyShareEntry The key share entry object to use to calculate shared secret. + * ssOutput The destination buffer for the shared secret. + * ssOutSz The size of the generated shared secret. + * * returns 0 on success and other values indicate failure. */ -static int TLSX_KeyShare_ProcessX448(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) +static int TLSX_KeyShare_ProcessX448_ex(WOLFSSL* ssl, + KeyShareEntry* keyShareEntry, + unsigned char* ssOutput, + word32* ssOutSz) { int ret; @@ -8640,9 +8986,7 @@ static int TLSX_KeyShare_ProcessX448(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) ssl->ecdhCurveOID = ECC_X448_OID; ret = wc_curve448_shared_secret_ex(key, peerX448Key, - ssl->arrays->preMasterSecret, - &ssl->arrays->preMasterSz, - EC448_LITTLE_ENDIAN); + ssOutput, ssOutSz, EC448_LITTLE_ENDIAN); } wc_curve448_free(peerX448Key); @@ -8650,9 +8994,13 @@ static int TLSX_KeyShare_ProcessX448(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) wc_curve448_free((curve448_key*)keyShareEntry->key); XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); keyShareEntry->key = NULL; + XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + keyShareEntry->ke = NULL; #else (void)ssl; (void)keyShareEntry; + (void)ssOutput; + (void)ssOutSz; ret = PEER_KEY_ERROR; WOLFSSL_ERROR_VERBOSE(ret); @@ -8661,13 +9009,31 @@ static int TLSX_KeyShare_ProcessX448(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) return ret; } +/* Process the X448 key share extension on the client side. + * + * ssl The SSL/TLS object. + * keyShareEntry The key share entry object to use to calculate shared secret. + * returns 0 on success and other values indicate failure. + */ +static int TLSX_KeyShare_ProcessX448(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) +{ + return TLSX_KeyShare_ProcessX448_ex(ssl, keyShareEntry, + ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz); +} + /* Process the ECC key share extension on the client side. * * ssl The SSL/TLS object. * keyShareEntry The key share entry object to use to calculate shared secret. + * ssOutput The destination buffer for the shared secret. + * ssOutSz The size of the generated shared secret. + * * returns 0 on success and other values indicate failure. */ -static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) +static int TLSX_KeyShare_ProcessEcc_ex(WOLFSSL* ssl, + KeyShareEntry* keyShareEntry, + unsigned char* ssOutput, + word32* ssOutSz) { int ret = 0; #ifdef HAVE_ECC @@ -8767,9 +9133,7 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) if (ret == 0) { ret = EccSharedSecret(ssl, eccKey, ssl->peerEccKey, keyShareEntry->ke, &keyShareEntry->keLen, - ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz, - ssl->options.side - ); + ssOutput, ssOutSz, ssl->options.side); #ifdef WOLFSSL_ASYNC_CRYPT if (ret == WC_NO_ERR_TRACE(WC_PENDING_E)) return ret; @@ -8797,6 +9161,8 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) #else (void)ssl; (void)keyShareEntry; + (void)ssOutput; + (void)ssOutSz; ret = PEER_KEY_ERROR; WOLFSSL_ERROR_VERBOSE(ret); @@ -8805,174 +9171,364 @@ static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) return ret; } -#ifdef WOLFSSL_HAVE_KYBER -/* Process the Kyber key share extension on the client side. +/* Process the ECC key share extension on the client side. * * ssl The SSL/TLS object. * keyShareEntry The key share entry object to use to calculate shared secret. * returns 0 on success and other values indicate failure. */ -static int TLSX_KeyShare_ProcessPqc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) +static int TLSX_KeyShare_ProcessEcc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) { - int ret = 0; - int type; - KyberKey kem[1]; - byte* sharedSecret = NULL; - word32 sharedSecretLen = 0; - int oqs_group = 0; - int ecc_group = 0; - ecc_key eccpubkey; - word32 outlen = 0; - word32 privSz = 0; - word32 ctSz = 0; - word32 ssSz = 0; + return TLSX_KeyShare_ProcessEcc_ex(ssl, keyShareEntry, + ssl->arrays->preMasterSecret, &ssl->arrays->preMasterSz); +} - if (keyShareEntry->ke == NULL) { - WOLFSSL_MSG("Invalid OQS algorithm specified."); - return BAD_FUNC_ARG; - } +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) +/* Process the Kyber key share extension on the client side. + * + * ssl The SSL/TLS object. + * keyShareEntry The key share entry object to use to calculate shared secret. + * ssOutput The destination buffer for the shared secret. + * ssOutSz The size of the generated shared secret. + * + * returns 0 on success and other values indicate failure. + */ +static int TLSX_KeyShare_ProcessPqcClient_ex(WOLFSSL* ssl, + KeyShareEntry* keyShareEntry, + unsigned char* ssOutput, + word32* ssOutSz) +{ + int ret = 0; + KyberKey* kem = (KyberKey*)keyShareEntry->key; +#ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ + word32 privSz = 0; +#endif + word32 ctSz = 0; + word32 ssSz = 0; if (ssl->options.side == WOLFSSL_SERVER_END) { /* I am the server, the shared secret has already been generated and - * is in keyShareEntry->ke; copy it to the pre-master secret - * pre-allocated buffer. */ - if (keyShareEntry->keLen > ENCRYPT_LEN) { - WOLFSSL_MSG("shared secret is too long."); - return LENGTH_ERROR; - } - - XMEMCPY(ssl->arrays->preMasterSecret, keyShareEntry->ke, - keyShareEntry->keLen); - ssl->arrays->preMasterSz = keyShareEntry->keLen; - XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_SECRET); - keyShareEntry->ke = NULL; - keyShareEntry->keLen = 0; + * is in ssl->arrays->preMasterSecret, so nothing really to do here. */ return 0; } - /* I am the client, the ciphertext is in keyShareEntry->ke */ - findEccPqc(&ecc_group, &oqs_group, keyShareEntry->group); - - ret = wc_ecc_init_ex(&eccpubkey, ssl->heap, ssl->devId); - if (ret != 0) { - WOLFSSL_MSG("Memory allocation error."); - return MEMORY_E; - } - - ret = kyber_id2type(oqs_group, &type); - if (ret != 0) { - wc_ecc_free(&eccpubkey); - WOLFSSL_MSG("Invalid OQS algorithm specified."); + if (keyShareEntry->ke == NULL) { + WOLFSSL_MSG("Invalid PQC algorithm specified."); return BAD_FUNC_ARG; } + if (ssOutSz == NULL) + return BAD_FUNC_ARG; - ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId); - if (ret != 0) { - wc_ecc_free(&eccpubkey); - WOLFSSL_MSG("Error creating Kyber KEM"); - return MEMORY_E; - } +#ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ + if (kem == NULL) { + int type = 0; - if (ret == 0) { - ret = wc_KyberKey_SharedSecretSize(kem, &ssSz); - } - if (ret == 0) { - sharedSecretLen = ssSz; - switch (ecc_group) { - case WOLFSSL_ECC_SECP256R1: - sharedSecretLen += 32; - outlen = 32; - break; - case WOLFSSL_ECC_SECP384R1: - sharedSecretLen += 48; - outlen = 48; - break; - case WOLFSSL_ECC_SECP521R1: - sharedSecretLen += 66; - outlen = 66; - break; - default: - break; + /* Allocate a Kyber key to hold private key. */ + kem = (KyberKey*) XMALLOC(sizeof(KyberKey), ssl->heap, + DYNAMIC_TYPE_PRIVATE_KEY); + if (kem == NULL) { + WOLFSSL_MSG("GenPqcKey memory error"); + ret = MEMORY_E; + } + if (ret == 0) { + ret = mlkem_id2type(keyShareEntry->group, &type); + } + if (ret != 0) { + WOLFSSL_MSG("Invalid PQC algorithm specified."); + ret = BAD_FUNC_ARG; } + if (ret == 0) { + ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId); + if (ret != 0) { + WOLFSSL_MSG("Error creating Kyber KEM"); + } + } + } +#else + if (kem == NULL || keyShareEntry->privKeyLen != 0) { + WOLFSSL_MSG("Invalid Kyber key."); + ret = BAD_FUNC_ARG; } +#endif + if (ret == 0) { - sharedSecret = (byte*)XMALLOC(sharedSecretLen, ssl->heap, - DYNAMIC_TYPE_TLSX); - if (sharedSecret == NULL) { - WOLFSSL_MSG("Memory allocation error."); - ret = MEMORY_E; - } + ret = wc_KyberKey_SharedSecretSize(kem, &ssSz); } if (ret == 0) { ret = wc_KyberKey_CipherTextSize(kem, &ctSz); } + +#ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ if (ret == 0) { ret = wc_KyberKey_PrivateKeySize(kem, &privSz); } + if (ret == 0 && privSz != keyShareEntry->privKeyLen) { + WOLFSSL_MSG("Invalid private key size."); + ret = BAD_FUNC_ARG; + } if (ret == 0) { ret = wc_KyberKey_DecodePrivateKey(kem, keyShareEntry->privKey, privSz); } +#endif + if (ret == 0) { - ret = wc_KyberKey_Decapsulate(kem, sharedSecret + outlen, - keyShareEntry->ke + keyShareEntry->keLen - ctSz, ctSz); + ret = wc_KyberKey_Decapsulate(kem, ssOutput, + keyShareEntry->ke, ctSz); if (ret != 0) { WOLFSSL_MSG("wc_KyberKey decapsulation failure."); ret = BAD_FUNC_ARG; } } + if (ret == 0) { + *ssOutSz = ssSz; + } + + wc_KyberKey_Free(kem); + + XFREE(kem, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); + keyShareEntry->key = NULL; + + XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + keyShareEntry->ke = NULL; + + return ret; +} + +/* Process the Kyber key share extension on the client side. + * + * ssl The SSL/TLS object. + * keyShareEntry The key share entry object to use to calculate shared secret. + * + * returns 0 on success and other values indicate failure. + */ +static int TLSX_KeyShare_ProcessPqcClient(WOLFSSL* ssl, + KeyShareEntry* keyShareEntry) +{ + return TLSX_KeyShare_ProcessPqcClient_ex(ssl, keyShareEntry, + ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz); +} + +/* Process the hybrid key share extension on the client side. + * + * ssl The SSL/TLS object. + * keyShareEntry The key share entry object to use to calculate shared secret. + * returns 0 on success and other values indicate failure. + */ +static int TLSX_KeyShare_ProcessPqcHybridClient(WOLFSSL* ssl, + KeyShareEntry* keyShareEntry) +{ + int ret = 0; + int pqc_group = 0; + int ecc_group = 0; + int pqc_first = 0; + KeyShareEntry* pqc_kse = NULL; + KeyShareEntry *ecc_kse = NULL; + word32 ctSz = 0; + word32 ssSzPqc = 0; + word32 ssSzEcc = 0; + + if (ssl->options.side == WOLFSSL_SERVER_END) { + /* I am the server, the shared secret has already been generated and + * is in ssl->arrays->preMasterSecret, so nothing really to do here. */ + return 0; + } + + if (keyShareEntry->ke == NULL) { + WOLFSSL_MSG("Invalid PQC algorithm specified."); + return BAD_FUNC_ARG; + } + + /* I am the client, both the PQC ciphertext and the ECHD public key are in + * keyShareEntry->ke */ + + /* Determine the ECC and PQC group of the hybrid combination */ + findEccPqc(&ecc_group, &pqc_group, &pqc_first, keyShareEntry->group); + if (ecc_group == 0 || pqc_group == 0) { + WOLFSSL_MSG("Invalid hybrid group"); + ret = BAD_FUNC_ARG; + } - if (ecc_group != 0) { + if (ret == 0) { + ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap, + DYNAMIC_TYPE_TLSX); + if (ecc_kse == NULL) { + WOLFSSL_MSG("kse memory allocation failure"); + ret = MEMORY_ERROR; + } + else { + XMEMSET(ecc_kse, 0, sizeof(*ecc_kse)); + } + } + if (ret == 0) { + pqc_kse = (KeyShareEntry*)XMALLOC(sizeof(*pqc_kse), ssl->heap, + DYNAMIC_TYPE_TLSX); + if (pqc_kse == NULL) { + WOLFSSL_MSG("kse memory allocation failure"); + ret = MEMORY_ERROR; + } + else { + XMEMSET(pqc_kse, 0, sizeof(*pqc_kse)); + } + } + + /* The ciphertext and shared secret sizes of a KEM are fixed. Hence, we + * decode these sizes to separate the KEM ciphertext from the ECDH public + * key. */ + if (ret == 0) { + #ifndef WOLFSSL_TLSX_PQC_MLKEM_STORE_OBJ + int type; + + pqc_kse->privKey = keyShareEntry->privKey; + + ret = mlkem_id2type(pqc_group, &type); + if (ret != 0) { + WOLFSSL_MSG("Invalid Kyber algorithm specified."); + ret = BAD_FUNC_ARG; + } if (ret == 0) { - /* Point is validated by import function. */ - ret = wc_ecc_import_x963(keyShareEntry->ke, - keyShareEntry->keLen - ctSz, - &eccpubkey); - if (ret != 0) { - WOLFSSL_MSG("ECC Public key import error."); + pqc_kse->key = XMALLOC(sizeof(KyberKey), ssl->heap, + DYNAMIC_TYPE_PRIVATE_KEY); + if (pqc_kse->key == NULL) { + WOLFSSL_MSG("GenPqcKey memory error"); + ret = MEMORY_E; } } - -#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \ - (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \ - !defined(HAVE_SELFTEST) if (ret == 0) { - ret = wc_ecc_set_rng((ecc_key *)keyShareEntry->key, ssl->rng); + ret = wc_KyberKey_Init(type, (KyberKey*)pqc_kse->key, + ssl->heap, ssl->devId); if (ret != 0) { - WOLFSSL_MSG("Failure to set the ECC private key RNG."); + WOLFSSL_MSG("Error creating Kyber KEM"); } } -#endif + #else + pqc_kse->key = keyShareEntry->privKey; + #endif + + pqc_kse->group = pqc_group; + pqc_kse->privKeyLen = keyShareEntry->privKeyLen; if (ret == 0) { - PRIVATE_KEY_UNLOCK(); - ret = wc_ecc_shared_secret((ecc_key *)keyShareEntry->key, - &eccpubkey, sharedSecret, &outlen); - PRIVATE_KEY_LOCK(); - if (outlen != sharedSecretLen - ssSz) { - WOLFSSL_MSG("ECC shared secret derivation error."); + ret = wc_KyberKey_SharedSecretSize((KyberKey*)pqc_kse->key, + &ssSzPqc); + } + if (ret == 0) { + ret = wc_KyberKey_CipherTextSize((KyberKey*)pqc_kse->key, + &ctSz); + if (ret == 0 && keyShareEntry->keLen <= ctSz) { + WOLFSSL_MSG("Invalid ciphertext size."); ret = BAD_FUNC_ARG; } } + if (ret == 0) { + pqc_kse->keLen = ctSz; + pqc_kse->ke = (byte*)XMALLOC(pqc_kse->keLen, ssl->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (pqc_kse->ke == NULL) { + WOLFSSL_MSG("pqc_kse memory allocation failure"); + ret = MEMORY_ERROR; + } + /* Copy the PQC KEM ciphertext. Depending on the pqc_first flag, + * the KEM ciphertext comes before or after the ECDH public key. */ + if (ret == 0) { + int offset = keyShareEntry->keLen - ctSz; + + if (pqc_first) + offset = 0; + + XMEMCPY(pqc_kse->ke, keyShareEntry->ke + offset, ctSz); + } + } } - if ((ret == 0) && (sharedSecretLen > ENCRYPT_LEN)) { - WOLFSSL_MSG("shared secret is too long."); - ret = LENGTH_ERROR; + + if (ret == 0) { + ecc_kse->group = ecc_group; + ecc_kse->keLen = keyShareEntry->keLen - ctSz; + ecc_kse->key = keyShareEntry->key; + ecc_kse->ke = (byte*)XMALLOC(ecc_kse->keLen, ssl->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (ecc_kse->ke == NULL) { + WOLFSSL_MSG("ecc_kse memory allocation failure"); + ret = MEMORY_ERROR; + } + /* Copy the ECDH public key. Depending on the pqc_first flag, the + * KEM ciphertext comes before or after the ECDH public key. */ + if (ret == 0) { + int offset = 0; + + if (pqc_first) + offset = ctSz; + + XMEMCPY(ecc_kse->ke, keyShareEntry->ke + offset, ecc_kse->keLen); + } + } + + /* Process ECDH key share part. The generated shared secret is directly + * stored in the ssl->arrays->preMasterSecret buffer. Depending on the + * pqc_first flag, the ECDH shared secret part goes before or after the + * KEM part. */ + if (ret == 0) { + int offset = 0; + + /* Set the ECC size variable to the initial buffer size */ + ssSzEcc = ssl->arrays->preMasterSz; + + if (pqc_first) + offset = ssSzPqc; + + #ifdef HAVE_CURVE25519 + if (ecc_group == WOLFSSL_ECC_X25519) { + ret = TLSX_KeyShare_ProcessX25519_ex(ssl, ecc_kse, + ssl->arrays->preMasterSecret + offset, &ssSzEcc); + } + else + #endif + #ifdef HAVE_CURVE448 + if (ecc_group == WOLFSSL_ECC_X448) { + ret = TLSX_KeyShare_ProcessX448_ex(ssl, ecc_kse, + ssl->arrays->preMasterSecret + offset, &ssSzEcc); + } + else + #endif + { + ret = TLSX_KeyShare_ProcessEcc_ex(ssl, ecc_kse, + ssl->arrays->preMasterSecret + offset, &ssSzEcc); + } + } + + if (ret == 0) { + keyShareEntry->key = ecc_kse->key; + + if ((ret == 0) && ((ssSzEcc + ssSzPqc) > ENCRYPT_LEN)) { + WOLFSSL_MSG("shared secret is too long."); + ret = LENGTH_ERROR; + } + } + + /* Process PQC KEM key share part. Depending on the pqc_first flag, the + * KEM shared secret part goes before or after the ECDH part. */ + if (ret == 0) { + int offset = ssSzEcc; + + if (pqc_first) + offset = 0; + + ret = TLSX_KeyShare_ProcessPqcClient_ex(ssl, pqc_kse, + ssl->arrays->preMasterSecret + offset, &ssSzPqc); } if (ret == 0) { - /* Copy the shared secret to the pre-master secret pre-allocated - * buffer. */ - XMEMCPY(ssl->arrays->preMasterSecret, sharedSecret, sharedSecretLen); - ssl->arrays->preMasterSz = (word32) sharedSecretLen; + keyShareEntry->privKey = (byte*)pqc_kse->key; + + ssl->arrays->preMasterSz = ssSzEcc + ssSzPqc; } - XFREE(sharedSecret, ssl->heap, DYNAMIC_TYPE_SECRET); + TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap); + TLSX_KeyShare_FreeAll(pqc_kse, ssl->heap); - wc_ecc_free(&eccpubkey); - wc_KyberKey_Free(kem); return ret; } -#endif /* WOLFSSL_HAVE_KYBER */ +#endif /* WOLFSSL_HAVE_MLKEM && !WOLFSSL_MLKEM_NO_DECAPSULATE */ /* Process the key share extension on the client side. * @@ -8992,15 +9548,17 @@ static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) ssl->arrays->preMasterSz = ENCRYPT_LEN; /* Use Key Share Data from server. */ - if (WOLFSSL_NAMED_GROUP_IS_FFHDE(keyShareEntry->group)) + if (WOLFSSL_NAMED_GROUP_IS_FFDHE(keyShareEntry->group)) ret = TLSX_KeyShare_ProcessDh(ssl, keyShareEntry); else if (keyShareEntry->group == WOLFSSL_ECC_X25519) ret = TLSX_KeyShare_ProcessX25519(ssl, keyShareEntry); else if (keyShareEntry->group == WOLFSSL_ECC_X448) ret = TLSX_KeyShare_ProcessX448(ssl, keyShareEntry); -#ifdef WOLFSSL_HAVE_KYBER +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) else if (WOLFSSL_NAMED_GROUP_IS_PQC(keyShareEntry->group)) - ret = TLSX_KeyShare_ProcessPqc(ssl, keyShareEntry); + ret = TLSX_KeyShare_ProcessPqcClient(ssl, keyShareEntry); + else if (WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(keyShareEntry->group)) + ret = TLSX_KeyShare_ProcessPqcHybridClient(ssl, keyShareEntry); #endif else ret = TLSX_KeyShare_ProcessEcc(ssl, keyShareEntry); @@ -9049,11 +9607,18 @@ static int TLSX_KeyShareEntry_Parse(const WOLFSSL* ssl, const byte* input, if (keLen > length - offset) return BUFFER_ERROR; -#ifdef WOLFSSL_HAVE_KYBER - if (WOLFSSL_NAMED_GROUP_IS_PQC(group) && +#ifdef WOLFSSL_HAVE_MLKEM + if ((WOLFSSL_NAMED_GROUP_IS_PQC(group) || + WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(group)) && ssl->options.side == WOLFSSL_SERVER_END) { - /* For KEMs, the public key is not stored. Casting away const because - * we know for KEMs, it will be read-only.*/ + /* When handling a key share containing a KEM public key on the server + * end, we have to perform the encapsulation immediately in order to + * send the resulting ciphertext back to the client in the ServerHello + * message. As the public key is not stored and we do not modify it, we + * don't have to create a copy of it. + * In case of a hybrid key exchange, the ECDH part is also performed + * immediately (to not split the generation of the master secret). + * Hence, we also don't have to store this public key either. */ ke = (byte *)&input[offset]; } else #endif @@ -9228,7 +9793,7 @@ int TLSX_KeyShare_Parse(WOLFSSL* ssl, const byte* input, word16 length, /* Not in list sent if there isn't a private key. */ if (keyShareEntry == NULL || (keyShareEntry->key == NULL - #if !defined(NO_DH) || defined(WOLFSSL_HAVE_KYBER) + #if !defined(NO_DH) || defined(WOLFSSL_HAVE_MLKEM) && keyShareEntry->privKey == NULL #endif )) { @@ -9253,13 +9818,15 @@ int TLSX_KeyShare_Parse(WOLFSSL* ssl, const byte* input, word16 length, if (ssl->error != WC_NO_ERR_TRACE(WC_PENDING_E)) #endif { - /* Check the selected group was supported by ClientHello extensions. */ + /* Check the selected group was supported by ClientHello extensions. + */ if (!TLSX_SupportedGroups_Find(ssl, group, ssl->extensions)) { WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA); return BAD_KEY_SHARE_DATA; } - /* Check if the group was sent. */ + /* Make sure KeyShare for server requested group was not sent in + * ClientHello. */ if (TLSX_KeyShare_Find(ssl, group)) { WOLFSSL_ERROR_VERBOSE(BAD_KEY_SHARE_DATA); return BAD_KEY_SHARE_DATA; @@ -9320,76 +9887,228 @@ static int TLSX_KeyShare_New(KeyShareEntry** list, int group, void *heap, return 0; } -#ifdef WOLFSSL_HAVE_KYBER -static int server_generate_pqc_ciphertext(WOLFSSL* ssl, - KeyShareEntry* keyShareEntry, byte* data, word16 len) -{ - /* I am the server. The data parameter is the client's public key. I need - * to generate the public information (AKA ciphertext) and shared secret - * here. Note the "public information" is equivalent to a the public key in - * key exchange parlance. That's why it is being assigned to pubKey. - */ - int type; - KyberKey kem[1]; - byte* sharedSecret = NULL; +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) +/* Process the Kyber key share extension on the server side. + * + * ssl The SSL/TLS object. + * keyShareEntry The key share entry object to be sent to the client. + * data The key share data received from the client. + * len The length of the key share data from the client. + * ssOutput The destination buffer for the shared secret. + * ssOutSz The size of the generated shared secret. + * + * returns 0 on success and other values indicate failure. + */ +static int TLSX_KeyShare_HandlePqcKeyServer(WOLFSSL* ssl, + KeyShareEntry* keyShareEntry, byte* clientData, word16 clientLen, + unsigned char* ssOutput, word32* ssOutSz) +{ + /* We are on the server side. The key share contains a PQC KEM public key + * that we are using for an encapsulate operation. The resulting ciphertext + * is stored in the server key share. */ + KyberKey* kemKey = (KyberKey*)keyShareEntry->key; byte* ciphertext = NULL; int ret = 0; - int oqs_group = 0; - int ecc_group = 0; - KeyShareEntry *ecc_kse = NULL; - ecc_key eccpubkey; - word32 outlen = 0; word32 pubSz = 0; word32 ctSz = 0; word32 ssSz = 0; - findEccPqc(&ecc_group, &oqs_group, keyShareEntry->group); - ret = kyber_id2type(oqs_group, &type); - if (ret != 0) { - WOLFSSL_MSG("Invalid Kyber algorithm specified."); + if (clientData == NULL) { + WOLFSSL_MSG("No KEM public key from the client."); return BAD_FUNC_ARG; } - ret = wc_ecc_init_ex(&eccpubkey, ssl->heap, ssl->devId); - if (ret != 0) { - WOLFSSL_MSG("Could not do ECC public key initialization."); - return MEMORY_E; + if (kemKey == NULL) { + int type = 0; + + /* Allocate a Kyber key to hold private key. */ + kemKey = (KyberKey*) XMALLOC(sizeof(KyberKey), ssl->heap, + DYNAMIC_TYPE_PRIVATE_KEY); + if (kemKey == NULL) { + WOLFSSL_MSG("GenPqcKey memory error"); + ret = MEMORY_E; + } + if (ret == 0) { + ret = mlkem_id2type(keyShareEntry->group, &type); + } + if (ret != 0) { + WOLFSSL_MSG("Invalid PQC algorithm specified."); + ret = BAD_FUNC_ARG; + } + if (ret == 0) { + ret = wc_KyberKey_Init(type, kemKey, ssl->heap, ssl->devId); + if (ret != 0) { + WOLFSSL_MSG("Error creating Kyber KEM"); + } + } } - ret = wc_KyberKey_Init(type, kem, ssl->heap, ssl->devId); - if (ret != 0) { - wc_ecc_free(&eccpubkey); - WOLFSSL_MSG("Error creating Kyber KEM"); - return MEMORY_E; + if (ret == 0) { + ret = wc_KyberKey_PublicKeySize(kemKey, &pubSz); + } + if (ret == 0) { + ret = wc_KyberKey_CipherTextSize(kemKey, &ctSz); + } + if (ret == 0) { + ret = wc_KyberKey_SharedSecretSize(kemKey, &ssSz); + } + + if (ret == 0 && clientLen != pubSz) { + WOLFSSL_MSG("Invalid public key."); + ret = BAD_FUNC_ARG; } if (ret == 0) { - ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap, - DYNAMIC_TYPE_TLSX); - if (ecc_kse == NULL) { - WOLFSSL_MSG("ecc_kse memory allocation failure"); - ret = MEMORY_ERROR; + ciphertext = (byte*)XMALLOC(ctSz, ssl->heap, DYNAMIC_TYPE_TLSX); + + if (ciphertext == NULL) { + WOLFSSL_MSG("Ciphertext memory allocation failure."); + ret = MEMORY_E; } } if (ret == 0) { - XMEMSET(ecc_kse, 0, sizeof(*ecc_kse)); + ret = wc_KyberKey_DecodePublicKey(kemKey, clientData, pubSz); } - - if (ret == 0 && ecc_group != 0) { - ecc_kse->group = ecc_group; - ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse); - /* No message, TLSX_KeyShare_GenEccKey() will do it. */ + if (ret == 0) { + ret = wc_KyberKey_Encapsulate(kemKey, ciphertext, + ssOutput, ssl->rng); + if (ret != 0) { + WOLFSSL_MSG("wc_KyberKey encapsulation failure."); + } } if (ret == 0) { - ret = wc_KyberKey_PublicKeySize(kem, &pubSz); + XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + + *ssOutSz = ssSz; + keyShareEntry->ke = NULL; + keyShareEntry->keLen = 0; + + keyShareEntry->pubKey = ciphertext; + keyShareEntry->pubKeyLen = ctSz; + ciphertext = NULL; + + /* Set namedGroup so wolfSSL_get_curve_name() can function properly on + * the server side. */ + ssl->namedGroup = keyShareEntry->group; + } + + XFREE(ciphertext, ssl->heap, DYNAMIC_TYPE_TLSX); + + wc_KyberKey_Free(kemKey); + XFREE(kemKey, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); + keyShareEntry->key = NULL; + return ret; +} + +static int TLSX_KeyShare_HandlePqcHybridKeyServer(WOLFSSL* ssl, + KeyShareEntry* keyShareEntry, byte* data, word16 len) +{ + /* I am the server. The data parameter is the concatenation of the client's + * ECDH public key and the KEM public key. I need to generate a matching + * public key for ECDH and encapsulate a shared secret using the KEM public + * key. We send the ECDH public key and the KEM ciphertext back to the + * client. Additionally, we create the ECDH shared secret here already. + */ + int type; + byte* ciphertext = NULL; + int ret = 0; + int pqc_group = 0; + int ecc_group = 0; + int pqc_first = 0; + KeyShareEntry *ecc_kse = NULL; + KeyShareEntry *pqc_kse = NULL; + word32 pubSz = 0; + word32 ctSz = 0; + word32 ssSzPqc = 0; + word32 ssSzEcc = 0; + + if (data == NULL) { + WOLFSSL_MSG("No hybrid key share data from the client."); + return BAD_FUNC_ARG; + } + + /* Determine the ECC and PQC group of the hybrid combination */ + findEccPqc(&ecc_group, &pqc_group, &pqc_first, keyShareEntry->group); + if (ecc_group == 0 || pqc_group == 0) { + WOLFSSL_MSG("Invalid hybrid group"); + ret = BAD_FUNC_ARG; } + if (ret == 0) { - ret = wc_KyberKey_CipherTextSize(kem, &ctSz); + ecc_kse = (KeyShareEntry*)XMALLOC(sizeof(*ecc_kse), ssl->heap, + DYNAMIC_TYPE_TLSX); + pqc_kse = (KeyShareEntry*)XMALLOC(sizeof(*pqc_kse), ssl->heap, + DYNAMIC_TYPE_TLSX); + if (ecc_kse == NULL || pqc_kse == NULL) { + WOLFSSL_MSG("kse memory allocation failure"); + ret = MEMORY_ERROR; + } } + + /* The ciphertext and shared secret sizes of a KEM are fixed. Hence, we + * decode these sizes to properly concatenate the KEM ciphertext with the + * ECDH public key. */ if (ret == 0) { - ret = wc_KyberKey_SharedSecretSize(kem, &ssSz); + XMEMSET(pqc_kse, 0, sizeof(*pqc_kse)); + pqc_kse->group = pqc_group; + + /* Allocate a Kyber key to hold private key. */ + pqc_kse->key = (KyberKey*) XMALLOC(sizeof(KyberKey), ssl->heap, + DYNAMIC_TYPE_PRIVATE_KEY); + if (pqc_kse->key == NULL) { + WOLFSSL_MSG("GenPqcKey memory error"); + ret = MEMORY_E; + } + if (ret == 0) { + ret = mlkem_id2type(pqc_kse->group, &type); + } + if (ret != 0) { + WOLFSSL_MSG("Invalid PQC algorithm specified."); + ret = BAD_FUNC_ARG; + } + if (ret == 0) { + ret = wc_KyberKey_Init(type, (KyberKey*)pqc_kse->key, + ssl->heap, ssl->devId); + if (ret != 0) { + WOLFSSL_MSG("Error creating Kyber KEM"); + } + } + if (ret == 0) { + ret = wc_KyberKey_SharedSecretSize((KyberKey*)pqc_kse->key, + &ssSzPqc); + } + if (ret == 0) { + ret = wc_KyberKey_CipherTextSize((KyberKey*)pqc_kse->key, + &ctSz); + } + if (ret == 0) { + ret = wc_KyberKey_PublicKeySize((KyberKey*)pqc_kse->key, + &pubSz); + } + } + + /* Generate the ECDH key share part to be sent to the client */ + if (ret == 0 && ecc_group != 0) { + XMEMSET(ecc_kse, 0, sizeof(*ecc_kse)); + ecc_kse->group = ecc_group; + #ifdef HAVE_CURVE25519 + if (ecc_group == WOLFSSL_ECC_X25519) { + ret = TLSX_KeyShare_GenX25519Key(ssl, ecc_kse); + } + else + #endif + #ifdef HAVE_CURVE448 + if (ecc_group == WOLFSSL_ECC_X448) { + ret = TLSX_KeyShare_GenX448Key(ssl, ecc_kse); + } + else + #endif + { + ret = TLSX_KeyShare_GenEccKey(ssl, ecc_kse); + } + /* No error message, TLSX_KeyShare_GenKey will do it. */ } if (ret == 0 && len != pubSz + ecc_kse->pubKeyLen) { @@ -9397,72 +10116,113 @@ static int server_generate_pqc_ciphertext(WOLFSSL* ssl, ret = BAD_FUNC_ARG; } + /* Allocate buffer for the concatenated client key share data + * (PQC KEM ciphertext + ECDH public key) */ if (ret == 0) { - sharedSecret = (byte*)XMALLOC(ecc_kse->keyLen + ssSz, ssl->heap, - DYNAMIC_TYPE_SECRET); ciphertext = (byte*)XMALLOC(ecc_kse->pubKeyLen + ctSz, ssl->heap, DYNAMIC_TYPE_TLSX); - if (sharedSecret == NULL || ciphertext == NULL) { - WOLFSSL_MSG("Ciphertext/shared secret memory allocation failure."); + if (ciphertext == NULL) { + WOLFSSL_MSG("Ciphertext memory allocation failure."); ret = MEMORY_E; } } - if (ecc_group != 0) { + /* Process ECDH key share part. The generated shared secret is directly + * stored in the ssl->arrays->preMasterSecret buffer. Depending on the + * pqc_first flag, the ECDH shared secret part goes before or after the + * KEM part. */ + if (ret == 0) { + ecc_kse->keLen = len - pubSz; + ecc_kse->ke = (byte*)XMALLOC(ecc_kse->keLen, ssl->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (ecc_kse->ke == NULL) { + WOLFSSL_MSG("ecc_kse memory allocation failure"); + ret = MEMORY_ERROR; + } if (ret == 0) { - /* Point is validated by import function. */ - ret = wc_ecc_import_x963(data, len - pubSz, &eccpubkey); - if (ret != 0) { - WOLFSSL_MSG("Bad ECC public key."); + int pubOffset = 0; + int ssOffset = 0; + + /* Set the ECC size variable to the initial buffer size */ + ssSzEcc = ssl->arrays->preMasterSz; + + if (pqc_first) { + pubOffset = pubSz; + ssOffset = ssSzPqc; } - } -#if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \ - (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION != 2))) && \ - !defined(HAVE_SELFTEST) - if (ret == 0) { - ret = wc_ecc_set_rng((ecc_key *)ecc_kse->key, ssl->rng); - } -#endif + XMEMCPY(ecc_kse->ke, data + pubOffset, ecc_kse->keLen); + #ifdef HAVE_CURVE25519 + if (ecc_group == WOLFSSL_ECC_X25519) { + ret = TLSX_KeyShare_ProcessX25519_ex(ssl, ecc_kse, + ssl->arrays->preMasterSecret + ssOffset, &ssSzEcc); + } + else + #endif + #ifdef HAVE_CURVE448 + if (ecc_group == WOLFSSL_ECC_X448) { + ret = TLSX_KeyShare_ProcessX448_ex(ssl, ecc_kse, + ssl->arrays->preMasterSecret + ssOffset, &ssSzEcc); + } + else + #endif + { + ret = TLSX_KeyShare_ProcessEcc_ex(ssl, ecc_kse, + ssl->arrays->preMasterSecret + ssOffset, &ssSzEcc); + } + } if (ret == 0) { - outlen = ecc_kse->keyLen; - PRIVATE_KEY_UNLOCK(); - ret = wc_ecc_shared_secret((ecc_key *)ecc_kse->key, &eccpubkey, - sharedSecret, - &outlen); - PRIVATE_KEY_LOCK(); - if (outlen != ecc_kse->keyLen) { + if (ssSzEcc != ecc_kse->keyLen) { WOLFSSL_MSG("Data length mismatch."); ret = BAD_FUNC_ARG; } } } - if (ret == 0) { - ret = wc_KyberKey_DecodePublicKey(kem, data + ecc_kse->pubKeyLen, - pubSz); + if (ret == 0 && ssSzEcc + ssSzPqc > ENCRYPT_LEN) { + WOLFSSL_MSG("shared secret is too long."); + ret = LENGTH_ERROR; } + + /* Process PQC KEM key share part. Depending on the pqc_first flag, the + * KEM shared secret part goes before or after the ECDH part. */ if (ret == 0) { - ret = wc_KyberKey_Encapsulate(kem, ciphertext + ecc_kse->pubKeyLen, - sharedSecret + outlen, ssl->rng); - if (ret != 0) { - WOLFSSL_MSG("wc_KyberKey encapsulation failure."); + int input_offset = ecc_kse->keLen; + int output_offset = ssSzEcc; + + if (pqc_first) { + input_offset = 0; + output_offset = 0; } + + ret = TLSX_KeyShare_HandlePqcKeyServer(ssl, pqc_kse, + data + input_offset, pubSz, + ssl->arrays->preMasterSecret + output_offset, &ssSzPqc); } if (ret == 0) { XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); - keyShareEntry->ke = sharedSecret; - keyShareEntry->keLen = outlen + ssSz; - sharedSecret = NULL; + ssl->arrays->preMasterSz = ssSzEcc + ssSzPqc; + keyShareEntry->ke = NULL; + keyShareEntry->keLen = 0; - if (ecc_kse->pubKeyLen > 0) + /* Concatenate the ECDH public key and the PQC KEM ciphertext. Based on + * the pqc_first flag, the ECDH public key goes before or after the KEM + * ciphertext. */ + if (pqc_first) { + XMEMCPY(ciphertext, pqc_kse->pubKey, ctSz); + XMEMCPY(ciphertext + ctSz, ecc_kse->pubKey, ecc_kse->pubKeyLen); + } + else { XMEMCPY(ciphertext, ecc_kse->pubKey, ecc_kse->pubKeyLen); + XMEMCPY(ciphertext + ecc_kse->pubKeyLen, pqc_kse->pubKey, ctSz); + } + keyShareEntry->pubKey = ciphertext; - keyShareEntry->pubKeyLen = (word32)(ecc_kse->pubKeyLen + ctSz); + keyShareEntry->pubKeyLen = ecc_kse->pubKeyLen + ctSz; ciphertext = NULL; /* Set namedGroup so wolfSSL_get_curve_name() can function properly on @@ -9471,13 +10231,11 @@ static int server_generate_pqc_ciphertext(WOLFSSL* ssl, } TLSX_KeyShare_FreeAll(ecc_kse, ssl->heap); - XFREE(sharedSecret, ssl->heap, DYNAMIC_TYPE_SECRET); + TLSX_KeyShare_FreeAll(pqc_kse, ssl->heap); XFREE(ciphertext, ssl->heap, DYNAMIC_TYPE_TLSX); - wc_ecc_free(&eccpubkey); - wc_KyberKey_Free(kem); return ret; } -#endif /* WOLFSSL_HAVE_KYBER */ +#endif /* WOLFSSL_HAVE_MLKEM && !WOLFSSL_MLKEM_NO_ENCAPSULATE */ /* Use the data to create a new key share object in the extensions. * @@ -9526,11 +10284,22 @@ int TLSX_KeyShare_Use(const WOLFSSL* ssl, word16 group, word16 len, byte* data, } -#ifdef WOLFSSL_HAVE_KYBER - if (WOLFSSL_NAMED_GROUP_IS_PQC(group) && - ssl->options.side == WOLFSSL_SERVER_END) { - ret = server_generate_pqc_ciphertext((WOLFSSL*)ssl, keyShareEntry, data, - len); +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) + if (ssl->options.side == WOLFSSL_SERVER_END && + WOLFSSL_NAMED_GROUP_IS_PQC(group)) { + ret = TLSX_KeyShare_HandlePqcKeyServer((WOLFSSL*)ssl, + keyShareEntry, + data, len, + ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz); + if (ret != 0) + return ret; + } + else if (ssl->options.side == WOLFSSL_SERVER_END && + WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(group)) { + ret = TLSX_KeyShare_HandlePqcHybridKeyServer((WOLFSSL*)ssl, + keyShareEntry, + data, len); if (ret != 0) return ret; } @@ -9691,54 +10460,93 @@ static int TLSX_KeyShare_IsSupported(int namedGroup) break; #endif #endif -#ifdef WOLFSSL_HAVE_KYBER +#ifdef WOLFSSL_HAVE_MLKEM #ifndef WOLFSSL_NO_ML_KEM - #ifdef WOLFSSL_WC_KYBER + #ifdef WOLFSSL_WC_MLKEM #ifndef WOLFSSL_NO_ML_KEM_512 case WOLFSSL_ML_KEM_512: case WOLFSSL_P256_ML_KEM_512: + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + case WOLFSSL_X25519_ML_KEM_512: + #endif #endif #ifndef WOLFSSL_NO_ML_KEM_768 case WOLFSSL_ML_KEM_768: case WOLFSSL_P384_ML_KEM_768: + case WOLFSSL_P256_ML_KEM_768: + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + case WOLFSSL_X25519_ML_KEM_768: + #endif + #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 + case WOLFSSL_X448_ML_KEM_768: + #endif #endif #ifndef WOLFSSL_NO_ML_KEM_1024 case WOLFSSL_ML_KEM_1024: case WOLFSSL_P521_ML_KEM_1024: + case WOLFSSL_P384_ML_KEM_1024: #endif break; #elif defined(HAVE_LIBOQS) case WOLFSSL_ML_KEM_512: case WOLFSSL_ML_KEM_768: case WOLFSSL_ML_KEM_1024: + { + int ret; + int id; + ret = mlkem_id2type(namedGroup, &id); + if (ret == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) { + return 0; + } + + if (! ext_mlkem_enabled(id)) { + return 0; + } + break; + } case WOLFSSL_P256_ML_KEM_512: case WOLFSSL_P384_ML_KEM_768: + case WOLFSSL_P256_ML_KEM_768: case WOLFSSL_P521_ML_KEM_1024: + case WOLFSSL_P384_ML_KEM_1024: + case WOLFSSL_X25519_ML_KEM_512: + case WOLFSSL_X448_ML_KEM_768: + case WOLFSSL_X25519_ML_KEM_768: { int ret; int id; - findEccPqc(NULL, &namedGroup, namedGroup); - ret = kyber_id2type(namedGroup, &id); + findEccPqc(NULL, &namedGroup, NULL, namedGroup); + ret = mlkem_id2type(namedGroup, &id); if (ret == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) { return 0; } - if (! ext_kyber_enabled(id)) { + if (! ext_mlkem_enabled(id)) { return 0; } break; } #endif -#endif -#ifdef WOLFSSL_KYBER_ORIGINAL - #ifdef WOLFSSL_WC_KYBER +#endif /* WOLFSSL_NO_ML_KEM */ +#ifdef WOLFSSL_MLKEM_KYBER + #ifdef WOLFSSL_WC_MLKEM #ifdef WOLFSSL_KYBER512 case WOLFSSL_KYBER_LEVEL1: case WOLFSSL_P256_KYBER_LEVEL1: + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + case WOLFSSL_X25519_KYBER_LEVEL1: + #endif #endif #ifdef WOLFSSL_KYBER768 case WOLFSSL_KYBER_LEVEL3: case WOLFSSL_P384_KYBER_LEVEL3: + case WOLFSSL_P256_KYBER_LEVEL3: + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + case WOLFSSL_X25519_KYBER_LEVEL3: + #endif + #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 + case WOLFSSL_X448_KYBER_LEVEL3: + #endif #endif #ifdef WOLFSSL_KYBER1024 case WOLFSSL_KYBER_LEVEL5: @@ -9749,26 +10557,43 @@ static int TLSX_KeyShare_IsSupported(int namedGroup) case WOLFSSL_KYBER_LEVEL1: case WOLFSSL_KYBER_LEVEL3: case WOLFSSL_KYBER_LEVEL5: + { + int ret; + int id; + ret = mlkem_id2type(namedGroup, &id); + if (ret == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) { + return 0; + } + + if (! ext_mlkem_enabled(id)) { + return 0; + } + break; + } case WOLFSSL_P256_KYBER_LEVEL1: case WOLFSSL_P384_KYBER_LEVEL3: + case WOLFSSL_P256_KYBER_LEVEL3: case WOLFSSL_P521_KYBER_LEVEL5: + case WOLFSSL_X25519_KYBER_LEVEL1: + case WOLFSSL_X448_KYBER_LEVEL3: + case WOLFSSL_X25519_KYBER_LEVEL3: { int ret; int id; - findEccPqc(NULL, &namedGroup, namedGroup); - ret = kyber_id2type(namedGroup, &id); + findEccPqc(NULL, &namedGroup, NULL, namedGroup); + ret = mlkem_id2type(namedGroup, &id); if (ret == WC_NO_ERR_TRACE(NOT_COMPILED_IN)) { return 0; } - if (! ext_kyber_enabled(id)) { + if (! ext_mlkem_enabled(id)) { return 0; } break; } #endif #endif -#endif /* WOLFSSL_HAVE_KYBER */ +#endif /* WOLFSSL_HAVE_MLKEM */ default: return 0; } @@ -9815,18 +10640,29 @@ static const word16 preferredGroup[] = { WOLFSSL_FFDHE_8192, #endif #ifndef WOLFSSL_NO_ML_KEM -#ifdef WOLFSSL_WC_KYBER +#ifdef WOLFSSL_WC_MLKEM #ifndef WOLFSSL_NO_ML_KEM_512 WOLFSSL_ML_KEM_512, WOLFSSL_P256_ML_KEM_512, + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + WOLFSSL_X25519_ML_KEM_512, + #endif #endif #ifndef WOLFSSL_NO_ML_KEM_768 WOLFSSL_ML_KEM_768, WOLFSSL_P384_ML_KEM_768, + WOLFSSL_P256_ML_KEM_768, + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + WOLFSSL_X25519_ML_KEM_768, + #endif + #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 + WOLFSSL_X448_ML_KEM_768, + #endif #endif #ifndef WOLFSSL_NO_ML_KEM_1024 WOLFSSL_ML_KEM_1024, WOLFSSL_P521_ML_KEM_1024, + WOLFSSL_P384_ML_KEM_1024, #endif #elif defined(HAVE_LIBOQS) /* These require a runtime call to TLSX_KeyShare_IsSupported to use */ @@ -9835,18 +10671,37 @@ static const word16 preferredGroup[] = { WOLFSSL_ML_KEM_1024, WOLFSSL_P256_ML_KEM_512, WOLFSSL_P384_ML_KEM_768, + WOLFSSL_P256_ML_KEM_768, WOLFSSL_P521_ML_KEM_1024, + WOLFSSL_P384_ML_KEM_1024, + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + WOLFSSL_X25519_ML_KEM_512, + WOLFSSL_X25519_ML_KEM_768, + #endif + #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 + WOLFSSL_X448_ML_KEM_768, + #endif #endif #endif /* !WOLFSSL_NO_ML_KEM */ -#ifdef WOLFSSL_KYBER_ORIGINAL -#ifdef WOLFSSL_WC_KYBER +#ifdef WOLFSSL_MLKEM_KYBER +#ifdef WOLFSSL_WC_MLKEM #ifdef WOLFSSL_KYBER512 WOLFSSL_KYBER_LEVEL1, WOLFSSL_P256_KYBER_LEVEL1, + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + WOLFSSL_X25519_KYBER_LEVEL1, + #endif #endif #ifdef WOLFSSL_KYBER768 WOLFSSL_KYBER_LEVEL3, WOLFSSL_P384_KYBER_LEVEL3, + WOLFSSL_P256_KYBER_LEVEL3, + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + WOLFSSL_X25519_KYBER_LEVEL3, + #endif + #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 + WOLFSSL_X448_KYBER_LEVEL3, + #endif #endif #ifdef WOLFSSL_KYBER1024 WOLFSSL_KYBER_LEVEL5, @@ -9859,9 +10714,17 @@ static const word16 preferredGroup[] = { WOLFSSL_KYBER_LEVEL5, WOLFSSL_P256_KYBER_LEVEL1, WOLFSSL_P384_KYBER_LEVEL3, + WOLFSSL_P256_KYBER_LEVEL3, WOLFSSL_P521_KYBER_LEVEL5, + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + WOLFSSL_X25519_KYBER_LEVEL1, + WOLFSSL_X25519_KYBER_LEVEL3, + #endif + #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 + WOLFSSL_X448_KYBER_LEVEL3, + #endif #endif -#endif /* WOLFSSL_KYBER_ORIGINAL */ +#endif /* WOLFSSL_MLKEM_KYBER */ WOLFSSL_NAMED_GROUP_INVALID }; @@ -9884,8 +10747,7 @@ static int TLSX_KeyShare_GroupRank(const WOLFSSL* ssl, int group) byte numGroups; if (ssl->numGroups == 0) { - groups = preferredGroup; - numGroups = PREFERRED_GROUP_SZ; + return 0; } else { groups = ssl->group; @@ -10031,10 +10893,11 @@ int TLSX_CKS_Set(WOLFSSL* ssl, TLSX** extensions) int TLSX_CKS_Parse(WOLFSSL* ssl, byte* input, word16 length, TLSX** extensions) { - (void) extensions; int ret; int i, j; + (void) extensions; + /* Validating the input. */ if (length == 0) return BUFFER_ERROR; @@ -10154,7 +11017,9 @@ int TLSX_KeyShare_Choose(const WOLFSSL *ssl, TLSX* extensions, /* Use server's preference order. */ for (clientKSE = list; clientKSE != NULL; clientKSE = clientKSE->next) { - if (clientKSE->ke == NULL) + if ((clientKSE->ke == NULL) && + (!WOLFSSL_NAMED_GROUP_IS_PQC(clientKSE->group)) && + (!WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(clientKSE->group))) continue; #ifdef WOLFSSL_SM2 @@ -10174,11 +11039,12 @@ int TLSX_KeyShare_Choose(const WOLFSSL *ssl, TLSX* extensions, if (!TLSX_SupportedGroups_Find(ssl, clientKSE->group, extensions)) continue; - if (!WOLFSSL_NAMED_GROUP_IS_FFHDE(clientKSE->group)) { + if (!WOLFSSL_NAMED_GROUP_IS_FFDHE(clientKSE->group)) { /* Check max value supported. */ if (clientKSE->group > WOLFSSL_ECC_MAX) { -#ifdef WOLFSSL_HAVE_KYBER - if (!WOLFSSL_NAMED_GROUP_IS_PQC(clientKSE->group)) +#ifdef WOLFSSL_HAVE_MLKEM + if (!WOLFSSL_NAMED_GROUP_IS_PQC(clientKSE->group) && + !WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(clientKSE->group)) #endif continue; } @@ -10233,7 +11099,7 @@ int TLSX_KeyShare_Setup(WOLFSSL *ssl, KeyShareEntry* clientKSE) return BAD_FUNC_ARG; } - /* Generate a new key pair except in the case of OQS KEM because we + /* Generate a new key pair except in the case of PQC KEM because we * are going to encapsulate and that does not require us to generate a * key pair. */ @@ -10242,8 +11108,9 @@ int TLSX_KeyShare_Setup(WOLFSSL *ssl, KeyShareEntry* clientKSE) return ret; if (clientKSE->key == NULL) { -#ifdef WOLFSSL_HAVE_KYBER - if (WOLFSSL_NAMED_GROUP_IS_PQC(clientKSE->group)) { +#ifdef WOLFSSL_HAVE_MLKEM + if (WOLFSSL_NAMED_GROUP_IS_PQC(clientKSE->group) || + WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(clientKSE->group)) { /* Going to need the public key (AKA ciphertext). */ serverKSE->pubKey = clientKSE->pubKey; clientKSE->pubKey = NULL; @@ -12004,41 +12871,35 @@ static int TLSX_ECH_Use(WOLFSSL_EchConfig* echConfig, TLSX** extensions, { int ret = 0; int suiteIndex; + TLSX* echX; WOLFSSL_ECH* ech; - if (extensions == NULL) return BAD_FUNC_ARG; - + /* skip if we already have an ech extension, we will for hrr */ + echX = TLSX_Find(*extensions, TLSX_ECH); + if (echX != NULL) + return 0; /* find a supported cipher suite */ suiteIndex = EchConfigGetSupportedCipherSuite(echConfig); - if (suiteIndex < 0) return suiteIndex; - ech = (WOLFSSL_ECH*)XMALLOC(sizeof(WOLFSSL_ECH), heap, DYNAMIC_TYPE_TMP_BUFFER); - if (ech == NULL) return MEMORY_E; - ForceZero(ech, sizeof(WOLFSSL_ECH)); - ech->state = ECH_WRITE_REAL; - ech->echConfig = echConfig; - /* 0 for outer */ ech->type = ECH_TYPE_OUTER; /* kemId */ ech->kemId = echConfig->kemId; - /* cipherSuite kdf */ ech->cipherSuite.kdfId = echConfig->cipherSuites[suiteIndex].kdfId; /* cipherSuite aead */ ech->cipherSuite.aeadId = echConfig->cipherSuites[suiteIndex].aeadId; /* configId */ ech->configId = echConfig->configId; - /* encLen */ switch (echConfig->kemId) { @@ -12058,30 +12919,23 @@ static int TLSX_ECH_Use(WOLFSSL_EchConfig* echConfig, TLSX** extensions, ech->encLen = DHKEM_X448_ENC_LEN; break; } - /* setup hpke */ ech->hpke = (Hpke*)XMALLOC(sizeof(Hpke), heap, DYNAMIC_TYPE_TMP_BUFFER); - if (ech->hpke == NULL) { XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; } - ret = wc_HpkeInit(ech->hpke, ech->kemId, ech->cipherSuite.kdfId, ech->cipherSuite.aeadId, heap); - /* setup the ephemeralKey */ if (ret == 0) ret = wc_HpkeGenerateKeyPair(ech->hpke, &ech->ephemeralKey, rng); - if (ret == 0) ret = TLSX_Push(extensions, TLSX_ECH, ech, heap); - if (ret != 0) { XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER); } - return ret; } @@ -12092,41 +12946,31 @@ static int TLSX_ServerECH_Use(TLSX** extensions, void* heap, int ret; WOLFSSL_ECH* ech; TLSX* echX; - if (extensions == NULL) return BAD_FUNC_ARG; - /* if we already have ech don't override it */ echX = TLSX_Find(*extensions, TLSX_ECH); if (echX != NULL) return 0; - ech = (WOLFSSL_ECH*)XMALLOC(sizeof(WOLFSSL_ECH), heap, DYNAMIC_TYPE_TMP_BUFFER); - if (ech == NULL) return MEMORY_E; - ForceZero(ech, sizeof(WOLFSSL_ECH)); - ech->state = ECH_WRITE_NONE; - /* 0 for outer */ ech->type = ECH_TYPE_OUTER; - ech->echConfig = configs; - /* setup the rest of the settings when we receive ech from the client */ ret = TLSX_Push(extensions, TLSX_ECH, ech, heap); - if (ret != 0) XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER); - return ret; } -/* return length after writing the ech */ -static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte* writeBuf, word16* offset) +/* return status after writing the ech and updating offset */ +static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte msgType, byte* writeBuf, + word16* offset) { int ret = 0; int rngRet = -1; @@ -12140,84 +12984,75 @@ static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte* writeBuf, word16* offset) Hpke hpke[1]; WC_RNG rng[1]; #endif - WOLFSSL_MSG("TLSX_ECH_Write"); - + if (msgType == hello_retry_request) { + /* reserve space to write the confirmation to */ + *offset += ECH_ACCEPT_CONFIRMATION_SZ; + /* set confBuf */ + ech->confBuf = writeBuf; + return 0; + } if (ech->state == ECH_WRITE_NONE || ech->state == ECH_PARSED_INTERNAL) return 0; - if (ech->state == ECH_WRITE_RETRY_CONFIGS) { /* get size then write */ ret = GetEchConfigsEx(ech->echConfig, NULL, &configsLen); - if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) return ret; - ret = GetEchConfigsEx(ech->echConfig, writeBuf, &configsLen); - if (ret != WOLFSSL_SUCCESS) return ret; - *offset += configsLen; - return 0; } - -#ifdef WOLFSSL_SMALL_STACK - hpke = (Hpke*)XMALLOC(sizeof(Hpke), NULL, DYNAMIC_TYPE_TMP_BUFFER); - - if (hpke == NULL) - return MEMORY_E; - - rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); - - if (rng == NULL) { - XFREE(hpke, NULL, DYNAMIC_TYPE_RNG); - return MEMORY_E; - } -#endif - /* type */ *writeBuf_p = ech->type; writeBuf_p += sizeof(ech->type); - /* outer has body, inner does not */ if (ech->type == ECH_TYPE_OUTER) { /* kdfId */ c16toa(ech->cipherSuite.kdfId, writeBuf_p); writeBuf_p += sizeof(ech->cipherSuite.kdfId); - /* aeadId */ c16toa(ech->cipherSuite.aeadId, writeBuf_p); writeBuf_p += sizeof(ech->cipherSuite.aeadId); - /* configId */ *writeBuf_p = ech->configId; writeBuf_p += sizeof(ech->configId); - /* encLen */ - c16toa(ech->encLen, writeBuf_p); + if (ech->hpkeContext == NULL) { + c16toa(ech->encLen, writeBuf_p); + } + else { + /* set to 0 if this is clientInner 2 */ + c16toa(0, writeBuf_p); + } writeBuf_p += 2; - if (ech->state == ECH_WRITE_GREASE) { +#ifdef WOLFSSL_SMALL_STACK + hpke = (Hpke*)XMALLOC(sizeof(Hpke), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (hpke == NULL) + return MEMORY_E; + rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); + if (rng == NULL) { + XFREE(hpke, NULL, DYNAMIC_TYPE_RNG); + return MEMORY_E; + } +#endif /* hpke init */ ret = wc_HpkeInit(hpke, ech->kemId, ech->cipherSuite.kdfId, ech->cipherSuite.aeadId, NULL); - if (ret == 0) rngRet = ret = wc_InitRng(rng); - /* create the ephemeralKey */ if (ret == 0) ret = wc_HpkeGenerateKeyPair(hpke, &ephemeralKey, rng); - /* enc */ if (ret == 0) { ret = wc_HpkeSerializePublicKey(hpke, ephemeralKey, writeBuf_p, &ech->encLen); writeBuf_p += ech->encLen; } - if (ret == 0) { /* innerClientHelloLen */ c16toa(GREASE_ECH_SIZE + ((writeBuf_p + 2 - writeBuf) % 32), @@ -12229,45 +13064,40 @@ static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte* writeBuf, word16* offset) ((writeBuf_p - writeBuf) % 32)); writeBuf_p += GREASE_ECH_SIZE + ((writeBuf_p - writeBuf) % 32); } - if (rngRet == 0) wc_FreeRng(rng); - if (ephemeralKey != NULL) wc_HpkeFreeKey(hpke, hpke->kem, ephemeralKey, hpke->heap); +#ifdef WOLFSSL_SMALL_STACK + XFREE(hpke, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(rng, NULL, DYNAMIC_TYPE_RNG); +#endif } else { - /* write enc to writeBuf_p */ - ret = wc_HpkeSerializePublicKey(ech->hpke, ech->ephemeralKey, - writeBuf_p, &ech->encLen); - writeBuf_p += ech->encLen; - + /* only write enc if this is our first ech, no hpke context */ + if (ech->hpkeContext == NULL) { + /* write enc to writeBuf_p */ + ret = wc_HpkeSerializePublicKey(ech->hpke, ech->ephemeralKey, + writeBuf_p, &ech->encLen); + writeBuf_p += ech->encLen; + } /* innerClientHelloLen */ c16toa(ech->innerClientHelloLen, writeBuf_p); writeBuf_p += 2; - /* set payload offset for when we finalize */ ech->outerClientPayload = writeBuf_p; - /* write zeros for payload */ XMEMSET(writeBuf_p, 0, ech->innerClientHelloLen); writeBuf_p += ech->innerClientHelloLen; } } - -#ifdef WOLFSSL_SMALL_STACK - XFREE(hpke, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(rng, NULL, DYNAMIC_TYPE_RNG); -#endif - if (ret == 0) *offset += (writeBuf_p - writeBuf); - return ret; } /* return the size needed for the ech extension */ -static int TLSX_ECH_GetSize(WOLFSSL_ECH* ech) +static int TLSX_ECH_GetSize(WOLFSSL_ECH* ech, byte msgType) { int ret; word32 size; @@ -12279,6 +13109,9 @@ static int TLSX_ECH_GetSize(WOLFSSL_ECH* ech) size += GREASE_ECH_SIZE + (size % 32); } + else if (msgType == hello_retry_request) { + size = ECH_ACCEPT_CONFIRMATION_SZ; + } else if (ech->state == ECH_WRITE_NONE || ech->state == ECH_PARSED_INTERNAL) { size = 0; @@ -12297,8 +13130,11 @@ static int TLSX_ECH_GetSize(WOLFSSL_ECH* ech) else { size = sizeof(ech->type) + sizeof(ech->cipherSuite) + - sizeof(ech->configId) + sizeof(word16) + ech->encLen + - sizeof(word16) + ech->innerClientHelloLen; + sizeof(ech->configId) + sizeof(word16) + sizeof(word16) + + ech->innerClientHelloLen; + /* only set encLen if this is inner hello 1 */ + if (ech->hpkeContext == NULL) + size += ech->encLen; } return (int)size; @@ -12316,10 +13152,8 @@ static int TLSX_ExtractEch(WOLFSSL_ECH* ech, WOLFSSL_EchConfig* echConfig, word32 rawConfigLen = 0; byte* info = NULL; word32 infoLen = 0; - if (ech == NULL || echConfig == NULL || aad == NULL) return BAD_FUNC_ARG; - /* verify the kem and key len */ switch (echConfig->kemId) { @@ -12342,10 +13176,8 @@ static int TLSX_ExtractEch(WOLFSSL_ECH* ech, WOLFSSL_EchConfig* echConfig, expectedEncLen = 0; break; } - if (expectedEncLen != ech->encLen) return BAD_FUNC_ARG; - /* verify the cipher suite */ for (i = 0; i < echConfig->numCipherSuites; i++) { if (echConfig->cipherSuites[i].kdfId == ech->cipherSuite.kdfId && @@ -12353,54 +13185,69 @@ static int TLSX_ExtractEch(WOLFSSL_ECH* ech, WOLFSSL_EchConfig* echConfig, break; } } - if (i >= echConfig->numCipherSuites) { return BAD_FUNC_ARG; } - - ech->hpke = (Hpke*)XMALLOC(sizeof(Hpke), heap, DYNAMIC_TYPE_TMP_BUFFER); - - if (ech->hpke == NULL) - return MEMORY_E; - - ret = wc_HpkeInit(ech->hpke, echConfig->kemId, ech->cipherSuite.kdfId, - ech->cipherSuite.aeadId, heap); - - /* get the rawConfigLen */ - if (ret == 0) - ret = GetEchConfig(echConfig, NULL, &rawConfigLen); - - if (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E)) - ret = 0; - - /* create info */ - if (ret == 0) { - infoLen = TLS_INFO_CONST_STRING_SZ + 1 + rawConfigLen; - info = (byte*)XMALLOC(infoLen, heap, DYNAMIC_TYPE_TMP_BUFFER); - - if (info == NULL) + /* check if hpke already exists, may if HelloRetryRequest */ + if (ech->hpke == NULL) { + ech->hpke = (Hpke*)XMALLOC(sizeof(Hpke), heap, DYNAMIC_TYPE_TMP_BUFFER); + if (ech->hpke == NULL) ret = MEMORY_E; - else { - XMEMCPY(info, (byte*)TLS_INFO_CONST_STRING, - TLS_INFO_CONST_STRING_SZ + 1); - ret = GetEchConfig(echConfig, info + - TLS_INFO_CONST_STRING_SZ + 1, &rawConfigLen); + /* init the hpke struct */ + if (ret == 0) { + ret = wc_HpkeInit(ech->hpke, echConfig->kemId, + ech->cipherSuite.kdfId, ech->cipherSuite.aeadId, heap); } - } + if (ret == 0) { + /* allocate hpkeContext */ + ech->hpkeContext = + (HpkeBaseContext*)XMALLOC(sizeof(HpkeBaseContext), + ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (ech->hpkeContext == NULL) + ret = MEMORY_E; + } + /* get the rawConfigLen */ + if (ret == 0) + ret = GetEchConfig(echConfig, NULL, &rawConfigLen); + if (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E)) + ret = 0; + /* create info */ + if (ret == 0) { + infoLen = TLS_INFO_CONST_STRING_SZ + 1 + rawConfigLen; + info = (byte*)XMALLOC(infoLen, heap, DYNAMIC_TYPE_TMP_BUFFER); + if (info == NULL) + ret = MEMORY_E; + else { + XMEMCPY(info, (byte*)TLS_INFO_CONST_STRING, + TLS_INFO_CONST_STRING_SZ + 1); + ret = GetEchConfig(echConfig, info + + TLS_INFO_CONST_STRING_SZ + 1, &rawConfigLen); + } + } + /* init the context for opening */ + if (ret == 0) { + ret = wc_HpkeInitOpenContext(ech->hpke, ech->hpkeContext, + echConfig->receiverPrivkey, ech->enc, ech->encLen, info, + infoLen); + } + } /* decrypt the ech payload */ - if (ret == 0) - ret = wc_HpkeOpenBase(ech->hpke, echConfig->receiverPrivkey, ech->enc, - ech->encLen, info, infoLen, aad, aadLen, ech->outerClientPayload, - ech->innerClientHelloLen, + if (ret == 0) { + ret = wc_HpkeContextOpenBase(ech->hpke, ech->hpkeContext, aad, aadLen, + ech->outerClientPayload, ech->innerClientHelloLen, ech->innerClientHello + HANDSHAKE_HEADER_SZ); - + } + /* free the hpke and context on failure */ if (ret != 0) { XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER); ech->hpke = NULL; + XFREE(ech->hpkeContext, heap, DYNAMIC_TYPE_TMP_BUFFER); + ech->hpkeContext = NULL; } - XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER); + if (info != NULL) + XFREE(info, heap, DYNAMIC_TYPE_TMP_BUFFER); return ret; } @@ -12417,94 +13264,98 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size, WOLFSSL_EchConfig* echConfig; byte* aadCopy; byte* readBuf_p = (byte*)readBuf; - WOLFSSL_MSG("TLSX_ECH_Parse"); - if (size == 0) return BAD_FUNC_ARG; - if (ssl->options.disableECH) { WOLFSSL_MSG("TLSX_ECH_Parse: ECH disabled. Ignoring."); return 0; } - + /* retry configs */ if (msgType == encrypted_extensions) { ret = wolfSSL_SetEchConfigs(ssl, readBuf, size); if (ret == WOLFSSL_SUCCESS) ret = 0; } + /* HRR with special confirmation */ + else if (msgType == hello_retry_request && ssl->options.useEch) { + /* length must be 8 */ + if (size != ECH_ACCEPT_CONFIRMATION_SZ) + return BAD_FUNC_ARG; + /* get extension */ + echX = TLSX_Find(ssl->extensions, TLSX_ECH); + if (echX == NULL) + return BAD_FUNC_ARG; + ech = (WOLFSSL_ECH*)echX->data; + ech->confBuf = (byte*)readBuf; + } else if (msgType == client_hello && ssl->ctx->echConfigs != NULL) { + /* get extension */ echX = TLSX_Find(ssl->extensions, TLSX_ECH); - if (echX == NULL) return BAD_FUNC_ARG; - ech = (WOLFSSL_ECH*)echX->data; - /* read the ech parameters before the payload */ ech->type = *readBuf_p; readBuf_p++; - if (ech->type == ECH_TYPE_INNER) { ech->state = ECH_PARSED_INTERNAL; return 0; } - /* technically the payload would only be 1 byte at this length */ if (size < 11 + ech->encLen) return BAD_FUNC_ARG; - + /* read kdfId */ ato16(readBuf_p, &ech->cipherSuite.kdfId); readBuf_p += 2; - + /* read aeadId */ ato16(readBuf_p, &ech->cipherSuite.aeadId); readBuf_p += 2; - + /* read configId */ ech->configId = *readBuf_p; readBuf_p++; - - ato16(readBuf_p, &ech->encLen); - readBuf_p += 2; - - if (ech->encLen > HPKE_Npk_MAX) - return BAD_FUNC_ARG; - - XMEMCPY(ech->enc, readBuf_p, ech->encLen); - readBuf_p += ech->encLen; - + /* only get enc if we don't already have the hpke context */ + if (ech->hpkeContext == NULL) { + /* read encLen */ + ato16(readBuf_p, &ech->encLen); + readBuf_p += 2; + if (ech->encLen > HPKE_Npk_MAX) + return BAD_FUNC_ARG; + /* read enc */ + XMEMCPY(ech->enc, readBuf_p, ech->encLen); + readBuf_p += ech->encLen; + } + else { + readBuf_p += 2; + } + /* read hello inner len */ ato16(readBuf_p, &ech->innerClientHelloLen); ech->innerClientHelloLen -= WC_AES_BLOCK_SIZE; readBuf_p += 2; - ech->outerClientPayload = readBuf_p; - /* make a copy of the aad */ aadCopy = (byte*)XMALLOC(ech->aadLen, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (aadCopy == NULL) return MEMORY_E; - XMEMCPY(aadCopy, ech->aad, ech->aadLen); - /* set the ech payload of the copy to zeros */ XMEMSET(aadCopy + (readBuf_p - ech->aad), 0, ech->innerClientHelloLen + WC_AES_BLOCK_SIZE); - + /* free the old ech in case this is our second client hello */ + if (ech->innerClientHello != NULL) + XFREE(ech->innerClientHello, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); /* allocate the inner payload buffer */ ech->innerClientHello = (byte*)XMALLOC(ech->innerClientHelloLen + HANDSHAKE_HEADER_SZ, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (ech->innerClientHello == NULL) { XFREE(aadCopy, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); return MEMORY_E; } - /* first check if the config id matches */ echConfig = ssl->ctx->echConfigs; - while (echConfig != NULL) { /* decrypt with this config */ if (echConfig->configId == ech->configId) { @@ -12512,26 +13363,20 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size, ssl->heap); break; } - echConfig = echConfig->next; } - /* try to decrypt with all configs */ if (echConfig == NULL || ret != 0) { echConfig = ssl->ctx->echConfigs; - while (echConfig != NULL) { ret = TLSX_ExtractEch(ech, echConfig, aadCopy, ech->aadLen, ssl->heap); - if (ret== 0) break; - echConfig = echConfig->next; } } - - /* if we failed to extract */ + /* if we failed to extract, set state to retry configs */ if (ret != 0) { XFREE(ech->innerClientHello, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); ech->innerClientHello = NULL; @@ -12539,19 +13384,15 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size, } else { i = 0; - /* decrement until before the padding */ while (ech->innerClientHello[ech->innerClientHelloLen + HANDSHAKE_HEADER_SZ - i - 1] != ECH_TYPE_INNER) { i++; } - /* subtract the length of the padding from the length */ ech->innerClientHelloLen -= i; } - XFREE(aadCopy, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - return 0; } @@ -12565,7 +13406,10 @@ static void TLSX_ECH_Free(WOLFSSL_ECH* ech, void* heap) if (ech->ephemeralKey != NULL) wc_HpkeFreeKey(ech->hpke, ech->hpke->kem, ech->ephemeralKey, ech->hpke->heap); - XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER); + if (ech->hpke != NULL) + XFREE(ech->hpke, heap, DYNAMIC_TYPE_TMP_BUFFER); + if (ech->hpkeContext != NULL) + XFREE(ech->hpkeContext, heap, DYNAMIC_TYPE_TMP_BUFFER); XFREE(ech, heap, DYNAMIC_TYPE_TMP_BUFFER); (void)heap; @@ -12575,58 +13419,65 @@ static void TLSX_ECH_Free(WOLFSSL_ECH* ech, void* heap) * status */ int TLSX_FinalizeEch(WOLFSSL_ECH* ech, byte* aad, word32 aadLen) { - int ret; + int ret = 0; void* receiverPubkey = NULL; - byte* info; - int infoLen; - byte* aadCopy; - - /* import the server public key */ - ret = wc_HpkeDeserializePublicKey(ech->hpke, &receiverPubkey, - ech->echConfig->receiverPubkey, ech->encLen); - - if (ret == 0) { - /* create info */ - infoLen = TLS_INFO_CONST_STRING_SZ + 1 + ech->echConfig->rawLen; - info = (byte*)XMALLOC(infoLen, ech->hpke->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (info == NULL) - ret = MEMORY_E; - + byte* info = NULL; + int infoLen = 0; + byte* aadCopy = NULL; + /* setup hpke context to seal, should be done at most once per connection */ + if (ech->hpkeContext == NULL) { + /* import the server public key */ + ret = wc_HpkeDeserializePublicKey(ech->hpke, &receiverPubkey, + ech->echConfig->receiverPubkey, ech->encLen); if (ret == 0) { - /* puts the null byte in for me */ - XMEMCPY(info, (byte*)TLS_INFO_CONST_STRING, TLS_INFO_CONST_STRING_SZ - + 1); - XMEMCPY(info + TLS_INFO_CONST_STRING_SZ + 1, ech->echConfig->raw, - ech->echConfig->rawLen); - - /* make a copy of the aad since we overwrite it */ - aadCopy = (byte*)XMALLOC(aadLen, ech->hpke->heap, + /* allocate hpke context */ + ech->hpkeContext = + (HpkeBaseContext*)XMALLOC(sizeof(HpkeBaseContext), + ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (ech->hpkeContext == NULL) + ret = MEMORY_E; + } + if (ret == 0) { + /* create info */ + infoLen = TLS_INFO_CONST_STRING_SZ + 1 + ech->echConfig->rawLen; + info = (byte*)XMALLOC(infoLen, ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (aadCopy == NULL) { - XFREE(info, ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (info == NULL) ret = MEMORY_E; - } } - if (ret == 0) { - XMEMCPY(aadCopy, aad, aadLen); - - /* seal the payload */ - ret = wc_HpkeSealBase(ech->hpke, ech->ephemeralKey, receiverPubkey, - info, (word32)infoLen, aadCopy, aadLen, ech->innerClientHello, - ech->innerClientHelloLen - ech->hpke->Nt, - ech->outerClientPayload); - - XFREE(info, ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(aadCopy, ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER); + /* puts the null byte in for me */ + XMEMCPY(info, (byte*)TLS_INFO_CONST_STRING, + TLS_INFO_CONST_STRING_SZ + 1); + XMEMCPY(info + TLS_INFO_CONST_STRING_SZ + 1, + ech->echConfig->raw, ech->echConfig->rawLen); + /* init the context for seal with info and keys */ + ret = wc_HpkeInitSealContext(ech->hpke, ech->hpkeContext, + ech->ephemeralKey, receiverPubkey, info, infoLen); } } - + if (ret == 0) { + /* make a copy of the aad since we overwrite it */ + aadCopy = (byte*)XMALLOC(aadLen, ech->hpke->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (aadCopy == NULL) { + ret = MEMORY_E; + } + } + if (ret == 0) { + XMEMCPY(aadCopy, aad, aadLen); + /* seal the payload with context */ + ret = wc_HpkeContextSealBase(ech->hpke, ech->hpkeContext, aadCopy, + aadLen, ech->innerClientHello, + ech->innerClientHelloLen - ech->hpke->Nt, ech->outerClientPayload); + } + if (info != NULL) + XFREE(info, ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (aadCopy != NULL) + XFREE(aadCopy, ech->hpke->heap, DYNAMIC_TYPE_TMP_BUFFER); if (receiverPubkey != NULL) wc_HpkeFreeKey(ech->hpke, ech->hpke->kem, receiverPubkey, ech->hpke->heap); - return ret; } @@ -13014,7 +13865,7 @@ static int TLSX_GetSize(TLSX* list, byte* semaphore, byte msgType, #endif /* WOLFSSL_DTLS_CID */ #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) case TLSX_ECH: - length += ECH_GET_SIZE((WOLFSSL_ECH*)extension->data); + length += ECH_GET_SIZE((WOLFSSL_ECH*)extension->data, msgType); break; #endif default: @@ -13264,7 +14115,7 @@ static int TLSX_Write(TLSX* list, byte* output, byte* semaphore, #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) case TLSX_ECH: WOLFSSL_MSG("ECH extension to write"); - ret = ECH_WRITE((WOLFSSL_ECH*)extension->data, + ret = ECH_WRITE((WOLFSSL_ECH*)extension->data, msgType, output + offset, &offset); break; #endif @@ -13481,9 +14332,9 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) #endif #endif -#ifdef WOLFSSL_HAVE_KYBER +#ifdef WOLFSSL_HAVE_MLKEM #ifndef WOLFSSL_NO_ML_KEM -#ifdef WOLFSSL_WC_KYBER +#ifdef WOLFSSL_WC_MLKEM #ifndef WOLFSSL_NO_ML_KEM_512 if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_512, @@ -13491,6 +14342,11 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_ML_KEM_512, ssl->heap); + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_ML_KEM_512, + ssl->heap); + #endif #endif #ifndef WOLFSSL_NO_ML_KEM_768 if (ret == WOLFSSL_SUCCESS) @@ -13499,6 +14355,19 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P384_ML_KEM_768, ssl->heap); + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_ML_KEM_768, + ssl->heap); + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_ML_KEM_768, + ssl->heap); + #endif + #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X448_ML_KEM_768, + ssl->heap); + #endif #endif #ifndef WOLFSSL_NO_ML_KEM_1024 if (ret == WOLFSSL_SUCCESS) @@ -13507,6 +14376,9 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_ML_KEM_1024, ssl->heap); + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P384_ML_KEM_1024, + ssl->heap); #endif #elif defined(HAVE_LIBOQS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_ML_KEM_512, ssl->heap); @@ -13522,13 +14394,32 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P384_ML_KEM_768, ssl->heap); + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_ML_KEM_768, + ssl->heap); if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_ML_KEM_1024, ssl->heap); + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P384_ML_KEM_1024, + ssl->heap); + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_ML_KEM_512, + ssl->heap); + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_ML_KEM_768, + ssl->heap); + #endif + #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X448_ML_KEM_768, + ssl->heap); + #endif #endif /* HAVE_LIBOQS */ #endif /* !WOLFSSL_NO_ML_KEM */ -#ifdef WOLFSSL_KYBER_ORIGINAL -#ifdef WOLFSSL_WC_KYBER +#ifdef WOLFSSL_MLKEM_KYBER +#ifdef WOLFSSL_WC_MLKEM #ifdef WOLFSSL_KYBER512 if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_KYBER_LEVEL1, @@ -13536,6 +14427,11 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_KYBER_LEVEL1, ssl->heap); + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_KYBER_LEVEL1, + ssl->heap); + #endif #endif #ifdef WOLFSSL_KYBER768 if (ret == WOLFSSL_SUCCESS) @@ -13544,6 +14440,19 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P384_KYBER_LEVEL3, ssl->heap); + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_KYBER_LEVEL3, + ssl->heap); + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_KYBER_LEVEL3, + ssl->heap); + #endif + #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X448_KYBER_LEVEL3, + ssl->heap); + #endif #endif #ifdef WOLFSSL_KYBER1024 if (ret == WOLFSSL_SUCCESS) @@ -13567,12 +14476,28 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P384_KYBER_LEVEL3, ssl->heap); + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P256_KYBER_LEVEL3, + ssl->heap); if (ret == WOLFSSL_SUCCESS) ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_P521_KYBER_LEVEL5, ssl->heap); + #if defined(HAVE_CURVE25519) && ECC_MIN_KEY_SZ <= 256 + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_KYBER_LEVEL1, + ssl->heap); + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X25519_KYBER_LEVEL3, + ssl->heap); + #endif + #if defined(HAVE_CURVE448) && ECC_MIN_KEY_SZ <= 448 + if (ret == WOLFSSL_SUCCESS) + ret = TLSX_UseSupportedCurve(extensions, WOLFSSL_X448_KYBER_LEVEL3, + ssl->heap); + #endif #endif /* HAVE_LIBOQS */ -#endif /* WOLFSSL_KYBER_ORIGINAL */ -#endif /* WOLFSSL_HAVE_KYBER */ +#endif /* WOLFSSL_MLKEM_KYBER */ +#endif /* WOLFSSL_HAVE_MLKEM */ (void)ssl; (void)extensions; @@ -14048,7 +14973,9 @@ static int TLSX_GetSizeWithEch(WOLFSSL* ssl, byte* semaphore, byte msgType, echX = TLSX_Find(ssl->ctx->extensions, TLSX_ECH); /* if type is outer change sni to public name */ - if (echX != NULL && ((WOLFSSL_ECH*)echX->data)->type == ECH_TYPE_OUTER) { + if (echX != NULL && ((WOLFSSL_ECH*)echX->data)->type == ECH_TYPE_OUTER && + (ssl->options.echAccepted || + ((WOLFSSL_ECH*)echX->data)->innerCount == 0)) { if (ssl->extensions) { serverNameX = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME); @@ -14255,7 +15182,9 @@ static int TLSX_WriteWithEch(WOLFSSL* ssl, byte* output, byte* semaphore, } /* if type is outer change sni to public name */ - if (echX != NULL && ((WOLFSSL_ECH*)echX->data)->type == ECH_TYPE_OUTER) { + if (echX != NULL && ((WOLFSSL_ECH*)echX->data)->type == ECH_TYPE_OUTER && + (ssl->options.echAccepted || + ((WOLFSSL_ECH*)echX->data)->innerCount == 0)) { if (ssl->extensions) { serverNameX = TLSX_Find(ssl->extensions, TLSX_SERVER_NAME); @@ -14315,31 +15244,36 @@ static int TLSX_WriteWithEch(WOLFSSL* ssl, byte* output, byte* semaphore, msgType, pOffset); } - if (echX != NULL) { - /* turn off and write it last */ - TURN_OFF(semaphore, TLSX_ToSemaphore(echX->type)); - } + /* only write if have a shot at acceptance */ + if (echX != NULL && + (ssl->options.echAccepted || + ((WOLFSSL_ECH*)echX->data)->innerCount == 0)) { + if (echX != NULL) { + /* turn off and write it last */ + TURN_OFF(semaphore, TLSX_ToSemaphore(echX->type)); + } - if (ret == 0 && ssl->extensions) { - ret = TLSX_Write(ssl->extensions, output + *pOffset, semaphore, - msgType, pOffset); - } + if (ret == 0 && ssl->extensions) { + ret = TLSX_Write(ssl->extensions, output + *pOffset, semaphore, + msgType, pOffset); + } - if (ret == 0 && ssl->ctx && ssl->ctx->extensions) { - ret = TLSX_Write(ssl->ctx->extensions, output + *pOffset, semaphore, - msgType, pOffset); - } + if (ret == 0 && ssl->ctx && ssl->ctx->extensions) { + ret = TLSX_Write(ssl->ctx->extensions, output + *pOffset, semaphore, + msgType, pOffset); + } - if (serverNameX != NULL) { - /* remove the public name SNI */ - TLSX_Remove(extensions, TLSX_SERVER_NAME, ssl->heap); + if (serverNameX != NULL) { + /* remove the public name SNI */ + TLSX_Remove(extensions, TLSX_SERVER_NAME, ssl->heap); - ret = TLSX_UseSNI(extensions, WOLFSSL_SNI_HOST_NAME, tmpServerName, - XSTRLEN(tmpServerName), ssl->heap); + ret = TLSX_UseSNI(extensions, WOLFSSL_SNI_HOST_NAME, tmpServerName, + XSTRLEN(tmpServerName), ssl->heap); - /* restore the inner server name */ - if (ret == WOLFSSL_SUCCESS) - ret = 0; + /* restore the inner server name */ + if (ret == WOLFSSL_SUCCESS) + ret = 0; + } } #ifdef WOLFSSL_SMALL_STACK @@ -14557,6 +15491,10 @@ int TLSX_GetResponseSize(WOLFSSL* ssl, byte msgType, word16* pLength) #ifdef WOLFSSL_SEND_HRR_COOKIE TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_COOKIE)); #endif +#ifdef HAVE_ECH + /* send the special confirmation */ + TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_ECH)); +#endif break; #endif @@ -14700,6 +15638,10 @@ int TLSX_WriteResponse(WOLFSSL *ssl, byte* output, byte msgType, word16* pOffset TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_KEY_SHARE)); } #endif +#ifdef HAVE_ECH + /* send the special confirmation */ + TURN_OFF(semaphore, TLSX_ToSemaphore(TLSX_ECH)); +#endif /* Cookie is written below as last extension. */ break; #endif diff --git a/src/src/tls13.c b/src/src/tls13.c index a1a1783..6efe446 100644 --- a/src/src/tls13.c +++ b/src/src/tls13.c @@ -1,6 +1,6 @@ /* tls13.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include /* * BUILD_GCM @@ -88,16 +89,7 @@ * Default behavior is to return a signed 64-bit value. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#ifdef WOLFSSL_TLS13 -#ifdef HAVE_SESSION_TICKET - #include -#endif +#if !defined(NO_TLS) && defined(WOLFSSL_TLS13) #ifndef WOLFCRYPT_ONLY @@ -180,11 +172,14 @@ static const byte dtls13ProtocolLabel[DTLS13_PROTOCOL_LABEL_SZ + 1] = "dtls13"; #endif /* WOLFSSL_DTLS13 */ #if defined(HAVE_ECH) -#define ECH_ACCEPT_CONFIRMATION_SZ 8 #define ECH_ACCEPT_CONFIRMATION_LABEL_SZ 23 +#define ECH_HRR_ACCEPT_CONFIRMATION_LABEL_SZ 27 static const byte echAcceptConfirmationLabel[ECH_ACCEPT_CONFIRMATION_LABEL_SZ + 1] = "ech accept confirmation"; +static const byte + echHrrAcceptConfirmationLabel[ECH_HRR_ACCEPT_CONFIRMATION_LABEL_SZ + 1] = + "hrr ech accept confirmation"; #endif #ifndef NO_CERTS @@ -1024,7 +1019,7 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen, ret = Tls13HKDFExpandLabel(ssl, firstExpand, hashLen, ssl->arrays->exporterSecret, hashLen, protocol, protocolLen, (byte*)label, (word32)labelLen, - emptyHash, hashLen, hashType); + emptyHash, hashLen, (int)hashType); if (ret != 0) return ret; @@ -1035,7 +1030,7 @@ int Tls13_Exporter(WOLFSSL* ssl, unsigned char *out, size_t outLen, ret = Tls13HKDFExpandLabel(ssl, out, (word32)outLen, firstExpand, hashLen, protocol, protocolLen, exporterLabel, EXPORTER_LABEL_SZ, - hashOut, hashLen, hashType); + hashOut, hashLen, (int)hashType); return ret; } @@ -4166,7 +4161,8 @@ int EchConfigGetSupportedCipherSuite(WOLFSSL_EchConfig* config) /* returns status after we hash the ech inner */ static int EchHashHelloInner(WOLFSSL* ssl, WOLFSSL_ECH* ech) { - int ret; + int ret = 0; + word32 realSz; HS_Hashes* tmpHashes; #ifdef WOLFSSL_DTLS13 byte falseHeader[DTLS13_HANDSHAKE_HEADER_SZ]; @@ -4176,29 +4172,51 @@ static int EchHashHelloInner(WOLFSSL* ssl, WOLFSSL_ECH* ech) if (ssl == NULL || ech == NULL) return BAD_FUNC_ARG; - - /* switch hsHashes to the ech version */ - InitHandshakeHashesAndCopy(ssl, ssl->hsHashes, &ssl->hsHashesEch); - - /* swap hsHashes so the regular hash functions work */ + realSz = ech->innerClientHelloLen - ech->paddingLen - ech->hpke->Nt; tmpHashes = ssl->hsHashes; - ssl->hsHashes = ssl->hsHashesEch; - - /* do the handshake header then the body */ - AddTls13HandShakeHeader(falseHeader, - ech->innerClientHelloLen - ech->paddingLen - ech->hpke->Nt, 0, 0, - client_hello, ssl); - ret = HashRaw(ssl, falseHeader, HANDSHAKE_HEADER_SZ); + ssl->hsHashes = NULL; + /* init the ech hashes */ + ret = InitHandshakeHashes(ssl); + if (ret == 0) { + ssl->hsHashesEch = ssl->hsHashes; + /* do the handshake header then the body */ + AddTls13HandShakeHeader(falseHeader, realSz, 0, 0, client_hello, ssl); + ret = HashRaw(ssl, falseHeader, HANDSHAKE_HEADER_SZ); + /* hash with inner */ + if (ret == 0) { + /* init hsHashesEchInner */ + if (ech->innerCount == 0) { + ssl->hsHashes = ssl->hsHashesEchInner; + ret = InitHandshakeHashes(ssl); + if (ret == 0) { + ssl->hsHashesEchInner = ssl->hsHashes; + ech->innerCount = 1; + } + } + else { + /* switch back to hsHashes so we have hrr -> echInner2 */ + ssl->hsHashes = tmpHashes; + ret = InitHandshakeHashesAndCopy(ssl, ssl->hsHashes, + &ssl->hsHashesEchInner); + } + if (ret == 0) { + ssl->hsHashes = ssl->hsHashesEchInner; + ret = HashRaw(ssl, falseHeader, HANDSHAKE_HEADER_SZ); + ssl->hsHashes = ssl->hsHashesEch; + } + } + } /* hash the body */ + if (ret == 0) + ret = HashRaw(ssl, ech->innerClientHello, realSz); + /* hash with inner */ if (ret == 0) { - ret = HashRaw(ssl, ech->innerClientHello, - (int)(ech->innerClientHelloLen - ech->paddingLen - ech->hpke->Nt)); + ssl->hsHashes = ssl->hsHashesEchInner; + ret = HashRaw(ssl, ech->innerClientHello, realSz); } - /* swap hsHashes back */ ssl->hsHashes = tmpHashes; - return ret; } #endif @@ -4443,23 +4461,26 @@ int SendTls13ClientHello(WOLFSSL* ssl) if (args->ech == NULL) return WOLFSSL_FATAL_ERROR; - /* set the type to inner */ - args->ech->type = ECH_TYPE_INNER; - args->preXLength = (int)args->length; + /* only prepare if we have a chance at acceptance */ + if (ssl->options.echAccepted || args->ech->innerCount == 0) { + /* set the type to inner */ + args->ech->type = ECH_TYPE_INNER; + args->preXLength = (int)args->length; - /* get size for inner */ - ret = TLSX_GetRequestSize(ssl, client_hello, &args->length); - if (ret != 0) - return ret; + /* get size for inner */ + ret = TLSX_GetRequestSize(ssl, client_hello, &args->length); + if (ret != 0) + return ret; - /* set the type to outer */ - args->ech->type = 0; - /* set innerClientHelloLen to ClientHelloInner + padding + tag */ - args->ech->paddingLen = 31 - ((args->length - 1) % 32); - args->ech->innerClientHelloLen = (word16)(args->length + - args->ech->paddingLen + args->ech->hpke->Nt); - /* set the length back to before we computed ClientHelloInner size */ - args->length = (word32)args->preXLength; + /* set the type to outer */ + args->ech->type = 0; + /* set innerClientHelloLen to ClientHelloInner + padding + tag */ + args->ech->paddingLen = 31 - ((args->length - 1) % 32); + args->ech->innerClientHelloLen = (word16)(args->length + + args->ech->paddingLen + args->ech->hpke->Nt); + /* set the length back to before we computed ClientHelloInner size */ + args->length = (word32)args->preXLength; + } } #endif @@ -4585,42 +4606,41 @@ int SendTls13ClientHello(WOLFSSL* ssl) #if defined(HAVE_ECH) /* write inner then outer */ - if (ssl->options.useEch == 1 && !ssl->options.disableECH) { + if (ssl->options.useEch == 1 && !ssl->options.disableECH && + (ssl->options.echAccepted || args->ech->innerCount == 0)) { /* set the type to inner */ args->ech->type = ECH_TYPE_INNER; - + /* innerClientHello may already exist from hrr, free if it does */ + if (args->ech->innerClientHello != NULL) { + XFREE(args->ech->innerClientHello, ssl->heap, + DYNAMIC_TYPE_TMP_BUFFER); + } /* allocate the inner */ args->ech->innerClientHello = (byte*)XMALLOC(args->ech->innerClientHelloLen - args->ech->hpke->Nt, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); if (args->ech->innerClientHello == NULL) return MEMORY_E; - /* set the padding bytes to 0 */ XMEMSET(args->ech->innerClientHello + args->ech->innerClientHelloLen - args->ech->hpke->Nt - args->ech->paddingLen, 0, args->ech->paddingLen); - /* copy the client hello to the ech innerClientHello, exclude record */ /* and handshake headers */ XMEMCPY(args->ech->innerClientHello, args->output + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ, args->idx - (RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ)); - /* copy the client random to inner */ XMEMCPY(ssl->arrays->clientRandomInner, ssl->arrays->clientRandom, RAN_LEN); - /* change the outer client random */ ret = wc_RNG_GenerateBlock(ssl->rng, args->output + args->clientRandomOffset, RAN_LEN); if (ret != 0) return ret; - /* copy the new client random */ XMEMCPY(ssl->arrays->clientRandom, args->output + args->clientRandomOffset, RAN_LEN); - /* write the extensions for inner */ args->length = 0; ret = TLSX_WriteRequest(ssl, args->ech->innerClientHello + args->idx - @@ -4628,7 +4648,6 @@ int SendTls13ClientHello(WOLFSSL* ssl) &args->length); if (ret != 0) return ret; - /* set the type to outer */ args->ech->type = 0; } @@ -4645,7 +4664,8 @@ int SendTls13ClientHello(WOLFSSL* ssl) #if defined(HAVE_ECH) /* encrypt and pack the ech innerClientHello */ - if (ssl->options.useEch == 1 && !ssl->options.disableECH) { + if (ssl->options.useEch == 1 && !ssl->options.disableECH && + (ssl->options.echAccepted || args->ech->innerCount == 0)) { ret = TLSX_FinalizeEch(args->ech, args->output + RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ, (word32)(args->sendSz - (RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ))); @@ -4675,7 +4695,8 @@ int SendTls13ClientHello(WOLFSSL* ssl) { #if defined(HAVE_ECH) /* compute the inner hash */ - if (ssl->options.useEch == 1 && !ssl->options.disableECH) + if (ssl->options.useEch == 1 && !ssl->options.disableECH && + (ssl->options.echAccepted || args->ech->innerCount == 0)) ret = EchHashHelloInner(ssl, args->ech); #endif /* compute the outer hash */ @@ -4768,15 +4789,15 @@ static int Dtls13ClientDoDowngrade(WOLFSSL* ssl) #endif /* WOLFSSL_DTLS13 && !WOLFSSL_NO_CLIENT*/ #if defined(HAVE_ECH) -/* check if the server accepted ech or not */ -static int EchCheckAcceptance(WOLFSSL* ssl, const byte* input, - int serverRandomOffset, int helloSz) +/* check if the server accepted ech or not, must be run after an hsHashes + * restart */ +static int EchCheckAcceptance(WOLFSSL* ssl, byte* label, word16 labelSz, + const byte* input, int acceptOffset, int helloSz) { int ret = 0; int digestType = 0; int digestSize = 0; HS_Hashes* tmpHashes; - HS_Hashes* acceptHashes; byte zeros[WC_MAX_DIGEST_SIZE]; byte transcriptEchConf[WC_MAX_DIGEST_SIZE]; byte expandLabelPrk[WC_MAX_DIGEST_SIZE]; @@ -4785,22 +4806,20 @@ static int EchCheckAcceptance(WOLFSSL* ssl, const byte* input, XMEMSET(transcriptEchConf, 0, sizeof(transcriptEchConf)); XMEMSET(expandLabelPrk, 0, sizeof(expandLabelPrk)); XMEMSET(acceptConfirmation, 0, sizeof(acceptConfirmation)); - /* copy ech hashes to accept */ - ret = InitHandshakeHashesAndCopy(ssl, ssl->hsHashesEch, &acceptHashes); - /* swap hsHashes to acceptHashes */ + /* store so we can restore regardless of the outcome */ tmpHashes = ssl->hsHashes; - ssl->hsHashes = acceptHashes; + /* swap hsHashes to hsHashesEch */ + ssl->hsHashes = ssl->hsHashesEch; /* hash up to the last 8 bytes */ - if (ret == 0) - ret = HashRaw(ssl, input, serverRandomOffset + RAN_LEN - - ECH_ACCEPT_CONFIRMATION_SZ); + ret = HashRaw(ssl, input, acceptOffset); /* hash 8 zeros */ if (ret == 0) ret = HashRaw(ssl, zeros, ECH_ACCEPT_CONFIRMATION_SZ); /* hash the rest of the hello */ if (ret == 0) { - ret = HashRaw(ssl, input + serverRandomOffset + RAN_LEN, - helloSz + HANDSHAKE_HEADER_SZ - (serverRandomOffset + RAN_LEN)); + ret = HashRaw(ssl, input + acceptOffset + ECH_ACCEPT_CONFIRMATION_SZ, + helloSz + HANDSHAKE_HEADER_SZ - + (acceptOffset + ECH_ACCEPT_CONFIRMATION_SZ)); } /* get the modified transcript hash */ if (ret == 0) @@ -4856,97 +4875,83 @@ static int EchCheckAcceptance(WOLFSSL* ssl, const byte* input, /* tls expand with the confirmation label */ if (ret == 0) { PRIVATE_KEY_UNLOCK(); - ret = Tls13HKDFExpandKeyLabel(ssl, - acceptConfirmation, ECH_ACCEPT_CONFIRMATION_SZ, - expandLabelPrk, (word32)digestSize, - tls13ProtocolLabel, TLS13_PROTOCOL_LABEL_SZ, - echAcceptConfirmationLabel, ECH_ACCEPT_CONFIRMATION_LABEL_SZ, - transcriptEchConf, (word32)digestSize, digestType, WOLFSSL_SERVER_END); + ret = Tls13HKDFExpandKeyLabel(ssl, acceptConfirmation, + ECH_ACCEPT_CONFIRMATION_SZ, expandLabelPrk, (word32)digestSize, + tls13ProtocolLabel, TLS13_PROTOCOL_LABEL_SZ, label, labelSz, + transcriptEchConf, (word32)digestSize, digestType, + WOLFSSL_SERVER_END); PRIVATE_KEY_LOCK(); } if (ret == 0) { /* last 8 bytes should match our expand output */ - ret = XMEMCMP(acceptConfirmation, - ssl->arrays->serverRandom + RAN_LEN - ECH_ACCEPT_CONFIRMATION_SZ, + ret = XMEMCMP(acceptConfirmation, input + acceptOffset, ECH_ACCEPT_CONFIRMATION_SZ); /* ech accepted */ if (ret == 0) { - /* use the inner random for client random */ - XMEMCPY(ssl->arrays->clientRandom, ssl->arrays->clientRandomInner, - RAN_LEN); - /* switch back to original hsHashes to free */ + /* set echAccepted to 1 */ + ssl->options.echAccepted = 1; + /* free hsHashes and go with inner */ ssl->hsHashes = tmpHashes; - /* set the final hsHashes to the ech hashes */ - tmpHashes = ssl->hsHashesEch; + FreeHandshakeHashes(ssl); + ssl->hsHashes = ssl->hsHashesEch; + tmpHashes = ssl->hsHashesEchInner; + ssl->hsHashesEchInner = NULL; } /* ech rejected */ else { - /* switch to hsHashesEch to free */ - ssl->hsHashes = ssl->hsHashesEch; + /* set echAccepted to 0, needed in case HRR */ + ssl->options.echAccepted = 0; + /* free inner since we're continuing with outer */ + ssl->hsHashes = ssl->hsHashesEchInner; + FreeHandshakeHashes(ssl); + ssl->hsHashesEchInner = NULL; } - /* free hsHashes */ - FreeHandshakeHashes(ssl); - /* set hsHashesEch to NULL to avoid double free */ - ssl->hsHashesEch = NULL; /* continue with outer if we failed to verify ech was accepted */ ret = 0; } - /* switch to acceptHashes */ - ssl->hsHashes = acceptHashes; - /* free acceptHashes */ FreeHandshakeHashes(ssl); - /* swap to tmp, will ech if accepted, hsHashes if rejected */ + /* set hsHashesEch to NULL to avoid double free */ + ssl->hsHashesEch = NULL; + /* swap to tmp, will be inner if accepted, hsHashes if rejected */ ssl->hsHashes = tmpHashes; return ret; } -/* replace the last 8 bytes of the server random with the ech acceptance - * parameter, return status */ -static int EchWriteAcceptance(WOLFSSL* ssl, byte* output, - int serverRandomOffset, int helloSz) +/* replace the last acceptance field for either sever hello or hrr with the ech + * acceptance parameter, return status */ +static int EchWriteAcceptance(WOLFSSL* ssl, byte* label, word16 labelSz, + byte* output, int acceptOffset, int helloSz, byte msgType) { int ret = 0; int digestType = 0; int digestSize = 0; HS_Hashes* tmpHashes = NULL; - HS_Hashes* acceptHashes = NULL; byte zeros[WC_MAX_DIGEST_SIZE]; byte transcriptEchConf[WC_MAX_DIGEST_SIZE]; byte expandLabelPrk[WC_MAX_DIGEST_SIZE]; XMEMSET(zeros, 0, sizeof(zeros)); XMEMSET(transcriptEchConf, 0, sizeof(transcriptEchConf)); XMEMSET(expandLabelPrk, 0, sizeof(expandLabelPrk)); - - /* copy ech hashes to accept */ - ret = InitHandshakeHashesAndCopy(ssl, ssl->hsHashes, &acceptHashes); - - /* swap hsHashes to acceptHashes */ + /* store so we can restore regardless of the outcome */ tmpHashes = ssl->hsHashes; - ssl->hsHashes = acceptHashes; - - /* hash up to the last 8 bytes */ - if (ret == 0) - ret = HashRaw(ssl, output, serverRandomOffset + RAN_LEN - - ECH_ACCEPT_CONFIRMATION_SZ); - + ssl->hsHashes = ssl->hsHashesEch; + /* hash up to the acceptOffset */ + ret = HashRaw(ssl, output, acceptOffset); /* hash 8 zeros */ if (ret == 0) - ret = HashRaw(ssl, zeros, ECH_ACCEPT_CONFIRMATION_SZ); - + ret = HashRaw(ssl, zeros, ECH_ACCEPT_CONFIRMATION_SZ); /* hash the rest of the hello */ - if (ret == 0) - ret = HashRaw(ssl, output + serverRandomOffset + RAN_LEN, - helloSz - (serverRandomOffset + RAN_LEN)); - + if (ret == 0) { + ret = HashRaw(ssl, output + acceptOffset + ECH_ACCEPT_CONFIRMATION_SZ, + helloSz - (acceptOffset + ECH_ACCEPT_CONFIRMATION_SZ)); + } /* get the modified transcript hash */ if (ret == 0) ret = GetMsgHash(ssl, transcriptEchConf); - if (ret > 0) ret = 0; - /* pick the right type and size based on mac_algorithm */ - if (ret == 0) + if (ret == 0) { switch (ssl->specs.mac_algorithm) { #ifndef NO_SHA256 case sha256_mac: @@ -4976,7 +4981,7 @@ static int EchWriteAcceptance(WOLFSSL* ssl, byte* output, ret = WOLFSSL_FATAL_ERROR; break; } - + } /* extract clientRandom with a key of all zeros */ if (ret == 0) { PRIVATE_KEY_UNLOCK(); @@ -4991,29 +4996,23 @@ static int EchWriteAcceptance(WOLFSSL* ssl, byte* output, #endif PRIVATE_KEY_LOCK(); } - /* tls expand with the confirmation label */ if (ret == 0) { PRIVATE_KEY_UNLOCK(); - ret = Tls13HKDFExpandKeyLabel(ssl, - output + serverRandomOffset + RAN_LEN - ECH_ACCEPT_CONFIRMATION_SZ, - ECH_ACCEPT_CONFIRMATION_SZ, - expandLabelPrk, (word32)digestSize, - tls13ProtocolLabel, TLS13_PROTOCOL_LABEL_SZ, - echAcceptConfirmationLabel, ECH_ACCEPT_CONFIRMATION_LABEL_SZ, - transcriptEchConf, (word32)digestSize, digestType, WOLFSSL_SERVER_END); + ret = Tls13HKDFExpandKeyLabel(ssl, output + acceptOffset, + ECH_ACCEPT_CONFIRMATION_SZ, expandLabelPrk, (word32)digestSize, + tls13ProtocolLabel, TLS13_PROTOCOL_LABEL_SZ, label, labelSz, + transcriptEchConf, (word32)digestSize, digestType, + WOLFSSL_SERVER_END); PRIVATE_KEY_LOCK(); } - - if (ret == 0) - XMEMCPY(ssl->arrays->serverRandom, output + serverRandomOffset, - RAN_LEN); - - /* free acceptHashes */ + /* mark that ech was accepted */ + if (ret == 0 && msgType != hello_retry_request) + ssl->options.echAccepted = 1; + /* free hsHashesEch, if this is an HRR we will start at client hello 2*/ FreeHandshakeHashes(ssl); - + ssl->hsHashesEch = NULL; ssl->hsHashes = tmpHashes; - return ret; } #endif @@ -5039,7 +5038,10 @@ typedef struct Dsh13Args { byte sessIdSz; byte extMsgType; #if defined(HAVE_ECH) - int serverRandomOffset; + TLSX* echX; + byte* acceptLabel; + word32 acceptOffset; + word16 acceptLabelSz; #endif } Dsh13Args; @@ -5196,7 +5198,8 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* Server random - keep for debugging. */ XMEMCPY(ssl->arrays->serverRandom, input + args->idx, RAN_LEN); #if defined(HAVE_ECH) - args->serverRandomOffset = (int)args->idx; + /* last 8 bytes of server random */ + args->acceptOffset = args->idx + RAN_LEN - ECH_ACCEPT_CONFIRMATION_SZ; #endif args->idx += RAN_LEN; @@ -5492,15 +5495,6 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (ret != 0) return ret; -#if defined(HAVE_ECH) - /* check for acceptConfirmation and HashInput with 8 0 bytes */ - if (ssl->options.useEch == 1 && !ssl->options.disableECH) { - ret = EchCheckAcceptance(ssl, input, args->serverRandomOffset, (int)helloSz); - if (ret != 0) - return ret; - } -#endif - #ifdef HAVE_NULL_CIPHER if (ssl->options.cipherSuite0 == ECC_BYTE && (ssl->options.cipherSuite == TLS_SHA256_SHA256 || @@ -5538,6 +5532,36 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return MATCH_SUITE_ERROR; } +#if defined(HAVE_ECH) + /* check for acceptConfirmation, must be done after hashes restart */ + if (ssl->options.useEch == 1) { + args->echX = TLSX_Find(ssl->extensions, TLSX_ECH); + /* account for hrr extension instead of server random */ + if (args->extMsgType == hello_retry_request) { + args->acceptOffset = + (word32)(((WOLFSSL_ECH*)args->echX->data)->confBuf - input); + args->acceptLabel = (byte*)echHrrAcceptConfirmationLabel; + args->acceptLabelSz = ECH_HRR_ACCEPT_CONFIRMATION_LABEL_SZ; + } + else { + args->acceptLabel = (byte*)echAcceptConfirmationLabel; + args->acceptLabelSz = ECH_ACCEPT_CONFIRMATION_LABEL_SZ; + } + /* check acceptance */ + if (ret == 0) { + ret = EchCheckAcceptance(ssl, args->acceptLabel, + args->acceptLabelSz, input, args->acceptOffset, helloSz); + } + if (ret != 0) + return ret; + /* use the inner random for client random */ + if (args->extMsgType != hello_retry_request) { + XMEMCPY(ssl->arrays->clientRandom, ssl->arrays->clientRandomInner, + RAN_LEN); + } + } +#endif /* HAVE_ECH */ + if (*extMsgType == server_hello) { #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) PreSharedKey* psk = NULL; @@ -5556,6 +5580,9 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return ret; ssl->options.pskNegotiated = 1; } +#else + /* no resumption possible */ + ssl->options.resuming = 0; #endif /* sanity check on PSK / KSE */ @@ -6674,7 +6701,6 @@ static int DoTls13SupportedVersions(WOLFSSL* ssl, const byte* input, word32 i, typedef struct Dch13Args { ProtocolVersion pv; - Suites* clSuites; word32 idx; word32 begin; int usingPSK; @@ -6682,17 +6708,17 @@ typedef struct Dch13Args { static void FreeDch13Args(WOLFSSL* ssl, void* pArgs) { - Dch13Args* args = (Dch13Args*)pArgs; - - (void)ssl; - - if (args && args->clSuites) { - XFREE(args->clSuites, ssl->heap, DYNAMIC_TYPE_SUITES); - args->clSuites = NULL; + /* openssl compat builds hang on to the client suites until WOLFSSL object + * is destroyed */ +#ifndef OPENSSL_EXTRA + if (ssl->clSuites) { + XFREE(ssl->clSuites, ssl->heap, DYNAMIC_TYPE_SUITES); + ssl->clSuites = NULL; } -#ifdef OPENSSL_EXTRA - ssl->clSuites = NULL; #endif + (void)ssl; + (void)pArgs; + } int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, @@ -6707,6 +6733,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif #if defined(HAVE_ECH) TLSX* echX = NULL; + HS_Hashes* tmpHashes; #endif WOLFSSL_START(WC_FUNC_CLIENT_HELLO_DO); @@ -6902,28 +6929,31 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif /* WOLFSSL_DTLS13 */ - args->clSuites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap, + XFREE(ssl->clSuites, ssl->heap, DYNAMIC_TYPE_SUITES); + ssl->clSuites = (Suites*)XMALLOC(sizeof(Suites), ssl->heap, DYNAMIC_TYPE_SUITES); - if (args->clSuites == NULL) { + if (ssl->clSuites == NULL) { ERROR_OUT(MEMORY_E, exit_dch); } /* Cipher suites */ if ((args->idx - args->begin) + OPAQUE16_LEN > helloSz) ERROR_OUT(BUFFER_ERROR, exit_dch); - ato16(&input[args->idx], &args->clSuites->suiteSz); + ato16(&input[args->idx], &ssl->clSuites->suiteSz); args->idx += OPAQUE16_LEN; - if ((args->clSuites->suiteSz % 2) != 0) { + if ((ssl->clSuites->suiteSz % 2) != 0) { ERROR_OUT(INVALID_PARAMETER, exit_dch); } /* suites and compression length check */ - if ((args->idx - args->begin) + args->clSuites->suiteSz + OPAQUE8_LEN > helloSz) + if ((args->idx - args->begin) + ssl->clSuites->suiteSz + OPAQUE8_LEN > + helloSz) { ERROR_OUT(BUFFER_ERROR, exit_dch); - if (args->clSuites->suiteSz > WOLFSSL_MAX_SUITE_SZ) + } + if (ssl->clSuites->suiteSz > WOLFSSL_MAX_SUITE_SZ) ERROR_OUT(BUFFER_ERROR, exit_dch); - XMEMCPY(args->clSuites->suites, input + args->idx, args->clSuites->suiteSz); - args->idx += args->clSuites->suiteSz; - args->clSuites->hashSigAlgoSz = 0; + XMEMCPY(ssl->clSuites->suites, input + args->idx, ssl->clSuites->suiteSz); + args->idx += ssl->clSuites->suiteSz; + ssl->clSuites->hashSigAlgoSz = 0; /* Compression */ b = input[args->idx++]; @@ -6960,7 +6990,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, echX = TLSX_Find(ssl->extensions, TLSX_ECH); if (echX == NULL) - return WOLFSSL_FATAL_ERROR; + ERROR_OUT(WOLFSSL_FATAL_ERROR, exit_dch); ((WOLFSSL_ECH*)echX->data)->aad = input + HANDSHAKE_HEADER_SZ; ((WOLFSSL_ECH*)echX->data)->aadLen = helloSz; @@ -6969,7 +6999,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* Parse extensions */ if ((ret = TLSX_Parse(ssl, input + args->idx, totalExtSz, client_hello, - args->clSuites))) { + ssl->clSuites))) { goto exit_dch; } @@ -7027,9 +7057,25 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif +#if defined(HAVE_ECH) + /* hash clientHelloInner to hsHashesEch independently since it can't include + * the HRR */ + if (ssl->ctx->echConfigs != NULL && !ssl->options.disableECH) { + tmpHashes = ssl->hsHashes; + ssl->hsHashes = NULL; + ret = InitHandshakeHashes(ssl); + if (ret != 0) + goto exit_dch; + if ((ret = HashInput(ssl, input + args->begin, (int)helloSz)) != 0) + goto exit_dch; + ssl->hsHashesEch = ssl->hsHashes; + ssl->hsHashes = tmpHashes; + } +#endif + #if (defined(HAVE_SESSION_TICKET) || !defined(NO_PSK)) && \ defined(HAVE_TLS_EXTENSIONS) - ret = CheckPreSharedKeys(ssl, input + args->begin, helloSz, args->clSuites, + ret = CheckPreSharedKeys(ssl, input + args->begin, helloSz, ssl->clSuites, &args->usingPSK); if (ret != 0) goto exit_dch; @@ -7053,7 +7099,9 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, WOLFSSL_MSG("Client did not send a KeyShare extension"); ERROR_OUT(INCOMPLETE_DATA, exit_dch); } - if (TLSX_Find(ssl->extensions, TLSX_SIGNATURE_ALGORITHMS) == NULL) { + /* Can't check ssl->extensions here as SigAlgs are unconditionally + set by TLSX_PopulateExtensions */ + if (ssl->clSuites->hashSigAlgoSz == 0) { WOLFSSL_MSG("Client did not send a SignatureAlgorithms extension"); ERROR_OUT(INCOMPLETE_DATA, exit_dch); } @@ -7079,13 +7127,12 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, case TLS_ASYNC_DO: { #ifdef OPENSSL_EXTRA - ssl->clSuites = args->clSuites; if ((ret = CertSetupCbWrapper(ssl)) != 0) goto exit_dch; #endif #ifndef NO_CERTS if (!args->usingPSK) { - if ((ret = MatchSuite(ssl, args->clSuites)) < 0) { + if ((ret = MatchSuite(ssl, ssl->clSuites)) < 0) { #ifdef WOLFSSL_ASYNC_CRYPT if (ret != WC_NO_ERR_TRACE(WC_PENDING_E)) #endif @@ -7178,7 +7225,7 @@ int DoTls13ClientHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ERROR_OUT(MATCH_SUITE_ERROR, exit_dch); } - #ifdef HAVE_SESSION_TICKET + #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) if (ssl->options.resuming) { ssl->options.resuming = 0; ssl->arrays->psk_keySz = 0; @@ -7306,7 +7353,9 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType) int sendSz; #if defined(HAVE_ECH) TLSX* echX = NULL; - word32 serverRandomOffset; + byte* acceptLabel = (byte*)echAcceptConfirmationLabel; + word32 acceptOffset; + word16 acceptLabelSz = ECH_ACCEPT_CONFIRMATION_LABEL_SZ; #endif WOLFSSL_START(WC_FUNC_SERVER_HELLO_SEND); @@ -7365,7 +7414,8 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType) } #if defined(HAVE_ECH) - serverRandomOffset = idx; + /* last 8 bytes of server random */ + acceptOffset = idx + RAN_LEN - ECH_ACCEPT_CONFIRMATION_SZ; #endif /* Store in SSL for debugging. */ @@ -7429,18 +7479,37 @@ int SendTls13ServerHello(WOLFSSL* ssl, byte extMsgType) #if defined(HAVE_ECH) if (ssl->ctx->echConfigs != NULL && !ssl->options.disableECH) { echX = TLSX_Find(ssl->extensions, TLSX_ECH); - if (echX == NULL) return WOLFSSL_FATAL_ERROR; - + /* use hrr offset */ + if (extMsgType == hello_retry_request) { + acceptOffset = + (word32)(((WOLFSSL_ECH*)echX->data)->confBuf - output); + acceptLabel = (byte*)echHrrAcceptConfirmationLabel; + acceptLabelSz = ECH_HRR_ACCEPT_CONFIRMATION_LABEL_SZ; + } /* replace the last 8 bytes of server random with the accept */ if (((WOLFSSL_ECH*)echX->data)->state == ECH_PARSED_INTERNAL) { - ret = EchWriteAcceptance(ssl, output + RECORD_HEADER_SZ, - serverRandomOffset - RECORD_HEADER_SZ, - sendSz - RECORD_HEADER_SZ); - - /* remove ech so we don't keep sending it in write */ - TLSX_Remove(&ssl->extensions, TLSX_ECH, ssl->heap); + if (ret == 0) { + ret = EchWriteAcceptance(ssl, acceptLabel, + acceptLabelSz, output + RECORD_HEADER_SZ, + acceptOffset - RECORD_HEADER_SZ, + sendSz - RECORD_HEADER_SZ, extMsgType); + } + if (extMsgType == hello_retry_request) { + /* reset the ech state for round 2 */ + ((WOLFSSL_ECH*)echX->data)->state = ECH_WRITE_NONE; + } + else { + if (ret == 0) { + /* update serverRandom on success */ + XMEMCPY(ssl->arrays->serverRandom, + output + acceptOffset - + (RAN_LEN -ECH_ACCEPT_CONFIRMATION_SZ), RAN_LEN); + } + /* remove ech so we don't keep sending it in write */ + TLSX_Remove(&ssl->extensions, TLSX_ECH, ssl->heap); + } } } #endif @@ -8012,9 +8081,8 @@ static WC_INLINE int DecodeTls13SigAlg(byte* input, byte* hashAlgo, else ret = INVALID_PARAMETER; break; -#if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) - case PQC_SA_MAJOR: #if defined(HAVE_FALCON) + case FALCON_SA_MAJOR: if (input[1] == FALCON_LEVEL1_SA_MINOR) { *hsType = falcon_level1_sa_algo; /* Hash performed as part of sign/verify operation. */ @@ -8025,8 +8093,11 @@ static WC_INLINE int DecodeTls13SigAlg(byte* input, byte* hashAlgo, *hashAlgo = sha512_mac; } else + ret = INVALID_PARAMETER; + break; #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) + case DILITHIUM_SA_MAJOR: if (input[1] == DILITHIUM_LEVEL2_SA_MINOR) { *hsType = dilithium_level2_sa_algo; /* Hash performed as part of sign/verify operation. */ @@ -8041,12 +8112,11 @@ static WC_INLINE int DecodeTls13SigAlg(byte* input, byte* hashAlgo, *hashAlgo = sha512_mac; } else -#endif /* HAVE_DILITHIUM */ { ret = INVALID_PARAMETER; } break; -#endif +#endif /* HAVE_DILITHIUM */ default: *hashAlgo = input[0]; *hsType = input[1]; @@ -8466,7 +8536,7 @@ static word32 NextCert(byte* data, word32 length, word32* idx) * offset index offset * returns Total number of bytes written. */ -static word32 WriteCSRToBuffer(WOLFSSL* ssl, DerBuffer** certExts, +static int WriteCSRToBuffer(WOLFSSL* ssl, DerBuffer** certExts, word16* extSz, word16 extSz_num) { int ret = 0; @@ -8484,7 +8554,7 @@ static word32 WriteCSRToBuffer(WOLFSSL* ssl, DerBuffer** certExts, if (csr) { for (extIdx = 0; extIdx < (word16)(extSz_num); extIdx++) { - tmpSz = TLSX_CSR_GetSize_ex(csr, 0, extIdx); + tmpSz = TLSX_CSR_GetSize_ex(csr, 0, (int)extIdx); if (tmpSz > (OPAQUE8_LEN + OPAQUE24_LEN) && certExts[extIdx] == NULL) { @@ -8519,7 +8589,7 @@ static word32 WriteCSRToBuffer(WOLFSSL* ssl, DerBuffer** certExts, /* chain cert empty extension size */ totalSz += OPAQUE16_LEN * extSz_num; } - return totalSz; + return (int)totalSz; } #endif /* HAVE_CERTIFICATE_STATUS_REQUEST */ /* Add certificate data and empty extension to output up to the fragment size. @@ -8622,6 +8692,7 @@ static int SendTls13Certificate(WOLFSSL* ssl) ssl->options.sendVerify = SEND_CERT; } wolfSSL_X509_free(x509); + x509 = NULL; wolfSSL_EVP_PKEY_free(pkey); } } @@ -9141,41 +9212,12 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) #endif #if defined(HAVE_FALCON) else if (ssl->hsType == DYNAMIC_TYPE_FALCON) { - falcon_key* fkey = (falcon_key*)ssl->hsKey; - byte level = 0; - if (wc_falcon_get_level(fkey, &level) != 0) { - ERROR_OUT(ALGO_ID_E, exit_scv); - } - if (level == 1) { - args->sigAlgo = falcon_level1_sa_algo; - } - else if (level == 5) { - args->sigAlgo = falcon_level5_sa_algo; - } - else { - ERROR_OUT(ALGO_ID_E, exit_scv); - } + args->sigAlgo = ssl->buffers.keyType; } #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) else if (ssl->hsType == DYNAMIC_TYPE_DILITHIUM) { - dilithium_key* fkey = (dilithium_key*)ssl->hsKey; - byte level = 0; - if (wc_dilithium_get_level(fkey, &level) != 0) { - ERROR_OUT(ALGO_ID_E, exit_scv); - } - if (level == 2) { - args->sigAlgo = dilithium_level2_sa_algo; - } - else if (level == 3) { - args->sigAlgo = dilithium_level3_sa_algo; - } - else if (level == 5) { - args->sigAlgo = dilithium_level5_sa_algo; - } - else { - ERROR_OUT(ALGO_ID_E, exit_scv); - } + args->sigAlgo = ssl->buffers.keyType; } #endif /* HAVE_DILITHIUM */ else { @@ -9459,9 +9501,11 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_SIGN) if (ssl->hsType == DYNAMIC_TYPE_DILITHIUM) { - ret = wc_dilithium_sign_msg(args->sigData, args->sigDataSz, - sigOut, &args->sigLen, - (dilithium_key*)ssl->hsKey, ssl->rng); + ret = wc_dilithium_sign_ctx_msg(NULL, 0, args->sigData, + args->sigDataSz, sigOut, + &args->sigLen, + (dilithium_key*)ssl->hsKey, + ssl->rng); args->length = (word16)args->sigLen; } #endif /* HAVE_DILITHIUM */ @@ -9553,11 +9597,9 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_SIGN) if (ssl->hsAltType == DYNAMIC_TYPE_DILITHIUM) { - ret = wc_dilithium_sign_msg(args->altSigData, - args->altSigDataSz, sigOut, - &args->altSigLen, - (dilithium_key*)ssl->hsAltKey, - ssl->rng); + ret = wc_dilithium_sign_ctx_msg(NULL, 0, args->altSigData, + args->altSigDataSz, sigOut, &args->altSigLen, + (dilithium_key*)ssl->hsAltKey, ssl->rng); } #endif /* HAVE_DILITHIUM */ @@ -10147,13 +10189,13 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, #endif #ifdef HAVE_DILITHIUM case dilithium_level2_sa_algo: - ret = decodeDilithiumKey(ssl, 2); + ret = decodeDilithiumKey(ssl, WC_ML_DSA_44); break; case dilithium_level3_sa_algo: - ret = decodeDilithiumKey(ssl, 3); + ret = decodeDilithiumKey(ssl, WC_ML_DSA_65); break; case dilithium_level5_sa_algo: - ret = decodeDilithiumKey(ssl, 5); + ret = decodeDilithiumKey(ssl, WC_ML_DSA_87); break; #endif #ifdef HAVE_FALCON @@ -10542,6 +10584,10 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, (void**)&ssl->peerFalconKey); ssl->peerFalconKeyPresent = 0; } + else if ((ret >= 0) && (res == 0)) { + WOLFSSL_MSG("Falcon signature verification failed"); + ret = SIG_VERIFY_E; + } } #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_VERIFY) @@ -10551,9 +10597,9 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, (ssl->peerDilithiumKeyPresent)) { int res = 0; WOLFSSL_MSG("Doing Dilithium peer cert verify"); - ret = wc_dilithium_verify_msg(sig, args->sigSz, - args->sigData, args->sigDataSz, - &res, ssl->peerDilithiumKey); + ret = wc_dilithium_verify_ctx_msg(sig, args->sigSz, NULL, 0, + args->sigData, args->sigDataSz, + &res, ssl->peerDilithiumKey); if ((ret >= 0) && (res == 1)) { /* CLIENT/SERVER: data verified with public key from @@ -10564,6 +10610,10 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, (void**)&ssl->peerDilithiumKey); ssl->peerDilithiumKeyPresent = 0; } + else if ((ret >= 0) && (res == 0)) { + WOLFSSL_MSG("Dilithium signature verification failed"); + ret = SIG_VERIFY_E; + } } #endif /* HAVE_DILITHIUM */ @@ -10644,6 +10694,10 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, (void**)&ssl->peerFalconKey); ssl->peerFalconKeyPresent = 0; } + else if ((ret >= 0) && (res == 0)) { + WOLFSSL_MSG("Falcon signature verification failed"); + ret = SIG_VERIFY_E; + } } #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) && !defined(WOLFSSL_DILITHIUM_NO_VERIFY) @@ -10653,9 +10707,10 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, (ssl->peerDilithiumKeyPresent)) { int res = 0; WOLFSSL_MSG("Doing Dilithium peer cert alt verify"); - ret = wc_dilithium_verify_msg(sig, args->altSignatureSz, - args->altSigData, args->altSigDataSz, - &res, ssl->peerDilithiumKey); + ret = wc_dilithium_verify_ctx_msg(sig, args->altSignatureSz, + NULL, 0, args->altSigData, + args->altSigDataSz, &res, + ssl->peerDilithiumKey); if ((ret >= 0) && (res == 1)) { /* CLIENT/SERVER: data verified with public key from @@ -10666,6 +10721,10 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, (void**)&ssl->peerDilithiumKey); ssl->peerDilithiumKeyPresent = 0; } + else if ((ret >= 0) && (res == 0)) { + WOLFSSL_MSG("Dilithium signature verification failed"); + ret = SIG_VERIFY_E; + } } #endif /* HAVE_DILITHIUM */ @@ -12692,16 +12751,15 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (echX != NULL && ((WOLFSSL_ECH*)echX->data)->state == ECH_WRITE_NONE) { - /* reset the inOutIdx to the outer start */ *inOutIdx = echInOutIdx; - /* call again with the inner hello */ - ret = DoTls13ClientHello(ssl, - ((WOLFSSL_ECH*)echX->data)->innerClientHello, - &echInOutIdx, - ((WOLFSSL_ECH*)echX->data)->innerClientHelloLen); - + if (ret == 0) { + ret = DoTls13ClientHello(ssl, + ((WOLFSSL_ECH*)echX->data)->innerClientHello, + &echInOutIdx, + ((WOLFSSL_ECH*)echX->data)->innerClientHelloLen); + } /* if the inner ech parsed successfully we have successfully * handled the hello and can skip the whole message */ if (ret == 0) @@ -13602,8 +13660,9 @@ int wolfSSL_UseKeyShare(WOLFSSL* ssl, word16 group) } #endif -#if defined(WOLFSSL_HAVE_KYBER) - if (WOLFSSL_NAMED_GROUP_IS_PQC(group)) { +#if defined(WOLFSSL_HAVE_MLKEM) + if (WOLFSSL_NAMED_GROUP_IS_PQC(group) || + WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(group)) { if (ssl->ctx != NULL && ssl->ctx->method != NULL && !IsAtLeastTLSv1_3(ssl->version)) { @@ -14884,7 +14943,7 @@ int wolfSSL_read_early_data(WOLFSSL* ssl, void* data, int sz, int* outSz) return WOLFSSL_FATAL_ERROR; } if (ssl->options.handShakeState == SERVER_FINISHED_COMPLETE) { - ret = ReceiveData(ssl, (byte*)data, sz, FALSE); + ret = ReceiveData(ssl, (byte*)data, (size_t)sz, FALSE); if (ret > 0) *outSz = ret; if (ssl->error == WC_NO_ERR_TRACE(ZERO_RETURN)) { @@ -15022,4 +15081,4 @@ int tls13ShowSecrets(WOLFSSL* ssl, int id, const unsigned char* secret, #endif /* !WOLFCRYPT_ONLY */ -#endif /* WOLFSSL_TLS13 */ +#endif /* !NO_TLS && WOLFSSL_TLS13 */ diff --git a/src/src/wolfio.c b/src/src/wolfio.c index 5e62e9f..0809734 100644 --- a/src/src/wolfio.c +++ b/src/src/wolfio.c @@ -1,6 +1,6 @@ /* wolfio.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -24,11 +24,7 @@ #define WOLFSSL_STRERROR_BUFFER_SIZE 256 #endif -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifndef WOLFCRYPT_ONLY @@ -41,11 +37,6 @@ #include #endif -#ifdef _WIN32_WCE - /* On WinCE winsock2.h must be included before windows.h for socket stuff */ - #include -#endif - #include #include #include @@ -56,7 +47,9 @@ int Nucleus_Net_Errno; #endif #if defined(USE_WOLFSSL_IO) || defined(HAVE_HTTP_CLIENT) - #ifndef USE_WINDOWS_API + #ifdef USE_WINDOWS_API + #include + #else #if defined(WOLFSSL_LWIP) && !defined(WOLFSSL_APACHE_MYNEWT) #elif defined(ARDUINO) #elif defined(FREESCALE_MQX) @@ -229,7 +222,7 @@ static int TranslateIoReturnCode(int err, SOCKET_T sd, int direction) else return WOLFSSL_CBIO_ERR_TIMEOUT; } -#endif +#endif /* SOCKET_ETIMEDOUT */ else if (err == SOCKET_ECONNRESET) { WOLFSSL_MSG("\tConnection reset"); @@ -248,7 +241,7 @@ static int TranslateIoReturnCode(int err, SOCKET_T sd, int direction) return WOLFSSL_CBIO_ERR_CONN_CLOSE; } -#if defined(_WIN32) +#if defined(_WIN32) && !defined(__WATCOMC__) strcpy_s(errstr, sizeof(errstr), "\tGeneral error: "); errstr_offset = strlen(errstr); FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, @@ -766,7 +759,7 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) else #endif /* WOLFSSL_DTLS13 */ timeout.tv_sec = dtls_timeout; - #endif + #endif /* USE_WINDOWS_API */ if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)) != 0) { WOLFSSL_MSG("setsockopt rcvtimeo failed"); @@ -863,22 +856,22 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) #ifndef WOLFSSL_PEER_ADDRESS_CHANGES else { ret = 0; -#ifdef WOLFSSL_RW_THREADED + #ifdef WOLFSSL_RW_THREADED if (wc_LockRwLock_Rd(&ssl->buffers.dtlsCtx.peerLock) != 0) return WOLFSSL_CBIO_ERR_GENERAL; -#endif + #endif /* WOLFSSL_RW_THREADED */ if (!sockAddrEqual(peer, peerSz, (SOCKADDR_S*)dtlsCtx->peer.sa, dtlsCtx->peer.sz)) { ret = WOLFSSL_CBIO_ERR_GENERAL; } -#ifdef WOLFSSL_RW_THREADED + #ifdef WOLFSSL_RW_THREADED if (wc_UnLockRwLock(&ssl->buffers.dtlsCtx.peerLock) != 0) return WOLFSSL_CBIO_ERR_GENERAL; -#endif + #endif /* WOLFSSL_RW_THREADED */ if (ret != 0) return ret; } -#endif +#endif /* !WOLFSSL_PEER_ADDRESS_CHANGES */ } #ifndef NO_ASN_TIME ssl->dtls_start_timeout = 0; @@ -1095,7 +1088,7 @@ int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx) return WOLFSSL_SUCCESS; } -#endif +#endif /* WOLFSSL_DTLS */ /* get the peer information in human readable form (ip, port, family) * default function assumes BSD sockets @@ -1254,6 +1247,9 @@ int wolfIO_SendTo(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int wr ret = ioctlsocket(sockfd, FIONBIO, &blocking); if (ret == SOCKET_ERROR) ret = WOLFSSL_FATAL_ERROR; + #elif defined(__WATCOMC__) && defined(__OS2__) + if (ioctl(sockfd, FIONBIO, &non_blocking) == -1) + ret = WOLFSSL_FATAL_ERROR; #else ret = fcntl(sockfd, F_GETFL, 0); if (ret >= 0) { @@ -1293,9 +1289,9 @@ int wolfIO_SendTo(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, int sz, int wr ret = select(nfds, &rfds, &wfds, NULL, &timeout); if (ret == 0) { - #ifdef DEBUG_HTTP + #ifdef DEBUG_HTTP fprintf(stderr, "Timeout: %d\n", ret); - #endif + #endif return HTTP_TIMEOUT; } else if (ret > 0) { @@ -1360,13 +1356,13 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec) #else HOSTENT *entry; #endif -#endif +#endif /* !WOLFSSL_USE_POPEN_HOST */ #ifdef WOLFSSL_IPV6 SOCKADDR_IN6 *sin; #else SOCKADDR_IN *sin; -#endif -#endif /* HAVE_SOCKADDR */ +#endif /* WOLFSSL_IPV6 */ +#endif /* HAVE_GETADDRINFO */ if (sockfd == NULL || ip == NULL) { return WOLFSSL_FATAL_ERROR; @@ -1377,8 +1373,8 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec) sockaddr_len = sizeof(SOCKADDR_IN6); #else sockaddr_len = sizeof(SOCKADDR_IN); -#endif -#endif +#endif /* WOLFSSL_IPV6 */ +#endif /* !HAVE_GETADDRINFO */ XMEMSET(&addr, 0, sizeof(addr)); #ifdef WOLFIO_DEBUG @@ -1496,7 +1492,8 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec) sin = (SOCKADDR_IN *)&addr; sin->sin_family = AF_INET; sin->sin_port = XHTONS(port); - XMEMCPY(&sin->sin_addr.s_addr, entry->h_addr_list[0], entry->h_length); + XMEMCPY(&sin->sin_addr.s_addr, entry->h_addr_list[0], + (size_t)entry->h_length); #endif } @@ -1530,7 +1527,7 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec) } #else (void)to_sec; -#endif +#endif /* HAVE_IO_TIMEOUT */ ret = connect(*sockfd, (SOCKADDR *)&addr, sockaddr_len); #ifdef HAVE_IO_TIMEOUT @@ -1549,7 +1546,7 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec) wolfIO_SetBlockingMode(*sockfd, 0); } } -#endif +#endif /* HAVE_IO_TIMEOUT */ if (ret != 0) { WOLFSSL_MSG("Responder tcp connect failed"); CloseSocket(*sockfd); @@ -2671,7 +2668,7 @@ int MicriumReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx) } } } - #endif + #endif /* WOLFSSL_DTLS */ ret = NetSock_RxData(sd, buf, sz, ssl->rflags, &err); if (ret < 0) { @@ -3423,7 +3420,7 @@ int wolfSSL_SetIO_LwIP(WOLFSSL* ssl, void* pcb, return ERR_OK; } -#endif +#endif /* WOLFSSL_LWIP_NATIVE */ #ifdef WOLFSSL_ISOTP static int isotp_send_single_frame(struct isotp_wolfssl_ctx *ctx, char *buf, @@ -3808,5 +3805,5 @@ int wolfSSL_SetIO_ISOTP(WOLFSSL *ssl, isotp_wolfssl_ctx *ctx, } return 0; } -#endif +#endif /* WOLFSSL_ISOTP */ #endif /* WOLFCRYPT_ONLY */ diff --git a/src/src/x509.c b/src/src/x509.c index d656815..62e3774 100644 --- a/src/src/x509.c +++ b/src/src/x509.c @@ -1,6 +1,6 @@ /* x509.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if !defined(WOLFSSL_X509_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN @@ -481,6 +476,24 @@ int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x, return WOLFSSL_FATAL_ERROR; } + +int wolfSSL_X509_OBJECT_set1_X509(WOLFSSL_X509_OBJECT *a, WOLFSSL_X509 *obj) +{ + WOLFSSL_STUB("wolfSSL_X509_OBJECT_set1_X509"); + (void)a; + (void)obj; + return 0; +} + +int wolfSSL_X509_OBJECT_set1_X509_CRL(WOLFSSL_X509_OBJECT *a, + WOLFSSL_X509_CRL *obj) +{ + WOLFSSL_STUB("wolfSSL_X509_OBJECT_set1_X509_CRL"); + (void)a; + (void)obj; + return 0; +} + #endif /* OPENSSL_ALL || OPENSSL_EXTRA */ #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || \ @@ -1181,12 +1194,24 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) } } - ext->obj->objSz = (unsigned int)objSz; if (((ext->obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) || (ext->obj->obj == NULL)) { - ext->obj->obj =(byte*)XREALLOC((byte*)ext->obj->obj, - ext->obj->objSz, - NULL,DYNAMIC_TYPE_ASN1); + #ifdef WOLFSSL_NO_REALLOC + byte* tmp = NULL; + + tmp = (byte*)XMALLOC(objSz, NULL, DYNAMIC_TYPE_ASN1); + if (tmp != NULL && ext->obj->obj != NULL) { + XMEMCPY(tmp, ext->obj->obj, ext->obj->objSz); + XFREE((byte*)ext->obj->obj, NULL, DYNAMIC_TYPE_ASN1); + } + else if (tmp == NULL) { + ext->obj->obj = tmp; + } + ext->obj->obj = tmp; + #else + ext->obj->obj = (byte*)XREALLOC((byte*)ext->obj->obj, objSz, + NULL, DYNAMIC_TYPE_ASN1); + #endif if (ext->obj->obj == NULL) { wolfSSL_X509_EXTENSION_free(ext); FreeDecodedCert(cert); @@ -1201,6 +1226,8 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) else { ext->obj->dynamic &= ~WOLFSSL_ASN1_DYNAMIC_DATA; } + ext->obj->objSz = (unsigned int)objSz; + /* Get OID from input and copy to ASN1_OBJECT buffer */ XMEMCPY(oidBuf+2, input+idx, length); XMEMCPY((byte*)ext->obj->obj, oidBuf, ext->obj->objSz); @@ -1663,10 +1690,10 @@ int wolfSSL_X509_EXTENSION_set_critical(WOLFSSL_X509_EXTENSION* ex, int crit) * Returns NULL on error or pointer to the v3_ext_method populated with * extension type-specific X509V3_EXT_* function(s). * - * NOTE: WC_NID_subject_key_identifier is currently the only extension implementing - * the X509V3_EXT_* functions, as it is the only type called directly by QT. The - * other extension types return a pointer to a v3_ext_method struct that - * contains only the NID. + * NOTE: WC_NID_subject_key_identifier is currently the only extension + * implementing the X509V3_EXT_* functions, as it is the only type called + * directly by QT. The other extension types return a pointer to a + * v3_ext_method struct that contains only the NID. */ #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L const WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex) @@ -1690,7 +1717,6 @@ WOLFSSL_v3_ext_method* wolfSSL_X509V3_EXT_get(WOLFSSL_X509_EXTENSION* ex) WOLFSSL_MSG("Failed to get nid from passed extension object"); return NULL; } - XMEMSET(&method, 0, sizeof(WOLFSSL_v3_ext_method)); switch (nid) { case WC_NID_basic_constraints: break; @@ -2333,7 +2359,11 @@ void* wolfSSL_X509_get_ext_d2i(const WOLFSSL_X509* x509, int nid, int* c, } dns = dns->next; - if (wolfSSL_sk_GENERAL_NAME_push(sk, gn) <= 0) { + /* Using wolfSSL_sk_insert to maintain backwards + * compatibility with earlier versions of _push API that + * pushed items to the start of the list instead of the + * end. */ + if (wolfSSL_sk_insert(sk, gn, 0) <= 0) { WOLFSSL_MSG("Error pushing ASN1 object onto stack"); goto err; } @@ -3569,9 +3599,8 @@ char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz) WOLFSSL_MSG("Memory error"); return NULL; } - if ((strLen = XSNPRINTF(str, (size_t)strSz, "%s=%s, ", sn, buf)) - >= strSz) - { + strLen = XSNPRINTF(str, (size_t)strSz, "%s=%s, ", sn, buf); + if ((strLen < 0) || (strLen >= strSz)) { WOLFSSL_MSG("buffer overrun"); XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER); return NULL; @@ -3587,8 +3616,8 @@ char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz) WOLFSSL_MSG("Memory error"); return NULL; } - if ((strLen = XSNPRINTF(str, (size_t)strSz, "%s=%s", sn, - buf)) >= strSz) { + strLen = XSNPRINTF(str, (size_t)strSz, "%s=%s", sn, buf); + if ((strLen < 0) || (strLen >= strSz)) { WOLFSSL_MSG("buffer overrun"); XFREE(str, NULL, DYNAMIC_TYPE_TMP_BUFFER); return NULL; @@ -4177,30 +4206,7 @@ int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, /* Return and remove the last x509 pushed on stack */ WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk) { - WOLFSSL_STACK* node; - WOLFSSL_X509* x509; - - if (sk == NULL) { - return NULL; - } - - node = sk->next; - x509 = sk->data.x509; - - if (node != NULL) { /* update sk and remove node from stack */ - sk->data.x509 = node->data.x509; - sk->next = node->next; - XFREE(node, NULL, DYNAMIC_TYPE_X509); - } - else { /* last x509 in stack */ - sk->data.x509 = NULL; - } - - if (sk->num > 0) { - sk->num--; - } - - return x509; + return (WOLFSSL_X509*)wolfSSL_sk_pop(sk); } /* Getter function for WOLFSSL_X509 pointer @@ -4227,38 +4233,7 @@ WOLFSSL_X509* wolfSSL_sk_X509_value(WOLF_STACK_OF(WOLFSSL_X509)* sk, int i) /* Return and remove the first x509 pushed on stack */ WOLFSSL_X509* wolfSSL_sk_X509_shift(WOLF_STACK_OF(WOLFSSL_X509)* sk) { - WOLFSSL_STACK* node; - WOLFSSL_X509* x509; - - if (sk == NULL) { - return NULL; - } - - node = sk->next; - x509 = sk->data.x509; - - if (node != NULL) { - /* walk to end of stack to first node pushed, and remove it */ - WOLFSSL_STACK* prevNode = sk; - - while (node->next != NULL) { - prevNode = node; - node = node->next; - } - - x509 = node->data.x509; - prevNode->next = NULL; - XFREE(node, NULL, DYNAMIC_TYPE_X509); - } - else { /* only one x509 in stack */ - sk->data.x509 = NULL; - } - - if (sk->num > 0) { - sk->num -= 1; - } - - return x509; + return (WOLFSSL_X509*)wolfSSL_sk_pop_node(sk, 0); } #endif /* OPENSSL_EXTRA */ @@ -4528,7 +4503,8 @@ WOLFSSL_GENERAL_NAME* wolfSSL_GENERAL_NAME_dup(WOLFSSL_GENERAL_NAME* gn) * WOLFSSL_SUCCESS otherwise. */ int wolfSSL_GENERAL_NAME_set0_othername(WOLFSSL_GENERAL_NAME* gen, - WOLFSSL_ASN1_OBJECT* oid, WOLFSSL_ASN1_TYPE* value) + WOLFSSL_ASN1_OBJECT* oid, + WOLFSSL_ASN1_TYPE* value) { WOLFSSL_ASN1_OBJECT *x = NULL; @@ -4570,17 +4546,7 @@ int wolfSSL_sk_GENERAL_NAME_push(WOLFSSL_GENERAL_NAMES* sk, */ WOLFSSL_GENERAL_NAME* wolfSSL_sk_GENERAL_NAME_value(WOLFSSL_STACK* sk, int idx) { - WOLFSSL_STACK* ret; - - if (sk == NULL) { - return NULL; - } - - ret = wolfSSL_sk_get_node(sk, idx); - if (ret != NULL) { - return ret->data.gn; - } - return NULL; + return (WOLFSSL_GENERAL_NAME*)wolfSSL_sk_value(sk, idx); } /* Gets the number of nodes in the stack @@ -4593,11 +4559,7 @@ int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk) { WOLFSSL_ENTER("wolfSSL_sk_GENERAL_NAME_num"); - if (sk == NULL) { - return WOLFSSL_FATAL_ERROR; - } - - return (int)sk->num; + return wolfSSL_sk_num(sk); } /* Allocates an empty GENERAL NAME stack */ @@ -5268,7 +5230,8 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) #endif /* !NO_FILESYSTEM */ static WOLFSSL_X509* loadX509orX509REQFromBuffer( - const unsigned char* buf, int sz, int format, int type) + const unsigned char* buf, int sz, int format, int type, + wc_pem_password_cb *cb, void *u) { int ret = 0; @@ -5278,8 +5241,15 @@ static WOLFSSL_X509* loadX509orX509REQFromBuffer( WOLFSSL_ENTER("wolfSSL_X509_load_certificate_ex"); if (format == WOLFSSL_FILETYPE_PEM) { + EncryptedInfo info; + XMEMSET(&info, 0, sizeof(EncryptedInfo)); + #ifdef WOLFSSL_ENCRYPTED_KEYS + info.passwd_cb = cb; + info.passwd_userdata = u; + #endif + #ifdef WOLFSSL_PEM_TO_DER - ret = PemToDer(buf, sz, type, &der, NULL, NULL, NULL); + ret = PemToDer(buf, sz, type, &der, NULL, &info, NULL); if (ret != 0) { FreeDer(&der); } @@ -5343,6 +5313,9 @@ static WOLFSSL_X509* loadX509orX509REQFromBuffer( WOLFSSL_ERROR(ret); } + /* unused parameter when built without WOLFSSL_ENCRYPTED_KEYS */ + (void)cb; + (void)u; return x509; } @@ -5350,7 +5323,7 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( const unsigned char* buf, int sz, int format) { return loadX509orX509REQFromBuffer(buf, sz, - format, CERT_TYPE); + format, CERT_TYPE, NULL, NULL); } #ifdef WOLFSSL_CERT_REQ @@ -5358,7 +5331,7 @@ WOLFSSL_X509* wolfSSL_X509_REQ_load_certificate_buffer( const unsigned char* buf, int sz, int format) { return loadX509orX509REQFromBuffer(buf, sz, - format, CERTREQ_TYPE); + format, CERTREQ_TYPE, NULL, NULL); } #endif @@ -6997,7 +6970,7 @@ static int X509PrintPubKey(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, int indent) case ECDSAk: len = XSNPRINTF(scratch, MAX_WIDTH, "%*sPublic Key Algorithm: EC\n", indent + 4, ""); - if (len >= MAX_WIDTH) + if ((len < 0) || (len >= MAX_WIDTH)) return WOLFSSL_FAILURE; if (wolfSSL_BIO_write(bio, scratch, len) <= 0) return WOLFSSL_FAILURE; @@ -7059,22 +7032,21 @@ static int X509PrintVersion(WOLFSSL_BIO* bio, int version, int indent) char scratch[MAX_WIDTH]; int scratchLen; - if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, - "%*s%s", indent, "", "Version:")) - >= MAX_WIDTH) - { + scratchLen = XSNPRINTF(scratch, MAX_WIDTH, "%*s%s", indent, "", "Version:"); + if ((scratchLen < 0) || (scratchLen >= MAX_WIDTH)) { return WOLFSSL_FAILURE; } + if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) { return WOLFSSL_FAILURE; } - if ((scratchLen = XSNPRINTF(scratch, MAX_WIDTH, - " %d (0x%x)\n", version, (byte)version-1)) - >= MAX_WIDTH) - { + scratchLen = XSNPRINTF(scratch, MAX_WIDTH, " %d (0x%x)\n", + version, (byte)version-1); + if ((scratchLen < 0) || (scratchLen >= MAX_WIDTH)) { return WOLFSSL_FAILURE; } + if (wolfSSL_BIO_write(bio, scratch, scratchLen) <= 0) { return WOLFSSL_FAILURE; } @@ -8042,11 +8014,22 @@ int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out) } #ifdef WOLFSSL_DUAL_ALG_CERTS +/* Generate a der preTBS from a decoded cert, and write + * to buffer. + * + * @param [in] cert The decoded cert to parse. + * @param [out] der The der buffer to write in. + * @param [in] derSz The der buffer size. + * + * @return preTBS der size on success. + * */ int wc_GeneratePreTBS(DecodedCert* cert, byte *der, int derSz) { int ret = 0; WOLFSSL_X509 *x = NULL; byte certIsCSR = 0; + WOLFSSL_ENTER("wc_GeneratePreTBS"); + if ((cert == NULL) || (der == NULL) || (derSz <= 0)) { return BAD_FUNC_ARG; } @@ -8079,6 +8062,7 @@ int wc_GeneratePreTBS(DecodedCert* cert, byte *der, int derSz) { if (x != NULL) { wolfSSL_X509_free(x); + x = NULL; } return ret; @@ -10343,6 +10327,19 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref( } #endif +#if defined(OPENSSL_EXTRA) + +WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_sk_X509_OBJECT_deep_copy( + const WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, + WOLFSSL_X509_OBJECT* (*c)(const WOLFSSL_X509_OBJECT*), + void (*f)(WOLFSSL_X509_OBJECT*)) +{ + (void)f; /* free function */ + (void)c; /* copy function */ + return wolfSSL_sk_dup((WOLFSSL_STACK*)sk); +} +#endif + #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) void wolfSSL_X509_NAME_free(WOLFSSL_X509_NAME *name) { @@ -10607,7 +10604,10 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509) cert->sigType = wolfSSL_X509_get_signature_type(x509); cert->keyType = x509->pubKeyOID; cert->isCA = wolfSSL_X509_get_isCA(x509); + cert->basicConstCrit = x509->basicConstCrit; cert->basicConstSet = x509->basicConstSet; + cert->pathLen = x509->pathLength; + cert->pathLenSet = x509->pathLengthSet; #ifdef WOLFSSL_CERT_EXT if (x509->subjKeyIdSz <= CTC_MAX_SKID_SIZE) { @@ -10674,10 +10674,13 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509) /* We point to instance in x509 so DON'T need to be free'd. */ cert->sapkiDer = x509->sapkiDer; cert->sapkiLen = x509->sapkiLen; + cert->sapkiCrit = x509->sapkiCrit; cert->altSigAlgDer = x509->altSigAlgDer; - cert->altSigAlgLen = x509->altSigAlgLen; + cert->altSigAlgLen = x509->altSigAlgLen; + cert->altSigAlgCrit = x509->altSigAlgCrit; cert->altSigValDer = x509->altSigValDer; cert->altSigValLen = x509->altSigValLen; + cert->altSigValCrit = x509->altSigValCrit; #endif /* WOLFSSL_DUAL_ALG_CERTS */ #endif /* WOLFSSL_CERT_EXT */ @@ -11052,9 +11055,15 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509) } #endif #if defined(HAVE_DILITHIUM) - if ((x509->pubKeyOID == DILITHIUM_LEVEL2k) || - (x509->pubKeyOID == DILITHIUM_LEVEL3k) || - (x509->pubKeyOID == DILITHIUM_LEVEL5k)) { + if ((x509->pubKeyOID == ML_DSA_LEVEL2k) || + (x509->pubKeyOID == ML_DSA_LEVEL3k) || + (x509->pubKeyOID == ML_DSA_LEVEL5k) + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT + || (x509->pubKeyOID == DILITHIUM_LEVEL2k) + || (x509->pubKeyOID == DILITHIUM_LEVEL3k) + || (x509->pubKeyOID == DILITHIUM_LEVEL5k) + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ + ) { dilithium = (dilithium_key*)XMALLOC(sizeof(dilithium_key), NULL, DYNAMIC_TYPE_DILITHIUM); if (dilithium == NULL) { @@ -11070,18 +11079,32 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509) return ret; } - if (x509->pubKeyOID == DILITHIUM_LEVEL2k) { + if (x509->pubKeyOID == ML_DSA_LEVEL2k) { + type = ML_DSA_LEVEL2_TYPE; + wc_dilithium_set_level(dilithium, WC_ML_DSA_44); + } + else if (x509->pubKeyOID == ML_DSA_LEVEL3k) { + type = ML_DSA_LEVEL3_TYPE; + wc_dilithium_set_level(dilithium, WC_ML_DSA_65); + } + else if (x509->pubKeyOID == ML_DSA_LEVEL5k) { + type = ML_DSA_LEVEL5_TYPE; + wc_dilithium_set_level(dilithium, WC_ML_DSA_87); + } + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT + else if (x509->pubKeyOID == DILITHIUM_LEVEL2k) { type = DILITHIUM_LEVEL2_TYPE; - wc_dilithium_set_level(dilithium, 2); + wc_dilithium_set_level(dilithium, WC_ML_DSA_44_DRAFT); } else if (x509->pubKeyOID == DILITHIUM_LEVEL3k) { type = DILITHIUM_LEVEL3_TYPE; - wc_dilithium_set_level(dilithium, 3); + wc_dilithium_set_level(dilithium, WC_ML_DSA_65_DRAFT); } else if (x509->pubKeyOID == DILITHIUM_LEVEL5k) { type = DILITHIUM_LEVEL5_TYPE; - wc_dilithium_set_level(dilithium, 5); + wc_dilithium_set_level(dilithium, WC_ML_DSA_87_DRAFT); } + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ ret = wc_Dilithium_PublicKeyDecode(x509->pubKey.buffer, &idx, dilithium, x509->pubKey.length); @@ -11262,9 +11285,15 @@ static int CertFromX509(Cert* cert, WOLFSSL_X509* x509) } #endif #if defined(HAVE_DILITHIUM) - if ((x509->pubKeyOID == DILITHIUM_LEVEL2k) || - (x509->pubKeyOID == DILITHIUM_LEVEL3k) || - (x509->pubKeyOID == DILITHIUM_LEVEL5k)) { + if ((x509->pubKeyOID == ML_DSA_LEVEL2k) || + (x509->pubKeyOID == ML_DSA_LEVEL3k) || + (x509->pubKeyOID == ML_DSA_LEVEL5k) + #ifdef WOLFSSL_DILITHIUM_FIPS204_DRAFT + || (x509->pubKeyOID == DILITHIUM_LEVEL2k) + || (x509->pubKeyOID == DILITHIUM_LEVEL3k) + || (x509->pubKeyOID == DILITHIUM_LEVEL5k) + #endif + ) { wc_dilithium_free(dilithium); XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM); } @@ -11941,12 +11970,12 @@ static WOLFSSL_X509 *loadX509orX509REQFromPemBio(WOLFSSL_BIO *bp, pemSz = (int)i; #ifdef WOLFSSL_CERT_REQ if (type == CERTREQ_TYPE) - x509 = wolfSSL_X509_REQ_load_certificate_buffer(pem, pemSz, - WOLFSSL_FILETYPE_PEM); + x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM, + CERTREQ_TYPE, cb, u); else #endif - x509 = wolfSSL_X509_load_certificate_buffer(pem, pemSz, - WOLFSSL_FILETYPE_PEM); + x509 = loadX509orX509REQFromBuffer(pem, pemSz, WOLFSSL_FILETYPE_PEM, + CERT_TYPE, cb, u); } if (x != NULL) { @@ -12671,6 +12700,7 @@ WOLFSSL_API WOLFSSL_X509_CRL* wolfSSL_PEM_read_X509_CRL(XFILE fp, return ne; } + static void wolfssl_x509_name_entry_set(WOLFSSL_X509_NAME_ENTRY* ne, int nid, int type, const unsigned char *data, int dataSz) { @@ -13075,6 +13105,17 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_X509_NAME_ENTRY_get_object( #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) || \ defined(OPENSSL_EXTRA_X509_SMALL) +#ifdef OPENSSL_EXTRA + int wolfSSL_X509_NAME_ENTRY_set(const WOLFSSL_X509_NAME_ENTRY *ne) + { + if (ne != NULL) { + return ne->set; + } + return 0; + } +#endif + + /* returns a pointer to the internal entry at location 'loc' on success, * a null pointer is returned in fail cases */ WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry( @@ -13342,30 +13383,7 @@ WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_value( WOLFSSL_X509_NAME* wolfSSL_sk_X509_NAME_pop( WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk) { - WOLFSSL_STACK* node; - WOLFSSL_X509_NAME* name; - - if (sk == NULL) { - return NULL; - } - - node = sk->next; - name = sk->data.name; - - if (node != NULL) { /* update sk and remove node from stack */ - sk->data.name = node->data.name; - sk->next = node->next; - XFREE(node, NULL, DYNAMIC_TYPE_OPENSSL); - } - else { /* last x509 in stack */ - sk->data.name = NULL; - } - - if (sk->num > 0) { - sk->num -= 1; - } - - return name; + return (WOLFSSL_X509_NAME*)wolfSSL_sk_pop(sk); } void wolfSSL_sk_X509_NAME_pop_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, @@ -13516,30 +13534,7 @@ WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_value( WOLFSSL_X509_INFO* wolfSSL_sk_X509_INFO_pop( WOLF_STACK_OF(WOLFSSL_X509_INFO)* sk) { - WOLFSSL_STACK* node; - WOLFSSL_X509_INFO* info; - - if (sk == NULL) { - return NULL; - } - - node = sk->next; - info = sk->data.info; - - if (node != NULL) { /* update sk and remove node from stack */ - sk->data.info = node->data.info; - sk->next = node->next; - wolfSSL_sk_free_node(node); - } - else { /* last x509 in stack */ - sk->data.info = NULL; - } - - if (sk->num > 0) { - sk->num -= 1; - } - - return info; + return (WOLFSSL_X509_INFO*)wolfSSL_sk_pop(sk); } #if defined(OPENSSL_ALL) @@ -13848,7 +13843,8 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, int tmpSz; /* reverse name order for RFC2253 and DN_REV */ - if ((flags & WOLFSSL_XN_FLAG_RFC2253) || (flags & WOLFSSL_XN_FLAG_DN_REV)) { + if ((flags & WOLFSSL_XN_FLAG_RFC2253) || + (flags & WOLFSSL_XN_FLAG_DN_REV)) { ne = wolfSSL_X509_NAME_get_entry(name, count - i - 1); } else { @@ -13986,6 +13982,11 @@ void wolfSSL_X509_OBJECT_free(WOLFSSL_X509_OBJECT *obj) if (obj->type == WOLFSSL_X509_LU_X509) { wolfSSL_X509_free(obj->data.x509); } + #ifdef HAVE_CRL + else if (obj->type == WOLFSSL_X509_LU_CRL) { + wolfSSL_X509_CRL_free(obj->data.crl); + } + #endif else { /* We don't free as this will point to * store->cm->crl which we don't own */ @@ -15190,7 +15191,10 @@ int wolfSSL_X509_REQ_add1_attr_by_NID(WOLFSSL_X509 *req, } if ((req->reqAttributes != NULL) && (req->reqAttributes->type == STACK_TYPE_X509_REQ_ATTR)) { - ret = wolfSSL_sk_push(req->reqAttributes, attr) > 0 + /* Using wolfSSL_sk_insert to maintain backwards compatibility with + * earlier versions of _push API that pushed items to the start of + * the list instead of the end. */ + ret = wolfSSL_sk_insert(req->reqAttributes, attr, 0) > 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } else { @@ -15275,7 +15279,6 @@ WOLFSSL_X509_ATTRIBUTE *wolfSSL_X509_REQ_get_attr( int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req, int nid, int lastpos) { - WOLFSSL_STACK* sk; int idx; WOLFSSL_ENTER("wolfSSL_X509_REQ_get_attr_by_NID"); @@ -15286,26 +15289,14 @@ int wolfSSL_X509_REQ_get_attr_by_NID(const WOLFSSL_X509 *req, } /* search through stack for first matching nid */ - idx = lastpos + 1; - do { - sk = wolfSSL_sk_get_node(req->reqAttributes, idx); - if (sk != NULL) { - WOLFSSL_X509_ATTRIBUTE* attr; - attr = (WOLFSSL_X509_ATTRIBUTE*)sk->data.generic; - if (nid == attr->object->nid) { - /* found a match */ - break; - } - } - idx++; - } while (sk != NULL); - - /* no matches found */ - if (sk == NULL) { - idx = WOLFSSL_FATAL_ERROR; + for (idx = lastpos + 1; idx < wolfSSL_sk_num(req->reqAttributes); idx++) { + WOLFSSL_X509_ATTRIBUTE* attr = + (WOLFSSL_X509_ATTRIBUTE*)wolfSSL_sk_value(req->reqAttributes, idx); + if (attr != NULL && attr->object != NULL && attr->object->nid == nid) + return idx; } - return idx; + return WOLFSSL_FATAL_ERROR; } WOLFSSL_X509_ATTRIBUTE* wolfSSL_X509_ATTRIBUTE_new(void) @@ -15638,6 +15629,17 @@ int wolfSSL_X509_ACERT_verify(WOLFSSL_X509_ACERT* x509, WOLFSSL_EVP_PKEY* pkey) return ret == 0 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } +/* Loads an x509 attribute certificate from buffer, and returns + * pointer to new WOLFSSL_X509_ACERT struct on success. + * + * @param [in] buf The acert buffer to load. + * @param [in] sz The size of the buffer. + * @param [in] format The format of the buffer data. + * @param [in] heap Dynamic memory allocation hint. + * + * @return pointer to WOLFSSL_X509_ACERT on success. + * @return NULL on error. + * */ WOLFSSL_X509_ACERT * wolfSSL_X509_ACERT_load_certificate_buffer_ex( const unsigned char* buf, int sz, int format, void * heap) { diff --git a/src/src/x509_str.c b/src/src/x509_str.c index 894da16..fedf4a0 100644 --- a/src/src/x509_str.c +++ b/src/src/x509_str.c @@ -1,6 +1,6 @@ /* x509_str.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if !defined(WOLFSSL_X509_STORE_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN @@ -105,6 +100,7 @@ void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx) if (ctx->current_issuer != NULL) { wolfSSL_X509_free(ctx->current_issuer); + ctx->current_issuer = NULL; } #endif @@ -114,8 +110,7 @@ void wolfSSL_X509_STORE_CTX_free(WOLFSSL_X509_STORE_CTX* ctx) #ifdef OPENSSL_EXTRA -#if ((defined(SESSION_CERTS) && !defined(WOLFSSL_QT)) || \ - defined(WOLFSSL_SIGNER_DER_CERT)) +#if defined(SESSION_CERTS) || defined(WOLFSSL_SIGNER_DER_CERT) /** * Find the issuing cert of the input cert. On a self-signed cert this @@ -809,10 +804,28 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) if (sk == NULL) return NULL; + for (i = 0; i < c->count; i++) { + WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, i); + + if (x509 == NULL) { + WOLFSSL_MSG("Unable to get x509 from chain"); + error = 1; + break; + } + + if (wolfSSL_sk_X509_push(sk, x509) <= 0) { + WOLFSSL_MSG("Unable to load x509 into stack"); + wolfSSL_X509_free(x509); + x509 = NULL; + error = 1; + break; + } + } + #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ defined(OPENSSL_EXTRA) /* add CA used to verify top of chain to the list */ - if (c->count > 0) { + if (!error && c->count > 0) { WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, c->count - 1); WOLFSSL_X509* issuer = NULL; if (x509 != NULL) { @@ -825,11 +838,14 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) if (wolfSSL_sk_X509_push(sk, issuer) <= 0) { WOLFSSL_MSG("Unable to load CA x509 into stack"); error = 1; + wolfSSL_X509_free(issuer); + issuer = NULL; } } else { WOLFSSL_MSG("Certificate is self signed"); wolfSSL_X509_free(issuer); + issuer = NULL; } } else { @@ -837,30 +853,9 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) } } wolfSSL_X509_free(x509); - if (error) { - wolfSSL_sk_X509_pop_free(sk, NULL); - wolfSSL_X509_free(issuer); - return NULL; - } + x509 = NULL; } #endif - - for (i = c->count - 1; i >= 0; i--) { - WOLFSSL_X509* x509 = wolfSSL_get_chain_X509(c, i); - - if (x509 == NULL) { - WOLFSSL_MSG("Unable to get x509 from chain"); - error = 1; - break; - } - - if (wolfSSL_sk_X509_push(sk, x509) <= 0) { - WOLFSSL_MSG("Unable to load x509 into stack"); - wolfSSL_X509_free(x509); - error = 1; - break; - } - } if (error) { wolfSSL_sk_X509_pop_free(sk, NULL); return NULL; @@ -978,6 +973,7 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_STORE_get1_certs( <= 0) { err = 1; wolfSSL_X509_free(filteredCert); + filteredCert = NULL; break; } } @@ -1415,6 +1411,7 @@ int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509) else { result = WOLFSSL_FATAL_ERROR; wolfSSL_X509_free(x509); + x509 = NULL; } } } @@ -1430,6 +1427,7 @@ int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509) else { result = WOLFSSL_FATAL_ERROR; wolfSSL_X509_free(x509); + x509 = NULL; } } } @@ -1474,18 +1472,10 @@ int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag) return ret; } - -int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE* store) -{ - (void)store; - return WOLFSSL_SUCCESS; -} - int X509StoreLoadCertBuffer(WOLFSSL_X509_STORE *str, byte *buf, word32 bufLen, int type) { int ret = WOLFSSL_SUCCESS; - WOLFSSL_X509 *x509 = NULL; if (str == NULL || buf == NULL) { @@ -1494,21 +1484,26 @@ int X509StoreLoadCertBuffer(WOLFSSL_X509_STORE *str, /* OpenSSL X509_STORE_load_file fails on DER file, we will as well */ x509 = wolfSSL_X509_load_certificate_buffer(buf, bufLen, type); - if (str->owned != NULL) { - if (wolfSSL_sk_X509_push(str->owned, x509) <= 0) { + if (x509 != NULL) { + ret = wolfSSL_X509_STORE_add_cert(str, x509); + if (ret != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Failed to load file"); ret = WOLFSSL_FAILURE; } + if (ret == WOLFSSL_SUCCESS && str->owned != NULL) { + if (wolfSSL_sk_X509_push(str->owned, x509) <= 0) { + ret = WOLFSSL_FAILURE; + } + else { + x509 = NULL; + } + } + wolfSSL_X509_free(x509); + x509 = NULL; } - if (ret == WOLFSSL_SUCCESS) { - ret = wolfSSL_X509_STORE_add_cert(str, x509); - } - if (ret != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("Failed to load file"); + else { ret = WOLFSSL_FAILURE; } - if (ret != WOLFSSL_SUCCESS || str->owned == NULL) { - wolfSSL_X509_free(x509); - } return ret; } @@ -1560,6 +1555,8 @@ static int X509StoreLoadFile(WOLFSSL_X509_STORE *str, static_buffer_init(&content, stackBuffer, FILE_BUFFER_SIZE); #endif + WOLFSSL_MSG_EX("X509StoreLoadFile: Loading file: %s", fname); + ret = X509StoreReadFile(fname, &content, &contentLen, &type); if (ret != WOLFSSL_SUCCESS) { WOLFSSL_MSG("Failed to load file"); @@ -1681,6 +1678,27 @@ WOLFSSL_API int wolfSSL_X509_STORE_load_locations(WOLFSSL_X509_STORE *str, return ret; } + +#if defined(XGETENV) && !defined(NO_GETENV) +int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE *str) +{ + int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE); + char* certDir = NULL; + char* certFile = NULL; + + WOLFSSL_ENTER("wolfSSL_X509_STORE_set_default_paths"); + + certFile = wc_strdup_ex(XGETENV("SSL_CERT_FILE"), DYNAMIC_TYPE_TMP_BUFFER); + certDir = wc_strdup_ex(XGETENV("SSL_CERT_DIR"), DYNAMIC_TYPE_TMP_BUFFER); + + ret = wolfSSL_X509_STORE_load_locations(str, certFile, certDir); + + XFREE(certFile, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(certDir, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; +} +#endif /* XGETENV && !NO_GETENV */ + #endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */ int wolfSSL_X509_CA_num(WOLFSSL_X509_STORE* store) @@ -1778,6 +1796,7 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s) if (wolfSSL_sk_X509_push(sk, x509) <= 0) { WOLFSSL_MSG("Unable to load x509 into stack"); wolfSSL_X509_free(x509); + x509 = NULL; goto error; } } @@ -1893,6 +1912,7 @@ WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects( #ifdef HAVE_CRL if (store->cm->crl != NULL) { + int res; obj = wolfSSL_X509_OBJECT_new(); if (obj == NULL) { WOLFSSL_MSG("wolfSSL_X509_OBJECT_new error"); @@ -1904,6 +1924,11 @@ WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* wolfSSL_X509_STORE_get0_objects( goto err_cleanup; } obj->type = WOLFSSL_X509_LU_CRL; + wolfSSL_RefInc(&store->cm->crl->ref, &res); + if (res != 0) { + WOLFSSL_MSG("Failed to lock crl mutex"); + goto err_cleanup; + } obj->data.crl = store->cm->crl; } #endif diff --git a/src/user_settings.h b/src/user_settings.h index 15bc03b..e2a0196 100644 --- a/src/user_settings.h +++ b/src/user_settings.h @@ -1,6 +1,6 @@ /* examples/configs/user_settings_arduino.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -23,7 +23,14 @@ */ /* Define a macro to display user settings version in example code: */ -#define WOLFSSL_USER_SETTINGS_ID "Arduino user_settings.h v5.7.4" +#define WOLFSSL_USER_SETTINGS_ID "Arduino user_settings.h v5.7.6" + +/* Disable wolfcrypt cryptographic security hardening. Comment out to enable: */ +/* #define WC_NO_HARDEN */ + +/* Instead, we harden ECC and RSA */ +#define ECC_TIMING_RESISTANT +#define WC_RSA_BLINDING /* Due to limited build control, we'll ignore file warnings. */ /* See https://github.com/arduino/arduino-cli/issues/631 */ @@ -37,6 +44,7 @@ #undef WOLFSSL_ESPIDF #define HAVE_ECC + #define WOLFSSL_SMALL_STACK /* #define WOLFSSL_SMALL_STACK_EXTRA */ /* #define WOLFSSL_SMALL_STACK_CIPHERS */ @@ -74,17 +82,27 @@ * WOLFSSL_CLIENT_EXAMPLE * WOLFSSL_SERVER_EXAMPLE */ + +/* The examples must be manually selected here: */ + #if defined(WOLFSSL_CLIENT_EXAMPLE) #define NO_WOLFSSL_SERVER #elif defined(WOLFSSL_SERVER_EXAMPLE) #define NO_WOLFSSL_CLIENT +#elif defined(WOLFSSL_TEMPLATE_EXAMPLE) + #define NO_WOLFSSL_SERVER + #define NO_WOLFSSL_CLIENT +#elif defined(WOLFSSL_AES_CTR_EXAMPLE) + #define NO_WOLFSSL_SERVER + #define NO_WOLFSSL_CLIENT + #define WOLFSSL_AES + #define WOLFSSL_AES_COUNTER #else /* Provide a hint to application that neither WOLFSSL_CLIENT_EXAMPLE * or WOLFSSL_SERVER_EXAMPLE macro hint was desired but not found. */ #define NO_WOLFSSL_SERVER_CLIENT_MISSING - #warning "Define WOLFSSL_CLIENT_EXAMPLE or WOLFSSL_SERVER_EXAMPLE to" \ - " optimize memory for small embedded devices." - /* Both can be disabled in wolfssl test & benchmark */ + + /* By default all examples are enabled; no specific optimizations */ #endif @@ -112,8 +130,8 @@ /* #define HAVE_PKCS7 */ /* when you want to use AES counter mode */ -/* #define WOLFSSL_AES_DIRECT */ -/* #define WOLFSSL_AES_COUNTER */ +#define WOLFSSL_AES_DIRECT +#define WOLFSSL_AES_COUNTER /* esp32-wroom-32se specific definition */ #if defined(WOLFSSL_ESPWROOM32SE) @@ -352,7 +370,7 @@ */ /* optional SM4 Ciphers. See https://github.com/wolfSSL/wolfsm -/* The section below defines macros used in typically all of the wolfSSL + * The section below defines macros used in typically all of the wolfSSL * examples such as the client and server for certs stored in header files. * * There are various certificate examples in this header file: diff --git a/src/wolfcrypt/src/aes.c b/src/wolfcrypt/src/aes.c index cf50064..6e7f104 100644 --- a/src/wolfcrypt/src/aes.c +++ b/src/wolfcrypt/src/aes.c @@ -1,6 +1,6 @@ /* aes.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -28,12 +28,8 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits 192-bits, and 256-bits of key sizes. */ -#ifdef HAVE_CONFIG_H - #include -#endif -#include -#include +#include #if !defined(NO_AES) @@ -97,8 +93,6 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #include #else -#include - #ifdef NO_INLINE #include #else @@ -239,7 +233,7 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits #endif /* WOLFSSL_AES_DIRECT || HAVE_AESGCM || HAVE_AESCCM */ #ifdef HAVE_AES_DECRYPT - #if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) + #if defined(WOLFSSL_AES_DIRECT) static WARN_UNUSED_RESULT int wc_AesDecrypt( Aes* aes, const byte* inBlock, byte* outBlock) { @@ -346,13 +340,12 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits return ret; } - #endif /* WOLFSSL_AES_DIRECT || HAVE_AESCCM */ + #endif /* WOLFSSL_AES_DIRECT */ #endif /* HAVE_AES_DECRYPT */ #elif defined(HAVE_COLDFIRE_SEC) /* Freescale Coldfire SEC support for CBC mode. * NOTE: no support for AES-CTR/GCM/CCM/Direct */ - #include #include "sec.h" #include "mcf5475_sec.h" #include "mcf5475_siu.h" @@ -805,6 +798,7 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits aes->use_aes_hw_crypto = IS_AARCH64_AES(cpuid_flags); #ifdef HAVE_AESGCM aes->use_pmull_hw_crypto = IS_AARCH64_PMULL(cpuid_flags); + aes->use_sha3_hw_crypto = IS_AARCH64_SHA3(cpuid_flags); #endif } @@ -1966,8 +1960,8 @@ static word32 GetTable8_4(const byte* t, byte o0, byte o1, byte o2, byte o3) static void AesEncrypt_C(Aes* aes, const byte* inBlock, byte* outBlock, word32 r) { - word32 s0, s1, s2, s3; - word32 t0, t1, t2, t3; + word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0; + word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0; const word32* rk; #ifdef WC_C_DYNAMIC_FALLBACK @@ -3015,8 +3009,8 @@ static WARN_UNUSED_RESULT WC_INLINE word32 PreFetchTd4(void) static void AesDecrypt_C(Aes* aes, const byte* inBlock, byte* outBlock, word32 r) { - word32 s0, s1, s2, s3; - word32 t0, t1, t2, t3; + word32 s0 = 0, s1 = 0, s2 = 0, s3 = 0; + word32 t0 = 0, t1 = 0, t2 = 0, t3 = 0; const word32* rk; #ifdef WC_C_DYNAMIC_FALLBACK @@ -3762,7 +3756,8 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( ByteReverseWords(rk, rk, keylen); #endif #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ - defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) + defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \ + defined(WOLFSSL_AES_CTS) aes->left = 0; #endif return wc_AesSetIV(aes, iv); @@ -3843,7 +3838,8 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE); #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ - defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) + defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \ + defined(WOLFSSL_AES_CTS) aes->left = 0; #endif @@ -3874,7 +3870,8 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( XMEMCPY(aes->key, userKey, keylen); #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ - defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) + defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \ + defined(WOLFSSL_AES_CTS) aes->left = 0; #endif @@ -3926,7 +3923,8 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( return BAD_FUNC_ARG; #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ - defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) + defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \ + defined(WOLFSSL_AES_CTS) aes->left = 0; #endif @@ -4007,7 +4005,8 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( ret = nrf51_aes_set_key(userKey); #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ - defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) + defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \ + defined(WOLFSSL_AES_CTS) aes->left = 0; #endif @@ -4064,7 +4063,8 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt( XMEMCPY(aes->key, userKey, keylen); #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ - defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) + defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \ + defined(WOLFSSL_AES_CTS) aes->left = 0; #endif return wc_AesSetIV(aes, iv); @@ -4557,7 +4557,8 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) } #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ - defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) + defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \ + defined(WOLFSSL_AES_CTS) aes->left = 0; #endif @@ -4574,12 +4575,53 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) #endif /* WC_C_DYNAMIC_FALLBACK */ #ifdef WOLFSSL_AESNI - aes->use_aesni = 0; + + /* The dynamics for determining whether AES-NI will be used are tricky. + * + * First, we check for CPU support and cache the result -- if AES-NI is + * missing, we always shortcut to the AesSetKey_C() path. + * + * Second, if the CPU supports AES-NI, we confirm on a per-call basis + * that it's safe to use in the caller context, using + * SAVE_VECTOR_REGISTERS2(). This is an always-true no-op in user-space + * builds, but has substantive logic behind it in kernel module builds. + * + * The outcome when SAVE_VECTOR_REGISTERS2() fails depends on + * WC_C_DYNAMIC_FALLBACK -- if that's defined, we return immediately with + * success but with AES-NI disabled (the earlier AesSetKey_C() allows + * future encrypt/decrypt calls to succeed), otherwise we fail. + * + * Upon successful return, aes->use_aesni will have a zero value if + * AES-NI is disabled, and a nonzero value if it's enabled. + * + * An additional, optional semantic is available via + * WC_FLAG_DONT_USE_AESNI, and is used in some kernel module builds to + * let the caller inhibit AES-NI. When this macro is defined, + * wc_AesInit() before wc_AesSetKey() is imperative, to avoid a read of + * uninitialized data in aes->use_aesni. That's why support for + * WC_FLAG_DONT_USE_AESNI must remain optional -- wc_AesInit() was only + * added in release 3.11.0, so legacy applications inevitably call + * wc_AesSetKey() on uninitialized Aes contexts. This must continue to + * function correctly with default build settings. + */ + if (checkedAESNI == 0) { haveAESNI = Check_CPU_support_AES(); checkedAESNI = 1; } - if (haveAESNI) { + if (haveAESNI +#if defined(WC_FLAG_DONT_USE_AESNI) && !defined(WC_C_DYNAMIC_FALLBACK) + && (aes->use_aesni != WC_FLAG_DONT_USE_AESNI) +#endif + ) + { +#if defined(WC_FLAG_DONT_USE_AESNI) + if (aes->use_aesni == WC_FLAG_DONT_USE_AESNI) { + aes->use_aesni = 0; + return 0; + } +#endif + aes->use_aesni = 0; #ifdef WOLFSSL_LINUXKM /* runtime alignment check */ if ((wc_ptr_t)&aes->key & (wc_ptr_t)0xf) { @@ -4613,6 +4655,15 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) #endif } } + else { + aes->use_aesni = 0; +#ifdef WC_C_DYNAMIC_FALLBACK + /* If WC_C_DYNAMIC_FALLBACK, we already called AesSetKey_C() + * above. + */ + return 0; +#endif + } #endif /* WOLFSSL_AESNI */ #if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \ @@ -4789,7 +4840,8 @@ int wc_AesSetIV(Aes* aes, const byte* iv) XMEMSET(aes->reg, 0, WC_AES_BLOCK_SIZE); #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ - defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) + defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \ + defined(WOLFSSL_AES_CTS) /* Clear any unused bytes from last cipher op. */ aes->left = 0; #endif @@ -6448,6 +6500,22 @@ static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz) #define AES_LASTGBLOCK(aes) ((aes)->streamData + 3 * WC_AES_BLOCK_SIZE) /* Access last encrypted block. */ #define AES_LASTBLOCK(aes) ((aes)->streamData + 4 * WC_AES_BLOCK_SIZE) + + #if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \ + !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) + #define GHASH_ONE_BLOCK(aes, block) \ + do { \ + if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) { \ + GHASH_ONE_BLOCK_AARCH64(aes, block); \ + } \ + else { \ + GHASH_ONE_BLOCK_SW(aes, block); \ + } \ + } \ + while (0) + #else + #define GHASH_ONE_BLOCK GHASH_ONE_BLOCK_SW + #endif #endif #if defined(HAVE_COLDFIRE_SEC) @@ -6456,7 +6524,7 @@ static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz) #endif #if defined(WOLFSSL_ARMASM) && !defined(__aarch64__) - /* implemented in wolfcrypt/src/port/arm/rmv8-aes.c */ + /* implemented in wolfcrypt/src/port/arm/armv8-aes.c */ #elif defined(WOLFSSL_RISCV_ASM) /* implemented in wolfcrypt/src/port/risc-v/riscv-64-aes.c */ @@ -6616,6 +6684,25 @@ void GenerateM0(Gcm* gcm) #endif /* GCM_TABLE */ +#if defined(WOLFSSL_AESNI) && defined(USE_INTEL_SPEEDUP) + #define HAVE_INTEL_AVX1 + #define HAVE_INTEL_AVX2 +#endif + +#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT) && \ + defined(WC_C_DYNAMIC_FALLBACK) +void GCM_generate_m0_aesni(const unsigned char *h, unsigned char *m) + XASM_LINK("GCM_generate_m0_aesni"); +#ifdef HAVE_INTEL_AVX1 +void GCM_generate_m0_avx1(const unsigned char *h, unsigned char *m) + XASM_LINK("GCM_generate_m0_avx1"); +#endif +#ifdef HAVE_INTEL_AVX2 +void GCM_generate_m0_avx2(const unsigned char *h, unsigned char *m) + XASM_LINK("GCM_generate_m0_avx2"); +#endif +#endif /* WOLFSSL_AESNI && GCM_TABLE_4BIT && WC_C_DYNAMIC_FALLBACK */ + /* Software AES - GCM SetKey */ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) { @@ -6685,9 +6772,33 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) VECTOR_REGISTERS_POP; } if (ret == 0) { - #if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) - GenerateM0(&aes->gcm); - #endif /* GCM_TABLE */ +#if defined(GCM_TABLE) || defined(GCM_TABLE_4BIT) +#if defined(WOLFSSL_AESNI) && defined(GCM_TABLE_4BIT) + if (aes->use_aesni) { + #if defined(WC_C_DYNAMIC_FALLBACK) + #ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_AVX2(intel_flags)) { + GCM_generate_m0_avx2(aes->gcm.H, (byte*)aes->gcm.M0); + } + else + #endif + #if defined(HAVE_INTEL_AVX1) + if (IS_INTEL_AVX1(intel_flags)) { + GCM_generate_m0_avx1(aes->gcm.H, (byte*)aes->gcm.M0); + } + else + #endif + { + GCM_generate_m0_aesni(aes->gcm.H, (byte*)aes->gcm.M0); + } + #endif + } + else +#endif + { + GenerateM0(&aes->gcm); + } +#endif /* GCM_TABLE || GCM_TABLE_4BIT */ } #endif /* FREESCALE_LTC_AES_GCM */ @@ -6710,11 +6821,6 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) #ifdef WOLFSSL_AESNI -#if defined(USE_INTEL_SPEEDUP) - #define HAVE_INTEL_AVX1 - #define HAVE_INTEL_AVX2 -#endif /* USE_INTEL_SPEEDUP */ - void AES_GCM_encrypt_aesni(const unsigned char *in, unsigned char *out, const unsigned char* addt, const unsigned char* ivec, unsigned char *tag, word32 nbytes, @@ -6866,10 +6972,10 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, * @param [in, out] aes AES GCM object. * @param [in] block Block of AAD or cipher text. */ -#define GHASH_ONE_BLOCK(aes, block) \ +#define GHASH_ONE_BLOCK_SW(aes, block) \ do { \ - xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \ - GMULT(AES_TAG(aes), aes->gcm.H); \ + xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \ + GMULT(AES_TAG(aes), (aes)->gcm.H); \ } \ while (0) #endif /* WOLFSSL_AESGCM_STREAM */ @@ -7099,9 +7205,9 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, * @param [in, out] aes AES GCM object. * @param [in] block Block of AAD or cipher text. */ -#define GHASH_ONE_BLOCK(aes, block) \ +#define GHASH_ONE_BLOCK_SW(aes, block) \ do { \ - xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \ + xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \ GMULT(AES_TAG(aes), aes->gcm.M0); \ } \ while (0) @@ -7392,8 +7498,6 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, */ #define GHASH_INIT_EXTRA(aes) WC_DO_NOTHING -#if !defined(__aarch64__) || !defined(WOLFSSL_ARMASM) || \ - defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) /* GHASH one block of data.. * * XOR block into tag and GMULT with H using pre-computed table. @@ -7401,13 +7505,12 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, * @param [in, out] aes AES GCM object. * @param [in] block Block of AAD or cipher text. */ -#define GHASH_ONE_BLOCK(aes, block) \ +#define GHASH_ONE_BLOCK_SW(aes, block) \ do { \ - xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \ + xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \ GMULT(AES_TAG(aes), (aes)->gcm.M0); \ } \ while (0) -#endif #endif /* WOLFSSL_AESGCM_STREAM */ #elif defined(WORD64_AVAILABLE) && !defined(GCM_WORD32) @@ -7574,17 +7677,17 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, * @param [in, out] aes AES GCM object. * @param [in] block Block of AAD or cipher text. */ -#define GHASH_ONE_BLOCK(aes, block) \ - do { \ - word64* x = (word64*)AES_TAG(aes); \ - word64* h = (word64*)aes->gcm.H; \ - word64 block64[2]; \ - XMEMCPY(block64, block, WC_AES_BLOCK_SIZE); \ - ByteReverseWords64(block64, block64, WC_AES_BLOCK_SIZE); \ - x[0] ^= block64[0]; \ - x[1] ^= block64[1]; \ - GMULT(x, h); \ - } \ +#define GHASH_ONE_BLOCK_SW(aes, block) \ + do { \ + word64* x = (word64*)AES_TAG(aes); \ + word64* h = (word64*)aes->gcm.H; \ + word64 block64[2]; \ + XMEMCPY(block64, block, WC_AES_BLOCK_SIZE); \ + ByteReverseWords64(block64, block64, WC_AES_BLOCK_SIZE); \ + x[0] ^= block64[0]; \ + x[1] ^= block64[1]; \ + GMULT(x, h); \ + } \ while (0) #ifdef OPENSSL_EXTRA @@ -7609,7 +7712,7 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, x[0] ^= len[0]; \ x[1] ^= len[1]; \ GMULT(x, h); \ - ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE); \ + ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE); \ } \ while (0) #else @@ -7632,7 +7735,7 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, x[0] ^= len[0]; \ x[1] ^= len[1]; \ GMULT(x, h); \ - ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE); \ + ByteReverseWords64(x, x, WC_AES_BLOCK_SIZE); \ } \ while (0) #endif @@ -7652,7 +7755,7 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, * @param [in, out] aes AES GCM object. * @param [in] block Block of AAD or cipher text. */ -#define GHASH_ONE_BLOCK(aes, block) \ +#define GHASH_ONE_BLOCK_SW(aes, block) \ do { \ word64* x = (word64*)AES_TAG(aes); \ word64* h = (word64*)aes->gcm.H; \ @@ -7884,19 +7987,19 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, * @param [in, out] aes AES GCM object. * @param [in] block Block of AAD or cipher text. */ -#define GHASH_ONE_BLOCK(aes, block) \ - do { \ - word32* x = (word32*)AES_TAG(aes); \ - word32* h = (word32*)aes->gcm.H; \ - word32 bigEnd[4]; \ - XMEMCPY(bigEnd, block, WC_AES_BLOCK_SIZE); \ - ByteReverseWords(bigEnd, bigEnd, WC_AES_BLOCK_SIZE); \ - x[0] ^= bigEnd[0]; \ - x[1] ^= bigEnd[1]; \ - x[2] ^= bigEnd[2]; \ - x[3] ^= bigEnd[3]; \ - GMULT(x, h); \ - } \ +#define GHASH_ONE_BLOCK_SW(aes, block) \ + do { \ + word32* x = (word32*)AES_TAG(aes); \ + word32* h = (word32*)aes->gcm.H; \ + word32 bigEnd[4]; \ + XMEMCPY(bigEnd, block, WC_AES_BLOCK_SIZE); \ + ByteReverseWords(bigEnd, bigEnd, WC_AES_BLOCK_SIZE); \ + x[0] ^= bigEnd[0]; \ + x[1] ^= bigEnd[1]; \ + x[2] ^= bigEnd[2]; \ + x[3] ^= bigEnd[3]; \ + GMULT(x, h); \ + } \ while (0) /* GHASH in AAD and cipher text lengths in bits. @@ -7919,7 +8022,7 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, x[2] ^= len[2]; \ x[3] ^= len[3]; \ GMULT(x, h); \ - ByteReverseWords(x, x, WC_AES_BLOCK_SIZE); \ + ByteReverseWords(x, x, WC_AES_BLOCK_SIZE); \ } \ while (0) #else @@ -7936,12 +8039,12 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, * @param [in, out] aes AES GCM object. * @param [in] block Block of AAD or cipher text. */ -#define GHASH_ONE_BLOCK(aes, block) \ +#define GHASH_ONE_BLOCK_SW(aes, block) \ do { \ word32* x = (word32*)AES_TAG(aes); \ word32* h = (word32*)aes->gcm.H; \ word32 block32[4]; \ - XMEMCPY(block32, block, WC_AES_BLOCK_SIZE); \ + XMEMCPY(block32, block, WC_AES_BLOCK_SIZE); \ x[0] ^= block32[0]; \ x[1] ^= block32[1]; \ x[2] ^= block32[2]; \ @@ -7985,7 +8088,7 @@ void GHASH(Gcm* gcm, const byte* a, word32 aSz, const byte* c, */ #define GHASH_LEN_BLOCK(aes) \ do { \ - byte scratch[WC_AES_BLOCK_SIZE]; \ + byte scratch[WC_AES_BLOCK_SIZE]; \ FlattenSzInBits(&scratch[0], (aes)->aSz); \ FlattenSzInBits(&scratch[8], (aes)->cSz); \ GHASH_ONE_BLOCK(aes, scratch); \ @@ -8139,7 +8242,8 @@ static void GHASH_FINAL(Aes* aes, byte* s, word32 sSz) } if (over > 0) { /* Zeroize the unused part of the block. */ - XMEMSET(AES_LASTGBLOCK(aes) + over, 0, (size_t)WC_AES_BLOCK_SIZE - over); + XMEMSET(AES_LASTGBLOCK(aes) + over, 0, + (size_t)WC_AES_BLOCK_SIZE - over); /* Hash the last block of cipher text. */ GHASH_ONE_BLOCK(aes, AES_LASTGBLOCK(aes)); } @@ -8192,8 +8296,6 @@ int wc_AesGcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz, #ifdef STM32_CRYPTO_AES_GCM /* this function supports inline encrypt */ -/* define STM32_AESGCM_PARTIAL for STM HW that does not support authentication - * on byte multiples (see CRYP_HEADERWIDTHUNIT_BYTE) */ static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32( Aes* aes, byte* out, const byte* in, word32 sz, const byte* iv, word32 ivSz, @@ -8279,12 +8381,11 @@ static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32( /* for cases where hardware cannot be used for authTag calculate it */ /* if IV is not 12 calculate GHASH using software */ if (ivSz != GCM_NONCE_MID_SZ - #if !defined(CRYP_HEADERWIDTHUNIT_BYTE) || defined(WOLFSSL_STM32MP13) + #if !defined(CRYP_HEADERWIDTHUNIT_BYTE) /* or hardware that does not support partial block */ || sz == 0 || partial != 0 #endif - #if (!defined(CRYP_HEADERWIDTHUNIT_BYTE) || defined(WOLFSSL_STM32MP13)) \ - && !defined(STM32_AESGCM_PARTIAL) + #if !defined(STM_CRYPT_HEADER_WIDTH) || STM_CRYPT_HEADER_WIDTH == 4 /* or authIn is not a multiple of 4 */ || authPadSz != authInSz #endif @@ -8306,12 +8407,7 @@ static WARN_UNUSED_RESULT int wc_AesGcmEncrypt_STM32( #if defined(STM32_HAL_V2) hcryp.Init.Algorithm = CRYP_AES_GCM; - #if defined(CRYP_HEADERWIDTHUNIT_BYTE) && !defined(WOLFSSL_STM32MP13) - /* V2 with CRYP_HEADERWIDTHUNIT_BYTE uses byte size for header */ - hcryp.Init.HeaderSize = authInSz; - #else - hcryp.Init.HeaderSize = authPadSz/sizeof(word32); - #endif + hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH; #ifdef CRYP_KEYIVCONFIG_ONCE /* allows repeated calls to HAL_CRYP_Encrypt */ hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE; @@ -8809,12 +8905,11 @@ static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32( /* for cases where hardware cannot be used for authTag calculate it */ /* if IV is not 12 calculate GHASH using software */ if (ivSz != GCM_NONCE_MID_SZ - #if !defined(CRYP_HEADERWIDTHUNIT_BYTE) || defined(WOLFSSL_STM32MP13) + #if !defined(CRYP_HEADERWIDTHUNIT_BYTE) /* or hardware that does not support partial block */ || sz == 0 || partial != 0 #endif - #if (!defined(CRYP_HEADERWIDTHUNIT_BYTE) || defined(WOLFSSL_STM32MP13)) \ - && !defined(STM32_AESGCM_PARTIAL) + #if !defined(STM_CRYPT_HEADER_WIDTH) || STM_CRYPT_HEADER_WIDTH == 4 /* or authIn is not a multiple of 4 */ || authPadSz != authInSz #endif @@ -8860,12 +8955,8 @@ static WARN_UNUSED_RESULT int wc_AesGcmDecrypt_STM32( #if defined(STM32_HAL_V2) hcryp.Init.Algorithm = CRYP_AES_GCM; - #if defined(CRYP_HEADERWIDTHUNIT_BYTE) && !defined(WOLFSSL_STM32MP13) - /* V2 with CRYP_HEADERWIDTHUNIT_BYTE uses byte size for header */ - hcryp.Init.HeaderSize = authInSz; - #else - hcryp.Init.HeaderSize = authPadSz/sizeof(word32); - #endif + hcryp.Init.HeaderSize = authPadSz / STM_CRYPT_HEADER_WIDTH; + #ifdef CRYP_KEYIVCONFIG_ONCE /* allows repeated calls to HAL_CRYP_Decrypt */ hcryp.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE; @@ -10189,7 +10280,7 @@ int wc_AesGcmInit(Aes* aes, const byte* key, word32 len, const byte* iv, else #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \ !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) - if (aes->use_aes_hw_crypto) { + if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) { AES_GCM_init_AARCH64(aes, iv, ivSz); /* Reset state fields. */ @@ -10328,7 +10419,7 @@ int wc_AesGcmEncryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz, else #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \ !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) - if (aes->use_aes_hw_crypto) { + if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) { AES_GCM_crypt_update_AARCH64(aes, out, in, sz); GHASH_UPDATE_AARCH64(aes, authIn, authInSz, out, sz); } @@ -10388,7 +10479,7 @@ int wc_AesGcmEncryptFinal(Aes* aes, byte* authTag, word32 authTagSz) else #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \ !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) - if (aes->use_aes_hw_crypto) { + if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) { AES_GCM_final_AARCH64(aes, authTag, authTagSz); } else @@ -10477,7 +10568,7 @@ int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz, else #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \ !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) - if (aes->use_aes_hw_crypto) { + if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) { GHASH_UPDATE_AARCH64(aes, authIn, authInSz, in, sz); AES_GCM_crypt_update_AARCH64(aes, out, in, sz); } @@ -10535,7 +10626,7 @@ int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, word32 authTagSz) else #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \ !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) - if (aes->use_aes_hw_crypto) { + if (aes->use_aes_hw_crypto && aes->use_pmull_hw_crypto) { ALIGN32 byte calcTag[WC_AES_BLOCK_SIZE]; AES_GCM_final_AARCH64(aes, calcTag, authTagSz); /* Check calculated tag matches the one passed in. */ @@ -10771,7 +10862,7 @@ int wc_GmacVerify(const byte* key, word32 keySz, #endif /* WC_NO_RNG */ -WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len) +int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len) { if (gmac == NULL || key == NULL) { return BAD_FUNC_ARG; @@ -10780,7 +10871,7 @@ WOLFSSL_API int wc_GmacSetKey(Gmac* gmac, const byte* key, word32 len) } -WOLFSSL_API int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz, +int wc_GmacUpdate(Gmac* gmac, const byte* iv, word32 ivSz, const byte* authIn, word32 authInSz, byte* authTag, word32 authTagSz) { @@ -10821,7 +10912,7 @@ int wc_AesCcmCheckTagSize(int sz) } #if defined(WOLFSSL_ARMASM) && !defined(__aarch64__) - /* implemented in wolfcrypt/src/port/arm/rmv8-aes.c */ + /* implemented in wolfcrypt/src/port/arm/armv8-aes.c */ #elif defined(WOLFSSL_RISCV_ASM) /* implementation located in wolfcrypt/src/port/risc-v/riscv-64-aes.c */ @@ -11832,7 +11923,13 @@ static WARN_UNUSED_RESULT int _AesEcbEncrypt( #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \ !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) if (aes->use_aes_hw_crypto) { - AES_encrypt_AARCH64(in, out, (byte*)aes->key, (int)aes->rounds); + word32 i; + + for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) { + AES_encrypt_AARCH64(in, out, (byte*)aes->key, (int)aes->rounds); + in += WC_AES_BLOCK_SIZE; + out += WC_AES_BLOCK_SIZE; + } } else #endif @@ -11890,7 +11987,13 @@ static WARN_UNUSED_RESULT int _AesEcbDecrypt( #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \ !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) if (aes->use_aes_hw_crypto) { - AES_decrypt_AARCH64(in, out, (byte*)aes->key, (int)aes->rounds); + word32 i; + + for (i = 0; i < sz; i += WC_AES_BLOCK_SIZE) { + AES_decrypt_AARCH64(in, out, (byte*)aes->key, (int)aes->rounds); + in += WC_AES_BLOCK_SIZE; + out += WC_AES_BLOCK_SIZE; + } } else #endif @@ -12753,7 +12856,12 @@ int wc_AesXtsSetKeyNoInit(XtsAes* aes, const byte* key, word32 len, int dir) } if ((len != (AES_128_KEY_SIZE*2)) && +#ifndef HAVE_FIPS + /* XTS-384 not allowed by FIPS and can not be treated like + * RSA-4096 bit keys back in the day, can not vendor affirm + * the use of 2 concatenated 192-bit keys (XTS-384) */ (len != (AES_192_KEY_SIZE*2)) && +#endif (len != (AES_256_KEY_SIZE*2))) { WOLFSSL_MSG("Unsupported key size"); @@ -12936,6 +13044,10 @@ int wc_AesXtsDecryptSector(XtsAes* aes, byte* out, const byte* in, word32 sz, #ifdef WOLFSSL_AESNI +#if defined(USE_INTEL_SPEEDUP_FOR_AES) && !defined(USE_INTEL_SPEEDUP) + #define USE_INTEL_SPEEDUP +#endif + #if defined(USE_INTEL_SPEEDUP) #define HAVE_INTEL_AVX1 #define HAVE_INTEL_AVX2 @@ -14799,4 +14911,276 @@ int wc_AesEaxFree(AesEax* eax) #endif /* WOLFSSL_AES_EAX */ +#ifdef WOLFSSL_AES_CTS + + +/* One-shot API */ +int wc_AesCtsEncrypt(const byte* key, word32 keySz, byte* out, + const byte* in, word32 inSz, + const byte* iv) +{ +#ifdef WOLFSSL_SMALL_STACK + Aes *aes = NULL; +#else + Aes aes[1]; +#endif + int ret = 0; + word32 outSz = inSz; + + if (key == NULL || out == NULL || in == NULL || iv == NULL) + return BAD_FUNC_ARG; + +#ifdef WOLFSSL_SMALL_STACK + aes = wc_AesNew(NULL, INVALID_DEVID, &ret); +#else + ret = wc_AesInit(aes, NULL, INVALID_DEVID); +#endif + if (ret == 0) + ret = wc_AesSetKey(aes, key, keySz, iv, AES_ENCRYPTION); + if (ret == 0) + ret = wc_AesCtsEncryptUpdate(aes, out, &outSz, in, inSz); + if (ret == 0) { + out += outSz; + outSz = inSz - outSz; + ret = wc_AesCtsEncryptFinal(aes, out, &outSz); + } + +#ifdef WOLFSSL_SMALL_STACK + wc_AesDelete(aes, NULL); +#else + wc_AesFree(aes); +#endif + return ret; +} + +int wc_AesCtsDecrypt(const byte* key, word32 keySz, byte* out, + const byte* in, word32 inSz, + const byte* iv) +{ +#ifdef WOLFSSL_SMALL_STACK + Aes *aes = NULL; +#else + Aes aes[1]; +#endif + int ret = 0; + word32 outSz = inSz; + + if (key == NULL || out == NULL || in == NULL || iv == NULL) { + return BAD_FUNC_ARG; + } + +#ifdef WOLFSSL_SMALL_STACK + aes = wc_AesNew(NULL, INVALID_DEVID, &ret); +#else + ret = wc_AesInit(aes, NULL, INVALID_DEVID); +#endif + if (ret == 0) + ret = wc_AesSetKey(aes, key, keySz, iv, AES_DECRYPTION); + if (ret == 0) + ret = wc_AesCtsDecryptUpdate(aes, out, &outSz, in, inSz); + if (ret == 0) { + out += outSz; + outSz = inSz - outSz; + ret = wc_AesCtsDecryptFinal(aes, out, &outSz); + } + +#ifdef WOLFSSL_SMALL_STACK + wc_AesDelete(aes, NULL); +#else + wc_AesFree(aes); +#endif + return ret; +} + +static int AesCtsUpdate(Aes* aes, byte* out, word32* outSz, + const byte* in, word32 inSz, int enc) +{ + word32 blocks = 0; + int ret = 0; + word32 writtenSz = 0; + word32 tmpOutSz; + + if (aes == NULL || out == NULL || in == NULL || outSz == NULL) + return BAD_FUNC_ARG; + + /* Error out early for easy sanity check */ + if (*outSz < inSz) + return BUFFER_E; + tmpOutSz = *outSz; + + /* We need to store last two blocks of plaintext */ + if (aes->left > 0) { + word32 copySz = min(inSz, (WC_AES_BLOCK_SIZE * 2) - aes->left); + XMEMCPY(aes->ctsBlock + aes->left, in, copySz); + aes->left += copySz; + in += copySz; + inSz -= copySz; + + if (aes->left == WC_AES_BLOCK_SIZE * 2) { + if (inSz > WC_AES_BLOCK_SIZE) { + if (tmpOutSz < WC_AES_BLOCK_SIZE * 2) + return BUFFER_E; + if (enc) { + ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock, + WC_AES_BLOCK_SIZE * 2); + } + else { + ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock, + WC_AES_BLOCK_SIZE * 2); + } + if (ret != 0) + return ret; + out += WC_AES_BLOCK_SIZE * 2; + writtenSz += WC_AES_BLOCK_SIZE * 2; + tmpOutSz -= WC_AES_BLOCK_SIZE * 2; + aes->left = 0; + } + else if (inSz > 0) { + if (tmpOutSz < WC_AES_BLOCK_SIZE) + return BUFFER_E; + if (enc) { + ret = wc_AesCbcEncrypt(aes, out, aes->ctsBlock, + WC_AES_BLOCK_SIZE); + } + else { + ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock, + WC_AES_BLOCK_SIZE); + } + if (ret != 0) + return ret; + out += WC_AES_BLOCK_SIZE; + writtenSz += WC_AES_BLOCK_SIZE; + tmpOutSz -= WC_AES_BLOCK_SIZE; + /* Move the last block in ctsBlock to the beginning for + * next operation */ + XMEMCPY(aes->ctsBlock, aes->ctsBlock + WC_AES_BLOCK_SIZE, + WC_AES_BLOCK_SIZE); + XMEMCPY(aes->ctsBlock + WC_AES_BLOCK_SIZE, in, inSz); + aes->left = WC_AES_BLOCK_SIZE + inSz; + *outSz = writtenSz; + return ret; /* Return the result of encryption */ + } + else { + /* Can't output data as we need > 1 block for Final call */ + *outSz = writtenSz; + return 0; + } + } + else { + /* All input has been absorbed into aes->ctsBlock */ + *outSz = 0; + return 0; + } + } + if (inSz > WC_AES_BLOCK_SIZE) { + /* We need to store the last two full or partial blocks */ + blocks = (inSz + (WC_AES_BLOCK_SIZE - 1)) / WC_AES_BLOCK_SIZE; + blocks -= 2; + } + if (tmpOutSz < blocks * WC_AES_BLOCK_SIZE) + return BUFFER_E; + if (enc) + ret = wc_AesCbcEncrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE); + else + ret = wc_AesCbcDecrypt(aes, out, in, blocks * WC_AES_BLOCK_SIZE); + in += blocks * WC_AES_BLOCK_SIZE; + inSz -= blocks * WC_AES_BLOCK_SIZE; + XMEMCPY(aes->ctsBlock, in, inSz); + aes->left = inSz; + writtenSz += blocks * WC_AES_BLOCK_SIZE; + *outSz = writtenSz; + return ret; +} + +/* Incremental API */ +int wc_AesCtsEncryptUpdate(Aes* aes, byte* out, word32* outSz, + const byte* in, word32 inSz) +{ + return AesCtsUpdate(aes, out, outSz, in, inSz, 1); +} + +int wc_AesCtsEncryptFinal(Aes* aes, byte* out, word32* outSz) +{ + int ret = 0; + + if (aes == NULL || out == NULL || outSz == NULL) + return BAD_FUNC_ARG; + if (*outSz < aes->left) + return BUFFER_E; + + /* Input must be at least two complete or partial blocks */ + if (aes->left <= WC_AES_BLOCK_SIZE) + return BAD_FUNC_ARG; + + /* Zero padding */ + XMEMSET(aes->ctsBlock + aes->left, 0, (WC_AES_BLOCK_SIZE * 2) - aes->left); + + ret = wc_AesCbcEncrypt(aes, aes->ctsBlock, aes->ctsBlock, + WC_AES_BLOCK_SIZE * 2); + if (ret != 0) + return ret; + + XMEMCPY(out, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE); + XMEMCPY(out + WC_AES_BLOCK_SIZE, aes->ctsBlock, + aes->left - WC_AES_BLOCK_SIZE); + *outSz = aes->left; + return ret; +} + +int wc_AesCtsDecryptUpdate(Aes* aes, byte* out, word32* outSz, + const byte* in, word32 inSz) +{ + return AesCtsUpdate(aes, out, outSz, in, inSz, 0); +} + +int wc_AesCtsDecryptFinal(Aes* aes, byte* out, word32* outSz) +{ + int ret = 0; + byte iv[WC_AES_BLOCK_SIZE]; + byte tmp[WC_AES_BLOCK_SIZE]; + word32 partialSz; + word32 padSz; + + if (aes == NULL || out == NULL || outSz == NULL) + return BAD_FUNC_ARG; + if (*outSz < aes->left) + return BUFFER_E; + + /* Input must be at least two complete or partial blocks */ + if (aes->left <= WC_AES_BLOCK_SIZE) + return BAD_FUNC_ARG; + + partialSz = aes->left - WC_AES_BLOCK_SIZE; + padSz = 2 * WC_AES_BLOCK_SIZE - aes->left; + /* Zero pad */ + XMEMSET(aes->ctsBlock + aes->left, 0, padSz); + + /* Store IV */ + XMEMCPY(iv, aes->reg, WC_AES_BLOCK_SIZE); + /* Load IV */ + XMEMCPY(aes->reg, aes->ctsBlock + WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE); + + ret = wc_AesCbcDecrypt(aes, tmp, aes->ctsBlock, WC_AES_BLOCK_SIZE); + if (ret != 0) + return ret; + + /* Write out partial block */ + XMEMCPY(out + WC_AES_BLOCK_SIZE, tmp, partialSz); + /* Retrieve the padding */ + XMEMCPY(aes->ctsBlock + aes->left, tmp + partialSz, padSz); + /* Restore IV */ + XMEMCPY(aes->reg, iv, WC_AES_BLOCK_SIZE); + + ret = wc_AesCbcDecrypt(aes, out, aes->ctsBlock + WC_AES_BLOCK_SIZE, + WC_AES_BLOCK_SIZE); + if (ret != 0) + return ret; + + *outSz = aes->left; + return ret; +} + +#endif /* WOLFSSL_AES_CTS */ + + #endif /* !NO_AES */ diff --git a/src/wolfcrypt/src/arc4.c b/src/wolfcrypt/src/arc4.c index 649d52f..a877d8b 100644 --- a/src/wolfcrypt/src/arc4.c +++ b/src/wolfcrypt/src/arc4.c @@ -1,6 +1,6 @@ /* arc4.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,16 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifndef NO_RC4 -#include #include diff --git a/src/wolfcrypt/src/ascon.c b/src/wolfcrypt/src/ascon.c new file mode 100644 index 0000000..248d06a --- /dev/null +++ b/src/wolfcrypt/src/ascon.c @@ -0,0 +1,521 @@ +/* ascon.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 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include + +#ifdef HAVE_ASCON + +#include +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +/* + * Implementation of the ASCON AEAD and HASH algorithms. Based on the NIST + * Initial Public Draft "NIST SP 800-232 ipd" and reference implementation found + * at https://github.com/ascon/ascon-c. + */ + +/* + * TODO + * - Add support for big-endian systems + * - Add support for 32-bit and smaller systems */ + +#ifndef WORD64_AVAILABLE + #error "Ascon implementation requires a 64-bit word" +#endif + +/* Data block size in bytes */ +#define ASCON_HASH256_RATE 8 +#define ASCON_HASH256_ROUNDS 12 +#define ASCON_HASH256_IV 0x0000080100CC0002ULL + +#define ASCON_AEAD128_ROUNDS_PA 12 +#define ASCON_AEAD128_ROUNDS_PB 8 +#define ASCON_AEAD128_IV 0x00001000808C0001ULL +#define ASCON_AEAD128_RATE 16 + +#define MAX_ROUNDS 12 + +#ifndef WOLFSSL_ASCON_UNROLL + +/* Table 5 */ +static const byte round_constants[MAX_ROUNDS] = { + 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, 0x78, 0x69, 0x5a, 0x4b +}; + +static byte start_index(byte rounds) +{ + switch (rounds) { + case 8: + return 4; + case 12: + return 0; + default: + WOLFSSL_MSG("Something went wrong in wolfCrypt logic. Wrong ASCON " + "rounds value."); + return MAX_ROUNDS; + } +} + +static WC_INLINE void ascon_round(AsconState* a, byte round) +{ + word64 tmp0, tmp1, tmp2, tmp3, tmp4; + /* 3.2 Constant-Addition Layer */ + a->s64[2] ^= round_constants[round]; + /* 3.3 Substitution Layer */ + a->s64[0] ^= a->s64[4]; + a->s64[4] ^= a->s64[3]; + a->s64[2] ^= a->s64[1]; + tmp0 = a->s64[0] ^ (~a->s64[1] & a->s64[2]); + tmp2 = a->s64[2] ^ (~a->s64[3] & a->s64[4]); + tmp4 = a->s64[4] ^ (~a->s64[0] & a->s64[1]); + tmp1 = a->s64[1] ^ (~a->s64[2] & a->s64[3]); + tmp3 = a->s64[3] ^ (~a->s64[4] & a->s64[0]); + tmp1 ^= tmp0; + tmp3 ^= tmp2; + tmp0 ^= tmp4; + tmp2 = ~tmp2; + /* 3.4 Linear Diffusion Layer */ + a->s64[4] = tmp4 ^ rotrFixed64(tmp4, 7) ^ rotrFixed64(tmp4, 41); + a->s64[1] = tmp1 ^ rotrFixed64(tmp1, 61) ^ rotrFixed64(tmp1, 39); + a->s64[3] = tmp3 ^ rotrFixed64(tmp3, 10) ^ rotrFixed64(tmp3, 17); + a->s64[0] = tmp0 ^ rotrFixed64(tmp0, 19) ^ rotrFixed64(tmp0, 28); + a->s64[2] = tmp2 ^ rotrFixed64(tmp2, 1) ^ rotrFixed64(tmp2, 6); +} + +static void permutation(AsconState* a, byte rounds) +{ + byte i = start_index(rounds); + for (; i < MAX_ROUNDS; i++) { + ascon_round(a, i); + } +} + +#else + +#define p(a, c) do { \ + word64 tmp0, tmp1, tmp2, tmp3, tmp4; \ + /* 3.2 Constant-Addition Layer */ \ + (a)->s64[2] ^= c; \ + /* 3.3 Substitution Layer */ \ + (a)->s64[0] ^= (a)->s64[4]; \ + (a)->s64[4] ^= (a)->s64[3]; \ + (a)->s64[2] ^= (a)->s64[1]; \ + tmp0 = (a)->s64[0] ^ (~(a)->s64[1] & (a)->s64[2]); \ + tmp2 = (a)->s64[2] ^ (~(a)->s64[3] & (a)->s64[4]); \ + tmp4 = (a)->s64[4] ^ (~(a)->s64[0] & (a)->s64[1]); \ + tmp1 = (a)->s64[1] ^ (~(a)->s64[2] & (a)->s64[3]); \ + tmp3 = (a)->s64[3] ^ (~(a)->s64[4] & (a)->s64[0]); \ + tmp1 ^= tmp0; \ + tmp3 ^= tmp2; \ + tmp0 ^= tmp4; \ + tmp2 = ~tmp2; \ + /* 3.4 Linear Diffusion Layer */ \ + (a)->s64[4] = tmp4 ^ rotrFixed64(tmp4, 7) ^ rotrFixed64(tmp4, 41); \ + (a)->s64[1] = tmp1 ^ rotrFixed64(tmp1, 61) ^ rotrFixed64(tmp1, 39); \ + (a)->s64[3] = tmp3 ^ rotrFixed64(tmp3, 10) ^ rotrFixed64(tmp3, 17); \ + (a)->s64[0] = tmp0 ^ rotrFixed64(tmp0, 19) ^ rotrFixed64(tmp0, 28); \ + (a)->s64[2] = tmp2 ^ rotrFixed64(tmp2, 1) ^ rotrFixed64(tmp2, 6); \ +} while (0) + +#define p8(a) \ + p(a, 0xb4); \ + p(a, 0xa5); \ + p(a, 0x96); \ + p(a, 0x87); \ + p(a, 0x78); \ + p(a, 0x69); \ + p(a, 0x5a); \ + p(a, 0x4b) + +#define p12(a) \ + p(a, 0xf0); \ + p(a, 0xe1); \ + p(a, 0xd2); \ + p(a, 0xc3); \ + p8(a) + +/* Needed layer to evaluate the macro values */ +#define _permutation(a, rounds) \ + p ## rounds(a) + +#define permutation(a, rounds) \ + _permutation(a, rounds) + +#endif + +/* AsconHash API */ + +wc_AsconHash256* wc_AsconHash256_New(void) +{ + wc_AsconHash256* ret = (wc_AsconHash256*)XMALLOC(sizeof(wc_AsconHash256), + NULL, DYNAMIC_TYPE_ASCON); + if (ret != NULL) { + if (wc_AsconHash256_Init(ret) != 0) { + wc_AsconHash256_Free(ret); + ret = NULL; + } + } + return ret; +} + +void wc_AsconHash256_Free(wc_AsconHash256* a) +{ + if (a != NULL) { + wc_AsconHash256_Clear(a); + XFREE(a, NULL, DYNAMIC_TYPE_ASCON); + } +} + +int wc_AsconHash256_Init(wc_AsconHash256* a) +{ + if (a == NULL) + return BAD_FUNC_ARG; + + XMEMSET(a, 0, sizeof(*a)); + + a->state.s64[0] = ASCON_HASH256_IV; + permutation(&a->state, ASCON_HASH256_ROUNDS); + + return 0; +} + +void wc_AsconHash256_Clear(wc_AsconHash256* a) +{ + if (a != NULL) { + ForceZero(a, sizeof(*a)); + } +} + +int wc_AsconHash256_Update(wc_AsconHash256* a, const byte* data, word32 dataSz) +{ + if (a == NULL || (data == NULL && dataSz != 0)) + return BAD_FUNC_ARG; + + if (dataSz == 0) + return 0; + + /* Process leftover block */ + if (a->lastBlkSz != 0) { + word32 toProcess = min(ASCON_HASH256_RATE - a->lastBlkSz, dataSz); + xorbuf(a->state.s8 + a->lastBlkSz, data, toProcess); + data += toProcess; + dataSz -= toProcess; + a->lastBlkSz += toProcess; + + if (a->lastBlkSz < ASCON_HASH256_RATE) + return 0; + + permutation(&a->state, ASCON_HASH256_ROUNDS); + /* Reset the counter */ + a->lastBlkSz = 0; + } + + while (dataSz >= ASCON_HASH256_RATE) { + /* Read in input as little endian numbers */ + xorbuf(a->state.s64, data, ASCON_HASH256_RATE); + permutation(&a->state, ASCON_HASH256_ROUNDS); + data += ASCON_HASH256_RATE; + dataSz -= ASCON_HASH256_RATE; + } + + xorbuf(a->state.s64, data, dataSz); + a->lastBlkSz = dataSz; + + return 0; +} + +int wc_AsconHash256_Final(wc_AsconHash256* a, byte* hash) +{ + byte i; + + if (a == NULL || hash == NULL) + return BAD_FUNC_ARG; + + /* Process last block */ + a->state.s8[a->lastBlkSz] ^= 1; + + for (i = 0; i < ASCON_HASH256_SZ; i += ASCON_HASH256_RATE) { + permutation(&a->state, ASCON_HASH256_ROUNDS); + XMEMCPY(hash, a->state.s64, ASCON_HASH256_RATE); + hash += ASCON_HASH256_RATE; + } + + /* Clear state as soon as possible */ + wc_AsconHash256_Clear(a); + return 0; +} + +/* AsconAEAD API */ + +wc_AsconAEAD128* wc_AsconAEAD128_New(void) +{ + wc_AsconAEAD128 *ret = (wc_AsconAEAD128*) XMALLOC(sizeof(wc_AsconAEAD128), + NULL, DYNAMIC_TYPE_ASCON); + if (ret != NULL) { + if (wc_AsconAEAD128_Init(ret) != 0) { + wc_AsconAEAD128_Free(ret); + ret = NULL; + } + } + return ret; +} + +void wc_AsconAEAD128_Free(wc_AsconAEAD128 *a) +{ + if (a != NULL) { + wc_AsconAEAD128_Clear(a); + XFREE(a, NULL, DYNAMIC_TYPE_ASCON); + } +} + +int wc_AsconAEAD128_Init(wc_AsconAEAD128 *a) +{ + if (a == NULL) + return BAD_FUNC_ARG; + + XMEMSET(a, 0, sizeof(*a)); + a->state.s64[0] = ASCON_AEAD128_IV; + + return 0; +} + +void wc_AsconAEAD128_Clear(wc_AsconAEAD128 *a) +{ + if (a != NULL) { + ForceZero(a, sizeof(*a)); + } +} + +int wc_AsconAEAD128_SetKey(wc_AsconAEAD128* a, const byte* key) +{ + if (a == NULL || key == NULL) + return BAD_FUNC_ARG; + if (a->keySet) + return BAD_STATE_E; + + XMEMCPY(a->key, key, ASCON_AEAD128_KEY_SZ); + a->state.s64[1] = a->key[0]; + a->state.s64[2] = a->key[1]; + a->keySet = 1; + + return 0; +} + +int wc_AsconAEAD128_SetNonce(wc_AsconAEAD128* a, const byte* nonce) +{ + if (a == NULL || nonce == NULL) + return BAD_FUNC_ARG; + if (a->nonceSet) + return BAD_STATE_E; + + XMEMCPY(&a->state.s64[3], nonce, ASCON_AEAD128_NONCE_SZ); + a->nonceSet = 1; + + return 0; +} + +int wc_AsconAEAD128_SetAD(wc_AsconAEAD128* a, const byte* ad, + word32 adSz) +{ + if (a == NULL || (ad == NULL && adSz > 0)) + return BAD_FUNC_ARG; + if (!a->keySet || !a->nonceSet) /* key and nonce must be set before */ + return BAD_STATE_E; + + permutation(&a->state, ASCON_AEAD128_ROUNDS_PA); + a->state.s64[3] ^= a->key[0]; + a->state.s64[4] ^= a->key[1]; + + if (adSz > 0) { + while (adSz >= ASCON_AEAD128_RATE) { + xorbuf(a->state.s64, ad, ASCON_AEAD128_RATE); + permutation(&a->state, ASCON_AEAD128_ROUNDS_PB); + ad += ASCON_AEAD128_RATE; + adSz -= ASCON_AEAD128_RATE; + } + xorbuf(a->state.s64, ad, adSz); + /* Pad the last block */ + a->state.s8[adSz] ^= 1; + permutation(&a->state, ASCON_AEAD128_ROUNDS_PB); + } + a->state.s64[4] ^= 1ULL << 63; + + a->adSet = 1; + return 0; +} + +int wc_AsconAEAD128_EncryptUpdate(wc_AsconAEAD128* a, byte* out, + const byte* in, word32 inSz) +{ + if (a == NULL || (in == NULL && inSz > 0)) + return BAD_FUNC_ARG; + if (!a->keySet || !a->nonceSet || !a->adSet) + return BAD_STATE_E; + + if (a->op == ASCON_AEAD128_NOTSET) + a->op = ASCON_AEAD128_ENCRYPT; + else if (a->op != ASCON_AEAD128_ENCRYPT) + return BAD_STATE_E; + + /* Process leftover from last block */ + if (a->lastBlkSz != 0) { + word32 toProcess = min(ASCON_AEAD128_RATE - a->lastBlkSz, inSz); + xorbuf(&a->state.s8[a->lastBlkSz], in, toProcess); + XMEMCPY(out, &a->state.s8[a->lastBlkSz], toProcess); + a->lastBlkSz += toProcess; + in += toProcess; + out += toProcess; + inSz -= toProcess; + + if (a->lastBlkSz < ASCON_AEAD128_RATE) + return 0; + + permutation(&a->state, ASCON_AEAD128_ROUNDS_PB); + a->lastBlkSz = 0; + } + + while (inSz >= ASCON_AEAD128_RATE) { + xorbuf(a->state.s64, in, ASCON_AEAD128_RATE); + XMEMCPY(out, a->state.s64, ASCON_AEAD128_RATE); + permutation(&a->state, ASCON_AEAD128_ROUNDS_PB); + in += ASCON_AEAD128_RATE; + out += ASCON_AEAD128_RATE; + inSz -= ASCON_AEAD128_RATE; + } + /* Store leftover */ + xorbuf(a->state.s64, in, inSz); + XMEMCPY(out, a->state.s64, inSz); + a->lastBlkSz = inSz; + + return 0; +} + + +int wc_AsconAEAD128_EncryptFinal(wc_AsconAEAD128* a, byte* tag) +{ + if (a == NULL || tag == NULL) + return BAD_FUNC_ARG; + if (!a->keySet || !a->nonceSet || !a->adSet) + return BAD_STATE_E; + + if (a->op != ASCON_AEAD128_ENCRYPT) + return BAD_STATE_E; + + /* Process leftover from last block */ + a->state.s8[a->lastBlkSz] ^= 1; + + a->state.s64[2] ^= a->key[0]; + a->state.s64[3] ^= a->key[1]; + permutation(&a->state, ASCON_AEAD128_ROUNDS_PA); + a->state.s64[3] ^= a->key[0]; + a->state.s64[4] ^= a->key[1]; + + XMEMCPY(tag, &a->state.s64[3], ASCON_AEAD128_TAG_SZ); + + /* Clear state as soon as possible */ + wc_AsconAEAD128_Clear(a); + + return 0; + +} + + +int wc_AsconAEAD128_DecryptUpdate(wc_AsconAEAD128* a, byte* out, + const byte* in, word32 inSz) +{ + if (a == NULL || (in == NULL && inSz > 0)) + return BAD_FUNC_ARG; + if (!a->keySet || !a->nonceSet || !a->adSet) + return BAD_STATE_E; + + if (a->op == ASCON_AEAD128_NOTSET) + a->op = ASCON_AEAD128_DECRYPT; + else if (a->op != ASCON_AEAD128_DECRYPT) + return BAD_STATE_E; + + /* Process leftover block */ + if (a->lastBlkSz != 0) { + word32 toProcess = min(ASCON_AEAD128_RATE - a->lastBlkSz, inSz); + xorbufout(out, a->state.s8 + a->lastBlkSz, in, toProcess); + XMEMCPY(a->state.s8 + a->lastBlkSz, in, toProcess); + in += toProcess; + out += toProcess; + inSz -= toProcess; + a->lastBlkSz += toProcess; + + if (a->lastBlkSz < ASCON_AEAD128_RATE) + return 0; + + permutation(&a->state, ASCON_AEAD128_ROUNDS_PB); + a->lastBlkSz = 0; + } + + while (inSz >= ASCON_AEAD128_RATE) { + xorbufout(out, a->state.s64, in, ASCON_AEAD128_RATE); + XMEMCPY(a->state.s64, in, ASCON_AEAD128_RATE); + permutation(&a->state, ASCON_AEAD128_ROUNDS_PB); + in += ASCON_AEAD128_RATE; + out += ASCON_AEAD128_RATE; + inSz -= ASCON_AEAD128_RATE; + } + /* Store leftover */ + xorbufout(out, a->state.s64, in, inSz); + XMEMCPY(a->state.s64, in, inSz); + a->lastBlkSz = inSz; + + return 0; +} + +int wc_AsconAEAD128_DecryptFinal(wc_AsconAEAD128* a, const byte* tag) +{ + if (a == NULL || tag == NULL) + return BAD_FUNC_ARG; + if (!a->keySet || !a->nonceSet || !a->adSet) + return BAD_STATE_E; + + if (a->op != ASCON_AEAD128_DECRYPT) + return BAD_STATE_E; + + /* Pad last block */ + a->state.s8[a->lastBlkSz] ^= 1; + + a->state.s64[2] ^= a->key[0]; + a->state.s64[3] ^= a->key[1]; + permutation(&a->state, ASCON_AEAD128_ROUNDS_PA); + a->state.s64[3] ^= a->key[0]; + a->state.s64[4] ^= a->key[1]; + + if (ConstantCompare(tag, (const byte*)&a->state.s64[3], + ASCON_AEAD128_TAG_SZ) != 0) + return ASCON_AUTH_E; + + /* Clear state as soon as possible */ + wc_AsconAEAD128_Clear(a); + + return 0; +} + +#endif /* HAVE_ASCON */ diff --git a/src/wolfcrypt/src/asm.c b/src/wolfcrypt/src/asm.c index 2096ae9..a724114 100644 --- a/src/wolfcrypt/src/asm.c +++ b/src/wolfcrypt/src/asm.c @@ -1,6 +1,6 @@ /* asm.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include /* * Based on public domain TomsFastMath 0.10 by Tom St Denis, tomstdenis@iahu.ca, diff --git a/src/wolfcrypt/src/asn.c b/src/wolfcrypt/src/asn.c index 6335df3..af74678 100644 --- a/src/wolfcrypt/src/asn.c +++ b/src/wolfcrypt/src/asn.c @@ -1,6 +1,6 @@ /* asn.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -34,11 +34,8 @@ * Provides routines to convert BER into DER. Replaces indefinite length * encoded items with explicit lengths. */ -#ifdef HAVE_CONFIG_H - #include -#endif -#include +#include /* ASN Options: @@ -109,7 +106,6 @@ ASN Options: * usage. */ -#include #ifndef NO_RSA #include #if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL) @@ -128,7 +124,6 @@ ASN Options: #include #include #include -#include #include #include @@ -1300,7 +1295,7 @@ static int GetASN_StoreData(const ASNItem* asn, ASNGetData* data, WOLFSSL_MSG_VSNPRINTF("Buffer too small for data: %d %d", len, *data->data.buffer.length); #endif - return ASN_PARSE_E; + return BUFFER_E; } /* Copy in data and record actual length seen. */ XMEMCPY(data->data.buffer.data, input + idx, (size_t)len); @@ -2451,8 +2446,9 @@ static int GetASNHeader_ex(const byte* input, byte tag, word32* inOutIdx, ret = ASN_PARSE_E; } else if ((input[(int)idx + length - 1] & 0x80) == 0x80) { - /* Last octet of a sub-identifier has bit 8 clear. Last octet must be - * last of a subidentifier. Ensure last octet hasn't got top bit set. */ + /* Last octet of a sub-identifier has bit 8 clear. Last octet must + * be last of a subidentifier. Ensure last octet hasn't got top bit + * set. */ WOLFSSL_MSG("OID last octet has top bit set"); ret = ASN_PARSE_E; } @@ -3629,8 +3625,8 @@ word32 SetIndefEnd(byte* output) /* Breaks an octet string up into chunks for use with streaming * returns 0 on success and updates idx */ -int StreamOctetString(const byte* inBuf, word32 inBufSz, byte* out, word32* outSz, - word32* idx) +int StreamOctetString(const byte* inBuf, word32 inBufSz, byte* out, + word32* outSz, word32* idx) { word32 i = 0; word32 outIdx = *idx; @@ -4495,16 +4491,295 @@ static const byte extAuthInfoCaIssuerOid[] = {43, 6, 1, 5, 5, 7, 48, 2}; /* certPolicyType */ static const byte extCertPolicyAnyOid[] = {85, 29, 32, 0}; +static const byte extCertPolicyIsrgDomainValid[] = + {43, 6, 1, 4, 1, 130, 223, 19, 1, 1, 1}; #ifdef WOLFSSL_FPKI #define CERT_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 3, 2, 1, 3, num} + static const byte extCertPolicyFpkiHighAssuranceOid[] = + CERT_POLICY_TYPE_OID_BASE(4); + static const byte extCertPolicyFpkiCommonHardwareOid[] = + CERT_POLICY_TYPE_OID_BASE(7); + static const byte extCertPolicyFpkiMediumHardwareOid[] = + CERT_POLICY_TYPE_OID_BASE(12); static const byte extCertPolicyFpkiCommonAuthOid[] = CERT_POLICY_TYPE_OID_BASE(13); + static const byte extCertPolicyFpkiCommonHighOid[] = + CERT_POLICY_TYPE_OID_BASE(16); + static const byte extCertPolicyFpkiCommonDevicesHardwareOid[] = + CERT_POLICY_TYPE_OID_BASE(36); + static const byte extCertPolicyFpkiCommonPivContentSigningOid[] = + CERT_POLICY_TYPE_OID_BASE(39); static const byte extCertPolicyFpkiPivAuthOid[] = CERT_POLICY_TYPE_OID_BASE(40); static const byte extCertPolicyFpkiPivAuthHwOid[] = CERT_POLICY_TYPE_OID_BASE(41); static const byte extCertPolicyFpkiPiviAuthOid[] = CERT_POLICY_TYPE_OID_BASE(45); + + /* Federal PKI Test OIDs - 2.16.840.1.101.3.2.1.48.x */ + #define TEST_CERT_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 3, 2, 1, 48, num} + static const byte extCertPolicyFpkiAuthTestOid[] = + TEST_CERT_POLICY_TYPE_OID_BASE(11); + static const byte extCertPolicyFpkiCardauthTestOid[] = + TEST_CERT_POLICY_TYPE_OID_BASE(13); + static const byte extCertPolicyFpkiPivContentTestOid[] = + TEST_CERT_POLICY_TYPE_OID_BASE(86); + static const byte extCertPolicyFpkiAuthDerivedTestOid[] = + TEST_CERT_POLICY_TYPE_OID_BASE(109); + static const byte extCertPolicyFpkiAuthDerivedHwTestOid[] = + TEST_CERT_POLICY_TYPE_OID_BASE(110); + + /* DoD PKI OIDs - 2.16.840.1.101.2.1.11.X */ + #define DOD_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 2, 1, 11, num} + static const byte extCertPolicyDodMediumOid[] = + DOD_POLICY_TYPE_OID_BASE(5); + static const byte extCertPolicyDodMediumHardwareOid[] = + DOD_POLICY_TYPE_OID_BASE(9); + static const byte extCertPolicyDodPivAuthOid[] = + DOD_POLICY_TYPE_OID_BASE(10); + static const byte extCertPolicyDodMediumNpeOid[] = + DOD_POLICY_TYPE_OID_BASE(17); + static const byte extCertPolicyDodMedium2048Oid[] = + DOD_POLICY_TYPE_OID_BASE(18); + static const byte extCertPolicyDodMediumHardware2048Oid[] = + DOD_POLICY_TYPE_OID_BASE(19); + static const byte extCertPolicyDodPivAuth2048Oid[] = + DOD_POLICY_TYPE_OID_BASE(20); + static const byte extCertPolicyDodPeerInteropOid[] = + DOD_POLICY_TYPE_OID_BASE(31); + static const byte extCertPolicyDodMediumNpe112Oid[] = + DOD_POLICY_TYPE_OID_BASE(36); + static const byte extCertPolicyDodMediumNpe128Oid[] = + DOD_POLICY_TYPE_OID_BASE(37); + static const byte extCertPolicyDodMediumNpe192Oid[] = + DOD_POLICY_TYPE_OID_BASE(38); + static const byte extCertPolicyDodMedium112Oid[] = + DOD_POLICY_TYPE_OID_BASE(39); + static const byte extCertPolicyDodMedium128Oid[] = + DOD_POLICY_TYPE_OID_BASE(40); + static const byte extCertPolicyDodMedium192Oid[] = + DOD_POLICY_TYPE_OID_BASE(41); + static const byte extCertPolicyDodMediumHardware112Oid[] = + DOD_POLICY_TYPE_OID_BASE(42); + static const byte extCertPolicyDodMediumHardware128Oid[] = + DOD_POLICY_TYPE_OID_BASE(43); + static const byte extCertPolicyDodMediumHardware192Oid[] = + DOD_POLICY_TYPE_OID_BASE(44); + static const byte extCertPolicyDodAdminOid[] = + DOD_POLICY_TYPE_OID_BASE(59); + static const byte extCertPolicyDodInternalNpe112Oid[] = + DOD_POLICY_TYPE_OID_BASE(60); + static const byte extCertPolicyDodInternalNpe128Oid[] = + DOD_POLICY_TYPE_OID_BASE(61); + static const byte extCertPolicyDodInternalNpe192Oid[] = + DOD_POLICY_TYPE_OID_BASE(62); + + /* ECA PKI OIDs - 2.16.840.1.101.3.2.1.12.X */ + #define ECA_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 3, 2, 1, 12, num} + static const byte extCertPolicyEcaMediumOid[] = + ECA_POLICY_TYPE_OID_BASE(1); + static const byte extCertPolicyEcaMediumHardwareOid[] = + ECA_POLICY_TYPE_OID_BASE(2); + static const byte extCertPolicyEcaMediumTokenOid[] = + ECA_POLICY_TYPE_OID_BASE(3); + static const byte extCertPolicyEcaMediumSha256Oid[] = + ECA_POLICY_TYPE_OID_BASE(4); + static const byte extCertPolicyEcaMediumTokenSha256Oid[] = + ECA_POLICY_TYPE_OID_BASE(5); + static const byte extCertPolicyEcaMediumHardwarePiviOid[] = + ECA_POLICY_TYPE_OID_BASE(6); + static const byte extCertPolicyEcaContentSigningPiviOid[] = + ECA_POLICY_TYPE_OID_BASE(8); + static const byte extCertPolicyEcaMediumDeviceSha256Oid[] = + ECA_POLICY_TYPE_OID_BASE(9); + static const byte extCertPolicyEcaMediumHardwareSha256Oid[] = + ECA_POLICY_TYPE_OID_BASE(10); + + /* Department of State PKI OIDs - 2.16.840.1.101.3.2.1.6.X */ + #define STATE_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 3, 2, 1, 6, num} + static const byte extCertPolicyStateBasicOid[] = + STATE_POLICY_TYPE_OID_BASE(1); + static const byte extCertPolicyStateLowOid[] = + STATE_POLICY_TYPE_OID_BASE(2); + static const byte extCertPolicyStateModerateOid[] = + STATE_POLICY_TYPE_OID_BASE(3); + static const byte extCertPolicyStateHighOid[] = + STATE_POLICY_TYPE_OID_BASE(4); + static const byte extCertPolicyStateMedHwOid[] = + STATE_POLICY_TYPE_OID_BASE(12); + static const byte extCertPolicyStateMediumDeviceHardwareOid[] = + STATE_POLICY_TYPE_OID_BASE(38); + + /* U.S. Treasury SSP PKI OIDs - 2.16.840.1.101.3.2.1.5.X */ + #define TREASURY_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 101, 3, 2, 1, 5, num} + static const byte extCertPolicyTreasuryMediumHardwareOid[] = + TREASURY_POLICY_TYPE_OID_BASE(4); + static const byte extCertPolicyTreasuryHighOid[] = + TREASURY_POLICY_TYPE_OID_BASE(5); + static const byte extCertPolicyTreasuryPiviHardwareOid[] = + TREASURY_POLICY_TYPE_OID_BASE(10); + static const byte extCertPolicyTreasuryPiviContentSigningOid[] = + TREASURY_POLICY_TYPE_OID_BASE(12); + + /* Boeing PKI OIDs - 1.3.6.1.4.1.73.15.3.1.X */ + #define BOEING_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 73, 15, 3, 1, num} + static const byte extCertPolicyBoeingMediumHardwareSha256Oid[] = + BOEING_POLICY_TYPE_OID_BASE(12); + static const byte extCertPolicyBoeingMediumHardwareContentSigningSha256Oid[] = + BOEING_POLICY_TYPE_OID_BASE(17); + + /* Carillon Federal Services OIDs - 1.3.6.1.4.1.45606.3.1.X */ + #define CARILLON_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 130, 228, 38, 3, 1, num} + static const byte extCertPolicyCarillonMediumhw256Oid[] = + CARILLON_POLICY_TYPE_OID_BASE(12); + static const byte extCertPolicyCarillonAivhwOid[] = + CARILLON_POLICY_TYPE_OID_BASE(20); + static const byte extCertPolicyCarillonAivcontentOid[] = + CARILLON_POLICY_TYPE_OID_BASE(22); + + /* Carillon Information Security OIDs - 1.3.6.1.4.1.25054.3.1.X */ + #define CIS_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 129, 195, 94, 3, 1, num} + static const byte extCertPolicyCisMediumhw256Oid[] = + CIS_POLICY_TYPE_OID_BASE(12); + static const byte extCertPolicyCisMeddevhw256Oid[] = + CIS_POLICY_TYPE_OID_BASE(14); + static const byte extCertPolicyCisIcecapHwOid[] = + CIS_POLICY_TYPE_OID_BASE(20); + static const byte extCertPolicyCisIcecapContentOid[] = + CIS_POLICY_TYPE_OID_BASE(22); + + /* CertiPath Bridge OIDs - 1.3.6.1.4.1.24019.1.1.1.X */ + #define CERTIPATH_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 129, 187, 83, 1, 1, 1, num} + static const byte extCertPolicyCertipathMediumhwOid[] = + CERTIPATH_POLICY_TYPE_OID_BASE(2); + static const byte extCertPolicyCertipathHighhwOid[] = + CERTIPATH_POLICY_TYPE_OID_BASE(3); + static const byte extCertPolicyCertipathIcecapHwOid[] = + CERTIPATH_POLICY_TYPE_OID_BASE(7); + static const byte extCertPolicyCertipathIcecapContentOid[] = + CERTIPATH_POLICY_TYPE_OID_BASE(9); + static const byte extCertPolicyCertipathVarMediumhwOid[] = + CERTIPATH_POLICY_TYPE_OID_BASE(18); + static const byte extCertPolicyCertipathVarHighhwOid[] = + CERTIPATH_POLICY_TYPE_OID_BASE(19); + + /* TSCP Bridge OIDs - 1.3.6.1.4.1.38099.1.1.1.X */ + #define TSCP_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 130, 169, 83, 1, 1, 1, num} + static const byte extCertPolicyTscpMediumhwOid[] = + TSCP_POLICY_TYPE_OID_BASE(2); + static const byte extCertPolicyTscpPiviOid[] = + TSCP_POLICY_TYPE_OID_BASE(5); + static const byte extCertPolicyTscpPiviContentOid[] = + TSCP_POLICY_TYPE_OID_BASE(7); + + /* DigiCert NFI PKI OIDs - 2.16.840.1.113733.1.7.23.3.1.X */ + #define DIGICERT_NFI_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 134, 248, 69, 1, 7, 23, 3, 1, num} + static const byte extCertPolicyDigicertNfiMediumHardwareOid[] = + DIGICERT_NFI_POLICY_TYPE_OID_BASE(7); + static const byte extCertPolicyDigicertNfiAuthOid[] = + DIGICERT_NFI_POLICY_TYPE_OID_BASE(13); + static const byte extCertPolicyDigicertNfiPiviHardwareOid[] = + DIGICERT_NFI_POLICY_TYPE_OID_BASE(18); + static const byte extCertPolicyDigicertNfiPiviContentSigningOid[] = + DIGICERT_NFI_POLICY_TYPE_OID_BASE(20); + static const byte extCertPolicyDigicertNfiMediumDevicesHardwareOid[] = + DIGICERT_NFI_POLICY_TYPE_OID_BASE(36); + + /* Entrust Managed Services NFI PKI OIDs - 2.16.840.1.114027.200.3.10.7.X */ + #define ENTRUST_NFI_POLICY_TYPE_OID_BASE(num) {96, 134, 72, 1, 134, 250, 107, 129, 72, 3, 10, 7, num} + static const byte extCertPolicyEntrustNfiMediumHardwareOid[] = + ENTRUST_NFI_POLICY_TYPE_OID_BASE(2); + static const byte extCertPolicyEntrustNfiMediumAuthenticationOid[] = + ENTRUST_NFI_POLICY_TYPE_OID_BASE(4); + static const byte extCertPolicyEntrustNfiPiviHardwareOid[] = + ENTRUST_NFI_POLICY_TYPE_OID_BASE(6); + static const byte extCertPolicyEntrustNfiPiviContentSigningOid[] = + ENTRUST_NFI_POLICY_TYPE_OID_BASE(9); + static const byte extCertPolicyEntrustNfiMediumDevicesHwOid[] = + ENTRUST_NFI_POLICY_TYPE_OID_BASE(16); + + /* Exostar LLC PKI OIDs - 1.3.6.1.4.1.13948.1.1.1.X */ + #define EXOSTAR_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 236, 124, 1, 1, 1, num} + static const byte extCertPolicyExostarMediumHardwareSha2Oid[] = + EXOSTAR_POLICY_TYPE_OID_BASE(6); + + /* IdenTrust NFI OIDs - 2.16.840.1.113839.0.100.X.Y */ + #define IDENTRUST_POLICY_TYPE_OID_BASE(num1, num2) {96, 134, 72, 1, 134, 249, 47, 0, 100, num1, num2} + static const byte extCertPolicyIdentrustMediumhwSignOid[] = + IDENTRUST_POLICY_TYPE_OID_BASE(12, 1); + static const byte extCertPolicyIdentrustMediumhwEncOid[] = + IDENTRUST_POLICY_TYPE_OID_BASE(12, 2); + static const byte extCertPolicyIdentrustPiviHwIdOid[] = + IDENTRUST_POLICY_TYPE_OID_BASE(18, 0); + static const byte extCertPolicyIdentrustPiviHwSignOid[] = + IDENTRUST_POLICY_TYPE_OID_BASE(18, 1); + static const byte extCertPolicyIdentrustPiviHwEncOid[] = + IDENTRUST_POLICY_TYPE_OID_BASE(18, 2); + static const byte extCertPolicyIdentrustPiviContentOid[] = + IDENTRUST_POLICY_TYPE_OID_BASE(20, 1); + + /* Lockheed Martin PKI OIDs - 1.3.6.1.4.1.103.100.1.1.3.X */ + #define LOCKHEED_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 103, 100, 1, 1, 3, num} + static const byte extCertPolicyLockheedMediumAssuranceHardwareOid[] = + LOCKHEED_POLICY_TYPE_OID_BASE(3); + + /* Northrop Grumman PKI OIDs - 1.3.6.1.4.1.16334.509.2.X */ + #define NORTHROP_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 255, 78, 131, 125, 2, num} + static const byte extCertPolicyNorthropMediumAssurance256HardwareTokenOid[] = + NORTHROP_POLICY_TYPE_OID_BASE(8); + static const byte extCertPolicyNorthropPiviAssurance256HardwareTokenOid[] = + NORTHROP_POLICY_TYPE_OID_BASE(9); + static const byte extCertPolicyNorthropPiviAssurance256ContentSigningOid[] = + NORTHROP_POLICY_TYPE_OID_BASE(11); + static const byte extCertPolicyNorthropMediumAssurance384HardwareTokenOid[] = + NORTHROP_POLICY_TYPE_OID_BASE(14); + + /* Raytheon PKI OIDs - 1.3.6.1.4.1.1569.10.1.X and 1.3.6.1.4.1.26769.10.1.X */ + #define RAYTHEON_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 140, 33, 10, 1, num} + static const byte extCertPolicyRaytheonMediumHardwareOid[] = + RAYTHEON_POLICY_TYPE_OID_BASE(12); + static const byte extCertPolicyRaytheonMediumDeviceHardwareOid[] = + RAYTHEON_POLICY_TYPE_OID_BASE(18); + + #define RAYTHEON_SHA2_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 129, 209, 17, 10, 1, num} + static const byte extCertPolicyRaytheonSha2MediumHardwareOid[] = + RAYTHEON_SHA2_POLICY_TYPE_OID_BASE(12); + static const byte extCertPolicyRaytheonSha2MediumDeviceHardwareOid[] = + RAYTHEON_SHA2_POLICY_TYPE_OID_BASE(18); + + /* WidePoint NFI PKI OIDs - 1.3.6.1.4.1.3922.1.1.1.X */ + #define WIDEPOINT_NFI_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 158, 82, 1, 1, 1, num} + static const byte extCertPolicyWidepointNfiMediumHardwareOid[] = + WIDEPOINT_NFI_POLICY_TYPE_OID_BASE(12); + static const byte extCertPolicyWidepointNfiPiviHardwareOid[] = + WIDEPOINT_NFI_POLICY_TYPE_OID_BASE(18); + static const byte extCertPolicyWidepointNfiPiviContentSigningOid[] = + WIDEPOINT_NFI_POLICY_TYPE_OID_BASE(20); + static const byte extCertPolicyWidepointNfiMediumDevicesHardwareOid[] = + WIDEPOINT_NFI_POLICY_TYPE_OID_BASE(38); + + /* Australian Defence Organisation PKI OIDs - 1.2.36.1.334.1.2.X.X */ + #define ADO_POLICY_TYPE_OID_BASE(type, num) {42, 36, 1, 130, 78, 1, 2, type, num} + static const byte extCertPolicyAdoIndividualMediumAssuranceOid[] = + ADO_POLICY_TYPE_OID_BASE(1, 2); + static const byte extCertPolicyAdoIndividualHighAssuranceOid[] = + ADO_POLICY_TYPE_OID_BASE(1, 3); + static const byte extCertPolicyAdoResourceMediumAssuranceOid[] = + ADO_POLICY_TYPE_OID_BASE(2, 2); + + /* Comodo Ltd PKI OID 1.3.6.1.4.1.6449.1.2.1.3.4 */ + #define COMODO_POLICY_TYPE_OID_BASE(num) {43, 6, 1, 4, 1, 178, 49, 1, 2, 1, 3, num} + static const byte extCertPolicyComodoLtdOid[] = + COMODO_POLICY_TYPE_OID_BASE(4); + + /* Netherlands Ministry of Defence PKI OIDs - 2.16.528.1.1003.1.2.5.X */ + #define NL_MOD_POLICY_TYPE_OID_BASE(num) {96, 132, 16, 1, 135, 107, 1, 2, 5, num} + static const byte extCertPolicyNlModAuthenticityOid[] = + NL_MOD_POLICY_TYPE_OID_BASE(1); + static const byte extCertPolicyNlModIrrefutabilityOid[] = + NL_MOD_POLICY_TYPE_OID_BASE(2); + static const byte extCertPolicyNlModConfidentialityOid[] = + NL_MOD_POLICY_TYPE_OID_BASE(3); #endif /* WOLFSSL_FPKI */ /* certAltNameType */ @@ -4619,6 +4894,11 @@ static const byte dcOid[] = {9, 146, 38, 137, 147, 242, 44, 100, 1, 25}; /* doma * * Use oidIgnoreType to autofail. * + * Note that while this function currently handles a large + * number of FPKI certificate policy OIDs, these OIDs are not + * currently being handled in the code, they are just recognized + * as valid OIDs. + * * @param [in] id OID id. * @param [in] type Type of OID (enum Oid_Types). * @param [out] oidSz Length of OID byte array returned. @@ -5295,7 +5575,35 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz) oid = extCertPolicyAnyOid; *oidSz = sizeof(extCertPolicyAnyOid); break; + case CP_ISRG_DOMAIN_VALID: + oid = extCertPolicyIsrgDomainValid; + *oidSz = sizeof(extCertPolicyIsrgDomainValid); + break; #if defined(WOLFSSL_FPKI) + case CP_FPKI_HIGH_ASSURANCE_OID: + oid = extCertPolicyFpkiHighAssuranceOid; + *oidSz = sizeof(extCertPolicyFpkiHighAssuranceOid); + break; + case CP_FPKI_COMMON_HARDWARE_OID: + oid = extCertPolicyFpkiCommonHardwareOid; + *oidSz = sizeof(extCertPolicyFpkiCommonHardwareOid); + break; + case CP_FPKI_MEDIUM_HARDWARE_OID: + oid = extCertPolicyFpkiMediumHardwareOid; + *oidSz = sizeof(extCertPolicyFpkiMediumHardwareOid); + break; + case CP_FPKI_COMMON_HIGH_OID: + oid = extCertPolicyFpkiCommonHighOid; + *oidSz = sizeof(extCertPolicyFpkiCommonHighOid); + break; + case CP_FPKI_COMMON_DEVICES_HARDWARE_OID: + oid = extCertPolicyFpkiCommonDevicesHardwareOid; + *oidSz = sizeof(extCertPolicyFpkiCommonDevicesHardwareOid); + break; + case CP_FPKI_COMMON_PIV_CONTENT_SIGNING_OID: + oid = extCertPolicyFpkiCommonPivContentSigningOid; + *oidSz = sizeof(extCertPolicyFpkiCommonPivContentSigningOid); + break; case CP_FPKI_COMMON_AUTH_OID: oid = extCertPolicyFpkiCommonAuthOid; *oidSz = sizeof(extCertPolicyFpkiCommonAuthOid); @@ -5312,6 +5620,441 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz) oid = extCertPolicyFpkiPiviAuthOid; *oidSz = sizeof(extCertPolicyFpkiPiviAuthOid); break; + case CP_FPKI_AUTH_TEST_OID: + oid = extCertPolicyFpkiAuthTestOid; + *oidSz = sizeof(extCertPolicyFpkiAuthTestOid); + break; + case CP_FPKI_CARDAUTH_TEST_OID: + oid = extCertPolicyFpkiCardauthTestOid; + *oidSz = sizeof(extCertPolicyFpkiCardauthTestOid); + break; + case CP_FPKI_PIV_CONTENT_TEST_OID: + oid = extCertPolicyFpkiPivContentTestOid; + *oidSz = sizeof(extCertPolicyFpkiPivContentTestOid); + break; + case CP_FPKI_PIV_AUTH_DERIVED_TEST_OID: + oid = extCertPolicyFpkiAuthDerivedTestOid; + *oidSz = sizeof(extCertPolicyFpkiAuthDerivedTestOid); + break; + case CP_FPKI_PIV_AUTH_DERIVED_HW_TEST_OID: + oid = extCertPolicyFpkiAuthDerivedHwTestOid; + *oidSz = sizeof(extCertPolicyFpkiAuthDerivedHwTestOid); + break; + case CP_DOD_MEDIUM_OID: + oid = extCertPolicyDodMediumOid; + *oidSz = sizeof(extCertPolicyDodMediumOid); + break; + case CP_DOD_MEDIUM_HARDWARE_OID: + oid = extCertPolicyDodMediumHardwareOid; + *oidSz = sizeof(extCertPolicyDodMediumHardwareOid); + break; + case CP_DOD_PIV_AUTH_OID: + oid = extCertPolicyDodPivAuthOid; + *oidSz = sizeof(extCertPolicyDodPivAuthOid); + break; + case CP_DOD_MEDIUM_NPE_OID: + oid = extCertPolicyDodMediumNpeOid; + *oidSz = sizeof(extCertPolicyDodMediumNpeOid); + break; + case CP_DOD_MEDIUM_2048_OID: + oid = extCertPolicyDodMedium2048Oid; + *oidSz = sizeof(extCertPolicyDodMedium2048Oid); + break; + case CP_DOD_MEDIUM_HARDWARE_2048_OID: + oid = extCertPolicyDodMediumHardware2048Oid; + *oidSz = sizeof(extCertPolicyDodMediumHardware2048Oid); + break; + case CP_DOD_PIV_AUTH_2048_OID: + oid = extCertPolicyDodPivAuth2048Oid; + *oidSz = sizeof(extCertPolicyDodPivAuth2048Oid); + break; + case CP_DOD_PEER_INTEROP_OID: + oid = extCertPolicyDodPeerInteropOid; + *oidSz = sizeof(extCertPolicyDodPeerInteropOid); + break; + case CP_DOD_MEDIUM_NPE_112_OID: + oid = extCertPolicyDodMediumNpe112Oid; + *oidSz = sizeof(extCertPolicyDodMediumNpe112Oid); + break; + case CP_DOD_MEDIUM_NPE_128_OID: + oid = extCertPolicyDodMediumNpe128Oid; + *oidSz = sizeof(extCertPolicyDodMediumNpe128Oid); + break; + case CP_DOD_MEDIUM_NPE_192_OID: + oid = extCertPolicyDodMediumNpe192Oid; + *oidSz = sizeof(extCertPolicyDodMediumNpe192Oid); + break; + case CP_DOD_MEDIUM_112_OID: + oid = extCertPolicyDodMedium112Oid; + *oidSz = sizeof(extCertPolicyDodMedium112Oid); + break; + case CP_DOD_MEDIUM_128_OID: + oid = extCertPolicyDodMedium128Oid; + *oidSz = sizeof(extCertPolicyDodMedium128Oid); + break; + case CP_DOD_MEDIUM_192_OID: + oid = extCertPolicyDodMedium192Oid; + *oidSz = sizeof(extCertPolicyDodMedium192Oid); + break; + case CP_DOD_MEDIUM_HARDWARE_112_OID: + oid = extCertPolicyDodMediumHardware112Oid; + *oidSz = sizeof(extCertPolicyDodMediumHardware112Oid); + break; + case CP_DOD_MEDIUM_HARDWARE_128_OID: + oid = extCertPolicyDodMediumHardware128Oid; + *oidSz = sizeof(extCertPolicyDodMediumHardware128Oid); + break; + case CP_DOD_MEDIUM_HARDWARE_192_OID: + oid = extCertPolicyDodMediumHardware192Oid; + *oidSz = sizeof(extCertPolicyDodMediumHardware192Oid); + break; + case CP_DOD_ADMIN_OID: + oid = extCertPolicyDodAdminOid; + *oidSz = sizeof(extCertPolicyDodAdminOid); + break; + case CP_DOD_INTERNAL_NPE_112_OID: + oid = extCertPolicyDodInternalNpe112Oid; + *oidSz = sizeof(extCertPolicyDodInternalNpe112Oid); + break; + case CP_DOD_INTERNAL_NPE_128_OID: + oid = extCertPolicyDodInternalNpe128Oid; + *oidSz = sizeof(extCertPolicyDodInternalNpe128Oid); + break; + case CP_DOD_INTERNAL_NPE_192_OID: + oid = extCertPolicyDodInternalNpe192Oid; + *oidSz = sizeof(extCertPolicyDodInternalNpe192Oid); + break; + case CP_ECA_MEDIUM_OID: + oid = extCertPolicyEcaMediumOid; + *oidSz = sizeof(extCertPolicyEcaMediumOid); + break; + case CP_ECA_MEDIUM_HARDWARE_OID: + oid = extCertPolicyEcaMediumHardwareOid; + *oidSz = sizeof(extCertPolicyEcaMediumHardwareOid); + break; + case CP_ECA_MEDIUM_TOKEN_OID: + oid = extCertPolicyEcaMediumTokenOid; + *oidSz = sizeof(extCertPolicyEcaMediumTokenOid); + break; + case CP_ECA_MEDIUM_SHA256_OID: + oid = extCertPolicyEcaMediumSha256Oid; + *oidSz = sizeof(extCertPolicyEcaMediumSha256Oid); + break; + case CP_ECA_MEDIUM_TOKEN_SHA256_OID: + oid = extCertPolicyEcaMediumTokenSha256Oid; + *oidSz = sizeof(extCertPolicyEcaMediumTokenSha256Oid); + break; + case CP_ECA_MEDIUM_HARDWARE_PIVI_OID: + oid = extCertPolicyEcaMediumHardwarePiviOid; + *oidSz = sizeof(extCertPolicyEcaMediumHardwarePiviOid); + break; + case CP_ECA_CONTENT_SIGNING_PIVI_OID: + oid = extCertPolicyEcaContentSigningPiviOid; + *oidSz = sizeof(extCertPolicyEcaContentSigningPiviOid); + break; + case CP_ECA_MEDIUM_DEVICE_SHA256_OID: + oid = extCertPolicyEcaMediumDeviceSha256Oid; + *oidSz = sizeof(extCertPolicyEcaMediumDeviceSha256Oid); + break; + case CP_ECA_MEDIUM_HARDWARE_SHA256_OID: + oid = extCertPolicyEcaMediumHardwareSha256Oid; + *oidSz = sizeof(extCertPolicyEcaMediumHardwareSha256Oid); + break; + + /* Department of State PKI OIDs */ + case CP_STATE_BASIC_OID: + oid = extCertPolicyStateBasicOid; + *oidSz = sizeof(extCertPolicyStateBasicOid); + break; + case CP_STATE_LOW_OID: + oid = extCertPolicyStateLowOid; + *oidSz = sizeof(extCertPolicyStateLowOid); + break; + case CP_STATE_MODERATE_OID: + oid = extCertPolicyStateModerateOid; + *oidSz = sizeof(extCertPolicyStateModerateOid); + break; + case CP_STATE_HIGH_OID: + oid = extCertPolicyStateHighOid; + *oidSz = sizeof(extCertPolicyStateHighOid); + break; + case CP_STATE_MEDHW_OID: + oid = extCertPolicyStateMedHwOid; + *oidSz = sizeof(extCertPolicyStateMedHwOid); + break; + case CP_STATE_MEDDEVHW_OID: + oid = extCertPolicyStateMediumDeviceHardwareOid; + *oidSz = sizeof(extCertPolicyStateMediumDeviceHardwareOid); + break; + + /* U.S. Treasury SSP PKI OIDs */ + case CP_TREAS_MEDIUMHW_OID: + oid = extCertPolicyTreasuryMediumHardwareOid; + *oidSz = sizeof(extCertPolicyTreasuryMediumHardwareOid); + break; + case CP_TREAS_HIGH_OID: + oid = extCertPolicyTreasuryHighOid; + *oidSz = sizeof(extCertPolicyTreasuryHighOid); + break; + case CP_TREAS_PIVI_HW_OID: + oid = extCertPolicyTreasuryPiviHardwareOid; + *oidSz = sizeof(extCertPolicyTreasuryPiviHardwareOid); + break; + case CP_TREAS_PIVI_CONTENT_OID: + oid = extCertPolicyTreasuryPiviContentSigningOid; + *oidSz = sizeof(extCertPolicyTreasuryPiviContentSigningOid); + break; + + /* Boeing PKI OIDs */ + case CP_BOEING_MEDIUMHW_SHA256_OID: + oid = extCertPolicyBoeingMediumHardwareSha256Oid; + *oidSz = sizeof(extCertPolicyBoeingMediumHardwareSha256Oid); + break; + case CP_BOEING_MEDIUMHW_CONTENT_SHA256_OID: + oid = extCertPolicyBoeingMediumHardwareContentSigningSha256Oid; + *oidSz = sizeof(extCertPolicyBoeingMediumHardwareContentSigningSha256Oid); + break; + + /* DigiCert NFI PKI OIDs */ + case CP_DIGICERT_NFSSP_MEDIUMHW_OID: + oid = extCertPolicyDigicertNfiMediumHardwareOid; + *oidSz = sizeof(extCertPolicyDigicertNfiMediumHardwareOid); + break; + case CP_DIGICERT_NFSSP_AUTH_OID: + oid = extCertPolicyDigicertNfiAuthOid; + *oidSz = sizeof(extCertPolicyDigicertNfiAuthOid); + break; + case CP_DIGICERT_NFSSP_PIVI_HW_OID: + oid = extCertPolicyDigicertNfiPiviHardwareOid; + *oidSz = sizeof(extCertPolicyDigicertNfiPiviHardwareOid); + break; + case CP_DIGICERT_NFSSP_PIVI_CONTENT_OID: + oid = extCertPolicyDigicertNfiPiviContentSigningOid; + *oidSz = sizeof(extCertPolicyDigicertNfiPiviContentSigningOid); + break; + case CP_DIGICERT_NFSSP_MEDDEVHW_OID: + oid = extCertPolicyDigicertNfiMediumDevicesHardwareOid; + *oidSz = sizeof(extCertPolicyDigicertNfiMediumDevicesHardwareOid); + break; + + /* Entrust Managed Services NFI PKI OIDs */ + case CP_ENTRUST_NFSSP_MEDIUMHW_OID: + oid = extCertPolicyEntrustNfiMediumHardwareOid; + *oidSz = sizeof(extCertPolicyEntrustNfiMediumHardwareOid); + break; + case CP_ENTRUST_NFSSP_MEDAUTH_OID: + oid = extCertPolicyEntrustNfiMediumAuthenticationOid; + *oidSz = sizeof(extCertPolicyEntrustNfiMediumAuthenticationOid); + break; + case CP_ENTRUST_NFSSP_PIVI_HW_OID: + oid = extCertPolicyEntrustNfiPiviHardwareOid; + *oidSz = sizeof(extCertPolicyEntrustNfiPiviHardwareOid); + break; + case CP_ENTRUST_NFSSP_PIVI_CONTENT_OID: + oid = extCertPolicyEntrustNfiPiviContentSigningOid; + *oidSz = sizeof(extCertPolicyEntrustNfiPiviContentSigningOid); + break; + case CP_ENTRUST_NFSSP_MEDDEVHW_OID: + oid = extCertPolicyEntrustNfiMediumDevicesHwOid; + *oidSz = sizeof(extCertPolicyEntrustNfiMediumDevicesHwOid); + break; + + /* Exostar LLC PKI OIDs */ + case CP_EXOSTAR_MEDIUMHW_SHA2_OID: + oid = extCertPolicyExostarMediumHardwareSha2Oid; + *oidSz = sizeof(extCertPolicyExostarMediumHardwareSha2Oid); + break; + + /* Lockheed Martin PKI OIDs */ + case CP_LOCKHEED_MEDIUMHW_OID: + oid = extCertPolicyLockheedMediumAssuranceHardwareOid; + *oidSz = sizeof(extCertPolicyLockheedMediumAssuranceHardwareOid); + break; + + /* Northrop Grumman PKI OIDs */ + case CP_NORTHROP_MEDIUM_256_HW_OID: + oid = extCertPolicyNorthropMediumAssurance256HardwareTokenOid; + *oidSz = sizeof(extCertPolicyNorthropMediumAssurance256HardwareTokenOid); + break; + case CP_NORTHROP_PIVI_256_HW_OID: + oid = extCertPolicyNorthropPiviAssurance256HardwareTokenOid; + *oidSz = sizeof(extCertPolicyNorthropPiviAssurance256HardwareTokenOid); + break; + case CP_NORTHROP_PIVI_256_CONTENT_OID: + oid = extCertPolicyNorthropPiviAssurance256ContentSigningOid; + *oidSz = sizeof(extCertPolicyNorthropPiviAssurance256ContentSigningOid); + break; + case CP_NORTHROP_MEDIUM_384_HW_OID: + oid = extCertPolicyNorthropMediumAssurance384HardwareTokenOid; + *oidSz = sizeof(extCertPolicyNorthropMediumAssurance384HardwareTokenOid); + break; + + /* Raytheon PKI OIDs */ + case CP_RAYTHEON_MEDIUMHW_OID: + oid = extCertPolicyRaytheonMediumHardwareOid; + *oidSz = sizeof(extCertPolicyRaytheonMediumHardwareOid); + break; + case CP_RAYTHEON_MEDDEVHW_OID: + oid = extCertPolicyRaytheonMediumDeviceHardwareOid; + *oidSz = sizeof(extCertPolicyRaytheonMediumDeviceHardwareOid); + break; + case CP_RAYTHEON_SHA2_MEDIUMHW_OID: + oid = extCertPolicyRaytheonSha2MediumHardwareOid; + *oidSz = sizeof(extCertPolicyRaytheonSha2MediumHardwareOid); + break; + case CP_RAYTHEON_SHA2_MEDDEVHW_OID: + oid = extCertPolicyRaytheonSha2MediumDeviceHardwareOid; + *oidSz = sizeof(extCertPolicyRaytheonSha2MediumDeviceHardwareOid); + break; + + /* WidePoint NFI PKI OIDs */ + case CP_WIDEPOINT_MEDIUMHW_OID: + oid = extCertPolicyWidepointNfiMediumHardwareOid; + *oidSz = sizeof(extCertPolicyWidepointNfiMediumHardwareOid); + break; + case CP_WIDEPOINT_PIVI_HW_OID: + oid = extCertPolicyWidepointNfiPiviHardwareOid; + *oidSz = sizeof(extCertPolicyWidepointNfiPiviHardwareOid); + break; + case CP_WIDEPOINT_PIVI_CONTENT_OID: + oid = extCertPolicyWidepointNfiPiviContentSigningOid; + *oidSz = sizeof(extCertPolicyWidepointNfiPiviContentSigningOid); + break; + case CP_WIDEPOINT_MEDDEVHW_OID: + oid = extCertPolicyWidepointNfiMediumDevicesHardwareOid; + *oidSz = sizeof(extCertPolicyWidepointNfiMediumDevicesHardwareOid); + break; + + /* Australian Defence Organisation PKI OIDs */ + case CP_ADO_MEDIUM_OID: + oid = extCertPolicyAdoIndividualMediumAssuranceOid; + *oidSz = sizeof(extCertPolicyAdoIndividualMediumAssuranceOid); + break; + case CP_ADO_HIGH_OID: + oid = extCertPolicyAdoIndividualHighAssuranceOid; + *oidSz = sizeof(extCertPolicyAdoIndividualHighAssuranceOid); + break; + case CP_ADO_RESOURCE_MEDIUM_OID: + oid = extCertPolicyAdoResourceMediumAssuranceOid; + *oidSz = sizeof(extCertPolicyAdoResourceMediumAssuranceOid); + break; + + /* Netherlands Ministry of Defence PKI OIDs */ + case CP_NL_MOD_AUTH_OID: + oid = extCertPolicyNlModAuthenticityOid; + *oidSz = sizeof(extCertPolicyNlModAuthenticityOid); + break; + case CP_NL_MOD_IRREFUT_OID: + oid = extCertPolicyNlModIrrefutabilityOid; + *oidSz = sizeof(extCertPolicyNlModIrrefutabilityOid); + break; + case CP_NL_MOD_CONFID_OID: + oid = extCertPolicyNlModConfidentialityOid; + *oidSz = sizeof(extCertPolicyNlModConfidentialityOid); + break; + + /* IdenTrust NFI OIDs */ + case CP_IDENTRUST_MEDIUMHW_SIGN_OID: + oid = extCertPolicyIdentrustMediumhwSignOid; + *oidSz = sizeof(extCertPolicyIdentrustMediumhwSignOid); + break; + case CP_IDENTRUST_MEDIUMHW_ENC_OID: + oid = extCertPolicyIdentrustMediumhwEncOid; + *oidSz = sizeof(extCertPolicyIdentrustMediumhwEncOid); + break; + case CP_IDENTRUST_PIVI_HW_ID_OID: + oid = extCertPolicyIdentrustPiviHwIdOid; + *oidSz = sizeof(extCertPolicyIdentrustPiviHwIdOid); + break; + case CP_IDENTRUST_PIVI_HW_SIGN_OID: + oid = extCertPolicyIdentrustPiviHwSignOid; + *oidSz = sizeof(extCertPolicyIdentrustPiviHwSignOid); + break; + case CP_IDENTRUST_PIVI_HW_ENC_OID: + oid = extCertPolicyIdentrustPiviHwEncOid; + *oidSz = sizeof(extCertPolicyIdentrustPiviHwEncOid); + break; + case CP_IDENTRUST_PIVI_CONTENT_OID: + oid = extCertPolicyIdentrustPiviContentOid; + *oidSz = sizeof(extCertPolicyIdentrustPiviContentOid); + break; + + /* TSCP Bridge OIDs */ + case CP_TSCP_MEDIUMHW_OID: + oid = extCertPolicyTscpMediumhwOid; + *oidSz = sizeof(extCertPolicyTscpMediumhwOid); + break; + case CP_TSCP_PIVI_OID: + oid = extCertPolicyTscpPiviOid; + *oidSz = sizeof(extCertPolicyTscpPiviOid); + break; + case CP_TSCP_PIVI_CONTENT_OID: + oid = extCertPolicyTscpPiviContentOid; + *oidSz = sizeof(extCertPolicyTscpPiviContentOid); + break; + + /* Carillon Federal Services OIDs */ + case CP_CARILLON_MEDIUMHW_256_OID: + oid = extCertPolicyCarillonMediumhw256Oid; + *oidSz = sizeof(extCertPolicyCarillonMediumhw256Oid); + break; + case CP_CARILLON_AIVHW_OID: + oid = extCertPolicyCarillonAivhwOid; + *oidSz = sizeof(extCertPolicyCarillonAivhwOid); + break; + case CP_CARILLON_AIVCONTENT_OID: + oid = extCertPolicyCarillonAivcontentOid; + *oidSz = sizeof(extCertPolicyCarillonAivcontentOid); + break; + + /* Carillon Information Security OIDs */ + case CP_CIS_MEDIUMHW_256_OID: + oid = extCertPolicyCisMediumhw256Oid; + *oidSz = sizeof(extCertPolicyCisMediumhw256Oid); + break; + case CP_CIS_MEDDEVHW_256_OID: + oid = extCertPolicyCisMeddevhw256Oid; + *oidSz = sizeof(extCertPolicyCisMeddevhw256Oid); + break; + case CP_CIS_ICECAP_HW_OID: + oid = extCertPolicyCisIcecapHwOid; + *oidSz = sizeof(extCertPolicyCisIcecapHwOid); + break; + case CP_CIS_ICECAP_CONTENT_OID: + oid = extCertPolicyCisIcecapContentOid; + *oidSz = sizeof(extCertPolicyCisIcecapContentOid); + break; + + /* CertiPath Bridge OIDs */ + case CP_CERTIPATH_MEDIUMHW_OID: + oid = extCertPolicyCertipathMediumhwOid; + *oidSz = sizeof(extCertPolicyCertipathMediumhwOid); + break; + case CP_CERTIPATH_HIGHHW_OID: + oid = extCertPolicyCertipathHighhwOid; + *oidSz = sizeof(extCertPolicyCertipathHighhwOid); + break; + case CP_CERTIPATH_ICECAP_HW_OID: + oid = extCertPolicyCertipathIcecapHwOid; + *oidSz = sizeof(extCertPolicyCertipathIcecapHwOid); + break; + case CP_CERTIPATH_ICECAP_CONTENT_OID: + oid = extCertPolicyCertipathIcecapContentOid; + *oidSz = sizeof(extCertPolicyCertipathIcecapContentOid); + break; + case CP_CERTIPATH_VAR_MEDIUMHW_OID: + oid = extCertPolicyCertipathVarMediumhwOid; + *oidSz = sizeof(extCertPolicyCertipathVarMediumhwOid); + break; + case CP_CERTIPATH_VAR_HIGHHW_OID: + oid = extCertPolicyCertipathVarHighhwOid; + *oidSz = sizeof(extCertPolicyCertipathVarHighhwOid); + break; + case CP_COMODO_OID: + oid = extCertPolicyComodoLtdOid; + *oidSz = sizeof(extCertPolicyComodoLtdOid); + break; + /* FPKI OIDs */ #endif /* WOLFSSL_FPKI */ default: break; @@ -5927,6 +6670,169 @@ static int DumpOID(const byte* oidData, word32 oidSz, word32 oid, } #endif /* ASN_DUMP_OID */ +#ifdef WOLFSSL_FPKI +/* Handles the large number of collisions from FPKI certificate policy + * OID sums. Returns a special value (100000 + actual sum) if a + * collision is detected. + * @param [in] oid Buffer holding OID. + * @param [in] oidSz Length of OID data in buffer. + * @param [in] oidSum The sum of the OID being passed in. + */ +static word32 fpkiCertPolOid(const byte* oid, word32 oidSz, word32 oidSum) { + + switch (oidSum) { + case CP_ADO_MEDIUM_OID: + if ((word32)sizeof(extCertPolicyComodoLtdOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyComodoLtdOid, + sizeof(extCertPolicyComodoLtdOid)) == 0) + return CP_COMODO_OID; + break; + case CP_FPKI_HIGH_ASSURANCE_OID: + if ((word32)sizeof(extCertPolicyStateBasicOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyStateBasicOid, + sizeof(extCertPolicyStateBasicOid)) == 0) + return CP_STATE_BASIC_OID; + break; + case CP_FPKI_COMMON_DEVICES_HARDWARE_OID: + if ((word32)sizeof(extCertPolicyDodPeerInteropOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyDodPeerInteropOid, + sizeof(extCertPolicyDodPeerInteropOid)) == 0) + return CP_DOD_PEER_INTEROP_OID; + break; + case CP_FPKI_PIV_AUTH_HW_OID: + if ((word32)sizeof(extCertPolicyDodMediumNpe112Oid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyDodMediumNpe112Oid, + sizeof(extCertPolicyDodMediumNpe112Oid)) == 0) + return CP_DOD_MEDIUM_NPE_112_OID; + else if ((word32)sizeof(extCertPolicyStateMediumDeviceHardwareOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyStateMediumDeviceHardwareOid, + sizeof(extCertPolicyStateMediumDeviceHardwareOid)) == 0) + return CP_STATE_MEDDEVHW_OID; + break; + case CP_FPKI_PIVI_AUTH_OID: + if ((word32)sizeof(extCertPolicyDodMedium128Oid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyDodMedium128Oid, + sizeof(extCertPolicyDodMedium128Oid)) == 0) + return CP_DOD_MEDIUM_128_OID; + break; + case CP_FPKI_COMMON_PIVI_CONTENT_SIGNING_OID: + if ((word32)sizeof(extCertPolicyDodMediumHardware112Oid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyDodMediumHardware112Oid, + sizeof(extCertPolicyDodMediumHardware112Oid)) == 0) + return CP_DOD_MEDIUM_HARDWARE_112_OID; + else if ((word32)sizeof(extCertPolicyCertipathHighhwOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyCertipathHighhwOid, + sizeof(extCertPolicyCertipathHighhwOid)) == 0) + return CP_CERTIPATH_HIGHHW_OID; + break; + case CP_DOD_MEDIUM_OID: + if ((word32)sizeof(extCertPolicyEcaMediumOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyEcaMediumOid, + sizeof(extCertPolicyEcaMediumOid)) == 0) + return CP_ECA_MEDIUM_OID; + break; + case CP_FPKI_COMMON_AUTH_OID: + if ((word32)sizeof(extCertPolicyEcaMediumSha256Oid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyEcaMediumSha256Oid, + sizeof(extCertPolicyEcaMediumSha256Oid)) == 0) + return CP_ECA_MEDIUM_SHA256_OID; + break; + case CP_FPKI_MEDIUM_HARDWARE_OID: + if ((word32)sizeof(extCertPolicyEcaMediumTokenOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyEcaMediumTokenOid, + sizeof(extCertPolicyEcaMediumTokenOid)) == 0) + return CP_ECA_MEDIUM_TOKEN_OID; + else if ((word32)sizeof(extCertPolicyTreasuryPiviHardwareOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyTreasuryPiviHardwareOid, + sizeof(extCertPolicyTreasuryPiviHardwareOid)) == 0) + return CP_TREAS_PIVI_HW_OID; + break; + case CP_DOD_MEDIUM_HARDWARE_OID: + if ((word32)sizeof(extCertPolicyEcaMediumTokenSha256Oid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyEcaMediumTokenSha256Oid, + sizeof(extCertPolicyEcaMediumTokenSha256Oid)) == 0) + return CP_ECA_MEDIUM_TOKEN_SHA256_OID; + else if ((word32)sizeof(extCertPolicyTreasuryPiviContentSigningOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyTreasuryPiviContentSigningOid, + sizeof(extCertPolicyTreasuryPiviContentSigningOid)) == 0) + return CP_TREAS_PIVI_CONTENT_OID; + break; + case CP_DOD_PIV_AUTH_OID: + if ((word32)sizeof(extCertPolicyEcaMediumHardwarePiviOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyEcaMediumHardwarePiviOid, + sizeof(extCertPolicyEcaMediumHardwarePiviOid)) == 0) + return CP_ECA_MEDIUM_HARDWARE_PIVI_OID; + else if ((word32)sizeof(extCertPolicyStateMedHwOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyStateMedHwOid, + sizeof(extCertPolicyStateMedHwOid)) == 0) + return CP_STATE_MEDHW_OID; + break; + case CP_FPKI_COMMON_HARDWARE_OID: + if ((word32)sizeof(extCertPolicyStateHighOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyStateHighOid, + sizeof(extCertPolicyStateHighOid)) == 0) + return CP_STATE_HIGH_OID; + else if ((word32)sizeof(extCertPolicyTreasuryHighOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyTreasuryHighOid, + sizeof(extCertPolicyTreasuryHighOid)) == 0) + return CP_TREAS_HIGH_OID; + break; + case CP_ECA_MEDIUM_HARDWARE_OID: + if ((word32)sizeof(extCertPolicyExostarMediumHardwareSha2Oid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyExostarMediumHardwareSha2Oid, + sizeof(extCertPolicyExostarMediumHardwareSha2Oid)) == 0) + return CP_EXOSTAR_MEDIUMHW_SHA2_OID; + break; + case CP_ADO_HIGH_OID: + if ((word32)sizeof(extCertPolicyAdoResourceMediumAssuranceOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyAdoResourceMediumAssuranceOid, + sizeof(extCertPolicyAdoResourceMediumAssuranceOid)) == 0) + return CP_ADO_RESOURCE_MEDIUM_OID; + break; + case CP_DOD_ADMIN_OID: + if ((word32)sizeof(extCertPolicyCarillonAivcontentOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyCarillonAivcontentOid, + sizeof(extCertPolicyCarillonAivcontentOid)) == 0) + return CP_CARILLON_AIVCONTENT_OID; + break; + case CP_TREAS_MEDIUMHW_OID: + if ((word32)sizeof(extCertPolicyStateModerateOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyStateModerateOid, + sizeof(extCertPolicyStateModerateOid)) == 0) + return CP_STATE_MODERATE_OID; + break; + case CP_CIS_ICECAP_HW_OID: + if ((word32)sizeof(extCertPolicyNlModIrrefutabilityOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyNlModIrrefutabilityOid, + sizeof(extCertPolicyNlModIrrefutabilityOid)) == 0) + return CP_NL_MOD_IRREFUT_OID; + break; + case CP_DOD_MEDIUM_192_OID: + if ((word32)sizeof(extCertPolicyCertipathMediumhwOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyCertipathMediumhwOid, + sizeof(extCertPolicyCertipathMediumhwOid)) == 0) + return CP_CERTIPATH_MEDIUMHW_OID; + break; + case CP_CARILLON_AIVHW_OID: + if ((word32)sizeof(extCertPolicyCertipathVarMediumhwOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyCertipathVarMediumhwOid, + sizeof(extCertPolicyCertipathVarMediumhwOid)) == 0) + return CP_CERTIPATH_VAR_MEDIUMHW_OID; + break; + case CP_ISRG_DOMAIN_VALID: + if ((word32)sizeof(extCertPolicyEcaContentSigningPiviOid) == (word32)oidSz && + XMEMCMP(oid, extCertPolicyEcaContentSigningPiviOid, + sizeof(extCertPolicyEcaContentSigningPiviOid)) == 0) + return CP_ECA_CONTENT_SIGNING_PIVI_OID; + break; + default: + break; + } + + return 0; +} +#endif + /* Get the OID data and verify it is of the type specified when compiled in. * * @param [in] input Buffer holding OID. @@ -5952,13 +6858,13 @@ static int GetOID(const byte* input, word32* inOutIdx, word32* oid, const byte* checkOid = NULL; word32 checkOidSz; #endif /* NO_VERIFY_OID */ -#if defined(HAVE_SPHINCS) +#if defined(HAVE_SPHINCS) || defined(WOLFSSL_FPKI) word32 found_collision = 0; #endif (void)oidType; *oid = 0; -#ifndef NO_VERIFY_OID +#if !defined(NO_VERIFY_OID) || defined(WOLFSSL_FPKI) /* Keep references to OID data and length for check. */ actualOid = &input[idx]; actualOidSz = (word32)length; @@ -5987,7 +6893,16 @@ static int GetOID(const byte* input, word32* inOutIdx, word32* oid, idx++; } -#ifdef HAVE_SPHINCS +#ifdef WOLFSSL_FPKI + /* Due to the large number of OIDs for FPKI certificate policy, there + are multiple collsisions. Handle them in a dedicated function, + if a collision is detected, the OID is adjusted. */ + if (oidType == oidCertPolicyType) { + found_collision = fpkiCertPolOid(actualOid, actualOidSz, *oid); + } +#endif + +#if defined(HAVE_SPHINCS) || defined(WOLFSSL_FPKI) if (found_collision) { *oid = found_collision; } @@ -6593,16 +7508,16 @@ static int DecodeRsaPssParams(const byte* params, word32 sz, defined(WOLFSSL_KCAPI_RSA) || defined(WOLFSSL_SE050))) /* Byte offset of numbers in RSA key. */ size_t rsaIntOffset[] = { - OFFSETOF(RsaKey, n), - OFFSETOF(RsaKey, e), + WC_OFFSETOF(RsaKey, n), + WC_OFFSETOF(RsaKey, e), #ifndef WOLFSSL_RSA_PUBLIC_ONLY - OFFSETOF(RsaKey, d), - OFFSETOF(RsaKey, p), - OFFSETOF(RsaKey, q), + WC_OFFSETOF(RsaKey, d), + WC_OFFSETOF(RsaKey, p), + WC_OFFSETOF(RsaKey, q), #if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM) - OFFSETOF(RsaKey, dP), - OFFSETOF(RsaKey, dQ), - OFFSETOF(RsaKey, u) + WC_OFFSETOF(RsaKey, dP), + WC_OFFSETOF(RsaKey, dQ), + WC_OFFSETOF(RsaKey, u) #endif #endif }; @@ -7429,7 +8344,7 @@ int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz, /* Get the size of the DER encoding. */ ret = SizeASN_Items(pkcs8KeyASN, dataASN, pkcs8KeyASN_Length-1, &sz); } - if (ret == 0) { + if ((ret == 0) || (ret == WC_NO_ERR_TRACE(LENGTH_ONLY_E))) { /* Always return the calculated size. */ *outSz = (word32)sz; } @@ -8319,9 +9234,12 @@ int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz, if (dilithium == NULL) return MEMORY_E; - if (wc_dilithium_init(dilithium) != 0) { - tmpIdx = 0; - if (wc_dilithium_set_level(dilithium, WC_ML_DSA_44) == 0) { + /* wc_dilithium_init() returns 0 on success and a non-zero value on + * failure. */ + if (wc_dilithium_init(dilithium) == 0) { + if ((*algoID == 0) && + (wc_dilithium_set_level(dilithium, WC_ML_DSA_44) == 0)) { + tmpIdx = 0; if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium, keySz) == 0) { *algoID = ML_DSA_LEVEL2k; @@ -8330,7 +9248,9 @@ int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz, WOLFSSL_MSG("Not Dilithium Level 2 DER key"); } } - else if (wc_dilithium_set_level(dilithium, WC_ML_DSA_65) == 0) { + if ((*algoID == 0) && + (wc_dilithium_set_level(dilithium, WC_ML_DSA_65) == 0)) { + tmpIdx = 0; if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium, keySz) == 0) { *algoID = ML_DSA_LEVEL3k; @@ -8339,7 +9259,9 @@ int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz, WOLFSSL_MSG("Not Dilithium Level 3 DER key"); } } - else if (wc_dilithium_set_level(dilithium, WC_ML_DSA_87) == 0) { + if ((*algoID == 0) && + (wc_dilithium_set_level(dilithium, WC_ML_DSA_87) == 0)) { + tmpIdx = 0; if (wc_Dilithium_PrivateKeyDecode(key, &tmpIdx, dilithium, keySz) == 0) { *algoID = ML_DSA_LEVEL5k; @@ -9209,26 +10131,6 @@ int ToTraditionalEnc(byte* input, word32 sz, const char* password, #ifdef HAVE_PKCS12 -#define PKCS8_MIN_BLOCK_SIZE 8 -static int Pkcs8Pad(byte* buf, int sz, int blockSz) -{ - int padSz; - - /* calculate pad size */ - padSz = blockSz - (sz & (blockSz - 1)); - - /* pad with padSz value */ - if (buf) { - int i; - for (i = 0; i < padSz; i++) { - buf[sz+i] = (byte)(padSz & 0xFF); - } - } - - /* return adjusted length */ - return sz + padSz; -} - #ifdef WOLFSSL_ASN_TEMPLATE /* ASN.1 template for PKCS #8 encrypted key with PBES1 parameters. * PKCS #8: RFC 5958, 3 - EncryptedPrivateKeyInfo @@ -9338,7 +10240,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, /* calculate size */ /* size of constructed string at end */ - sz = (word32)Pkcs8Pad(NULL, (int)inputSz, blockSz); + sz = wc_PkcsPad(NULL, inputSz, (word32)blockSz); totalSz = ASN_TAG_SZ; totalSz += SetLength(sz, seq); totalSz += sz; @@ -9434,7 +10336,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, out[inOutIdx++] = ASN_CONTEXT_SPECIFIC | 0; /* get pad size and verify buffer room */ - sz = (word32)Pkcs8Pad(NULL, (int)inputSz, blockSz); + sz = wc_PkcsPad(NULL, inputSz, (word32)blockSz); if (sz + inOutIdx > *outSz) { #ifdef WOLFSSL_SMALL_STACK XFREE(saltTmp, heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -9445,7 +10347,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, /* copy input to output buffer and pad end */ XMEMCPY(out + inOutIdx, input, inputSz); - sz = (word32)Pkcs8Pad(out + inOutIdx, (int)inputSz, blockSz); + sz = wc_PkcsPad(out + inOutIdx, inputSz, (word32)blockSz); #ifdef WOLFSSL_SMALL_STACK cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER); if (cbcIv == NULL) { @@ -9519,7 +10421,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, salt, saltSz); SetASN_Int16Bit(&dataASN[P8ENCPBES1ASN_IDX_ENCALGO_PBEPARAM_ITER], (word16)itt); - pkcs8Sz = (word32)Pkcs8Pad(NULL, (int)inputSz, blockSz); + pkcs8Sz = wc_PkcsPad(NULL, inputSz, (word32)blockSz); SetASN_Buffer(&dataASN[P8ENCPBES1ASN_IDX_ENCDATA], NULL, pkcs8Sz); /* Calculate size of encoding. */ @@ -9557,7 +10459,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, byte* pkcs8 = (byte*)dataASN[P8ENCPBES1ASN_IDX_ENCDATA].data.buffer.data; XMEMCPY(pkcs8, input, inputSz); - Pkcs8Pad(pkcs8, (int)inputSz, blockSz); + (void)wc_PkcsPad(pkcs8, inputSz, (word32)blockSz); /* Encrypt PKCS#8 key inline. */ ret = wc_CryptKey(password, passwordSz, salt, (int)saltSz, itt, id, @@ -9577,6 +10479,36 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, #endif /* HAVE_PKCS12 */ #endif /* NO_PWDBASED */ +/* Block padding used for PKCS#5, PKCS#7, PKCS#8 and PKCS#12. + * + * The length of padding is the value of each padding byte. + * + * When buf is NULL, the padded size is returned. + * + * @param [in, out] buf Buffer of data to be padded. May be NULL. + * @param [in] sz Size of data in bytes. + * @param [in] blockSz Size of block, in bytes, which buffer size must be + * a multiple of. Assumed to be less than 256 and + * a power of 2. + * @return Size of padded buffer in bytes. + */ +word32 wc_PkcsPad(byte* buf, word32 sz, word32 blockSz) +{ + /* Calculate number of padding bytes. */ + word32 padSz = blockSz - (sz & (blockSz - 1)); + + /* Pad with padSz byte. */ + if (buf != NULL) { + word32 i; + for (i = 0; i < padSz; i++) { + buf[sz+i] = (byte)(padSz & 0xFF); + } + } + + /* Return padded buffer size in bytes. */ + return sz + padSz; +} + #ifndef NO_RSA #ifdef WOLFSSL_ASN_TEMPLATE /* ASN.1 template for an RSA public key. @@ -11477,8 +12409,8 @@ int wc_DsaKeyToParamsDer(DsaKey* key, byte* output, word32 inLen) } /* This version of the function allows output to be NULL. In that case, the - DsaKeyIntsToDer will return WC_NO_ERR_TRACE(LENGTH_ONLY_E) and the required output buffer - size will be pointed to by inLen. */ + DsaKeyIntsToDer will return WC_NO_ERR_TRACE(LENGTH_ONLY_E) and the required + output buffer size will be pointed to by inLen. */ int wc_DsaKeyToParamsDer_ex(DsaKey* key, byte* output, word32* inLen) { if (!key || !inLen) @@ -13096,13 +14028,13 @@ static const CertNameData certNameSubject[] = { { "/CN=", 4, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectCN), - OFFSETOF(DecodedCert, subjectCNLen), - OFFSETOF(DecodedCert, subjectCNEnc), + WC_OFFSETOF(DecodedCert, subjectCN), + WC_OFFSETOF(DecodedCert, subjectCNLen), + WC_OFFSETOF(DecodedCert, subjectCNEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES - OFFSETOF(DecodedCert, issuerCN), - OFFSETOF(DecodedCert, issuerCNLen), - OFFSETOF(DecodedCert, issuerCNEnc), + WC_OFFSETOF(DecodedCert, issuerCN), + WC_OFFSETOF(DecodedCert, issuerCNLen), + WC_OFFSETOF(DecodedCert, issuerCNEnc), #endif #endif #ifdef WOLFSSL_X509_NAME_AVAILABLE @@ -13113,13 +14045,13 @@ static const CertNameData certNameSubject[] = { { "/SN=", 4, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectSN), - OFFSETOF(DecodedCert, subjectSNLen), - OFFSETOF(DecodedCert, subjectSNEnc), + WC_OFFSETOF(DecodedCert, subjectSN), + WC_OFFSETOF(DecodedCert, subjectSNLen), + WC_OFFSETOF(DecodedCert, subjectSNEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES - OFFSETOF(DecodedCert, issuerSN), - OFFSETOF(DecodedCert, issuerSNLen), - OFFSETOF(DecodedCert, issuerSNEnc), + WC_OFFSETOF(DecodedCert, issuerSN), + WC_OFFSETOF(DecodedCert, issuerSNLen), + WC_OFFSETOF(DecodedCert, issuerSNEnc), #endif #endif #ifdef WOLFSSL_X509_NAME_AVAILABLE @@ -13130,13 +14062,13 @@ static const CertNameData certNameSubject[] = { { "/serialNumber=", 14, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectSND), - OFFSETOF(DecodedCert, subjectSNDLen), - OFFSETOF(DecodedCert, subjectSNDEnc), + WC_OFFSETOF(DecodedCert, subjectSND), + WC_OFFSETOF(DecodedCert, subjectSNDLen), + WC_OFFSETOF(DecodedCert, subjectSNDEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES - OFFSETOF(DecodedCert, issuerSND), - OFFSETOF(DecodedCert, issuerSNDLen), - OFFSETOF(DecodedCert, issuerSNDEnc), + WC_OFFSETOF(DecodedCert, issuerSND), + WC_OFFSETOF(DecodedCert, issuerSNDLen), + WC_OFFSETOF(DecodedCert, issuerSNDEnc), #endif #endif #ifdef WOLFSSL_X509_NAME_AVAILABLE @@ -13147,13 +14079,13 @@ static const CertNameData certNameSubject[] = { { "/C=", 3, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectC), - OFFSETOF(DecodedCert, subjectCLen), - OFFSETOF(DecodedCert, subjectCEnc), + WC_OFFSETOF(DecodedCert, subjectC), + WC_OFFSETOF(DecodedCert, subjectCLen), + WC_OFFSETOF(DecodedCert, subjectCEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES - OFFSETOF(DecodedCert, issuerC), - OFFSETOF(DecodedCert, issuerCLen), - OFFSETOF(DecodedCert, issuerCEnc), + WC_OFFSETOF(DecodedCert, issuerC), + WC_OFFSETOF(DecodedCert, issuerCLen), + WC_OFFSETOF(DecodedCert, issuerCEnc), #endif #endif #ifdef WOLFSSL_X509_NAME_AVAILABLE @@ -13164,13 +14096,13 @@ static const CertNameData certNameSubject[] = { { "/L=", 3, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectL), - OFFSETOF(DecodedCert, subjectLLen), - OFFSETOF(DecodedCert, subjectLEnc), + WC_OFFSETOF(DecodedCert, subjectL), + WC_OFFSETOF(DecodedCert, subjectLLen), + WC_OFFSETOF(DecodedCert, subjectLEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES - OFFSETOF(DecodedCert, issuerL), - OFFSETOF(DecodedCert, issuerLLen), - OFFSETOF(DecodedCert, issuerLEnc), + WC_OFFSETOF(DecodedCert, issuerL), + WC_OFFSETOF(DecodedCert, issuerLLen), + WC_OFFSETOF(DecodedCert, issuerLEnc), #endif #endif #ifdef WOLFSSL_X509_NAME_AVAILABLE @@ -13181,13 +14113,13 @@ static const CertNameData certNameSubject[] = { { "/ST=", 4, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectST), - OFFSETOF(DecodedCert, subjectSTLen), - OFFSETOF(DecodedCert, subjectSTEnc), + WC_OFFSETOF(DecodedCert, subjectST), + WC_OFFSETOF(DecodedCert, subjectSTLen), + WC_OFFSETOF(DecodedCert, subjectSTEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES - OFFSETOF(DecodedCert, issuerST), - OFFSETOF(DecodedCert, issuerSTLen), - OFFSETOF(DecodedCert, issuerSTEnc), + WC_OFFSETOF(DecodedCert, issuerST), + WC_OFFSETOF(DecodedCert, issuerSTLen), + WC_OFFSETOF(DecodedCert, issuerSTEnc), #endif #endif #ifdef WOLFSSL_X509_NAME_AVAILABLE @@ -13198,9 +14130,9 @@ static const CertNameData certNameSubject[] = { { "/street=", 8, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectStreet), - OFFSETOF(DecodedCert, subjectStreetLen), - OFFSETOF(DecodedCert, subjectStreetEnc), + WC_OFFSETOF(DecodedCert, subjectStreet), + WC_OFFSETOF(DecodedCert, subjectStreetLen), + WC_OFFSETOF(DecodedCert, subjectStreetEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES 0, 0, @@ -13215,13 +14147,13 @@ static const CertNameData certNameSubject[] = { { "/O=", 3, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectO), - OFFSETOF(DecodedCert, subjectOLen), - OFFSETOF(DecodedCert, subjectOEnc), + WC_OFFSETOF(DecodedCert, subjectO), + WC_OFFSETOF(DecodedCert, subjectOLen), + WC_OFFSETOF(DecodedCert, subjectOEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES - OFFSETOF(DecodedCert, issuerO), - OFFSETOF(DecodedCert, issuerOLen), - OFFSETOF(DecodedCert, issuerOEnc), + WC_OFFSETOF(DecodedCert, issuerO), + WC_OFFSETOF(DecodedCert, issuerOLen), + WC_OFFSETOF(DecodedCert, issuerOEnc), #endif #endif #ifdef WOLFSSL_X509_NAME_AVAILABLE @@ -13232,13 +14164,13 @@ static const CertNameData certNameSubject[] = { { "/OU=", 4, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectOU), - OFFSETOF(DecodedCert, subjectOULen), - OFFSETOF(DecodedCert, subjectOUEnc), + WC_OFFSETOF(DecodedCert, subjectOU), + WC_OFFSETOF(DecodedCert, subjectOULen), + WC_OFFSETOF(DecodedCert, subjectOUEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES - OFFSETOF(DecodedCert, issuerOU), - OFFSETOF(DecodedCert, issuerOULen), - OFFSETOF(DecodedCert, issuerOUEnc), + WC_OFFSETOF(DecodedCert, issuerOU), + WC_OFFSETOF(DecodedCert, issuerOULen), + WC_OFFSETOF(DecodedCert, issuerOUEnc), #endif #endif #ifdef WOLFSSL_X509_NAME_AVAILABLE @@ -13300,9 +14232,9 @@ static const CertNameData certNameSubject[] = { { "/businessCategory=", 18, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectBC), - OFFSETOF(DecodedCert, subjectBCLen), - OFFSETOF(DecodedCert, subjectBCEnc), + WC_OFFSETOF(DecodedCert, subjectBC), + WC_OFFSETOF(DecodedCert, subjectBCLen), + WC_OFFSETOF(DecodedCert, subjectBCEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES 0, 0, @@ -13334,9 +14266,9 @@ static const CertNameData certNameSubject[] = { { "/postalCode=", 12, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectPC), - OFFSETOF(DecodedCert, subjectPCLen), - OFFSETOF(DecodedCert, subjectPCEnc), + WC_OFFSETOF(DecodedCert, subjectPC), + WC_OFFSETOF(DecodedCert, subjectPCLen), + WC_OFFSETOF(DecodedCert, subjectPCEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES 0, 0, @@ -13351,9 +14283,9 @@ static const CertNameData certNameSubject[] = { { "/userid=", 8, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectUID), - OFFSETOF(DecodedCert, subjectUIDLen), - OFFSETOF(DecodedCert, subjectUIDEnc), + WC_OFFSETOF(DecodedCert, subjectUID), + WC_OFFSETOF(DecodedCert, subjectUIDLen), + WC_OFFSETOF(DecodedCert, subjectUIDEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES 0, 0, @@ -13369,9 +14301,9 @@ static const CertNameData certNameSubject[] = { { "/N=", 3, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectN), - OFFSETOF(DecodedCert, subjectNLen), - OFFSETOF(DecodedCert, subjectNEnc), + WC_OFFSETOF(DecodedCert, subjectN), + WC_OFFSETOF(DecodedCert, subjectNLen), + WC_OFFSETOF(DecodedCert, subjectNEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES 0, 0, @@ -13386,9 +14318,9 @@ static const CertNameData certNameSubject[] = { { "/GN=", 4, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectGN), - OFFSETOF(DecodedCert, subjectGNLen), - OFFSETOF(DecodedCert, subjectGNEnc), + WC_OFFSETOF(DecodedCert, subjectGN), + WC_OFFSETOF(DecodedCert, subjectGNLen), + WC_OFFSETOF(DecodedCert, subjectGNEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES 0, 0, @@ -13403,9 +14335,9 @@ static const CertNameData certNameSubject[] = { { "/initials=", 10, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectI), - OFFSETOF(DecodedCert, subjectILen), - OFFSETOF(DecodedCert, subjectIEnc), + WC_OFFSETOF(DecodedCert, subjectI), + WC_OFFSETOF(DecodedCert, subjectILen), + WC_OFFSETOF(DecodedCert, subjectIEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES 0, 0, @@ -13420,9 +14352,9 @@ static const CertNameData certNameSubject[] = { { "/dnQualifier=", 13, #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_CERT_EXT) - OFFSETOF(DecodedCert, subjectDNQ), - OFFSETOF(DecodedCert, subjectDNQLen), - OFFSETOF(DecodedCert, subjectDNQEnc), + WC_OFFSETOF(DecodedCert, subjectDNQ), + WC_OFFSETOF(DecodedCert, subjectDNQLen), + WC_OFFSETOF(DecodedCert, subjectDNQEnc), #ifdef WOLFSSL_HAVE_ISSUER_NAMES 0, 0, @@ -16265,7 +17197,8 @@ static WC_INLINE int IsSigAlgoECC(word32 algoOID) * @return Encoded data size on success. * @return 0 when dynamic memory allocation fails. */ -static word32 SetAlgoIDImpl(int algoOID, byte* output, int type, int curveSz, byte absentParams) +static word32 SetAlgoIDImpl(int algoOID, byte* output, int type, int curveSz, + byte absentParams) { #ifndef WOLFSSL_ASN_TEMPLATE word32 tagSz, idSz, seqSz, algoSz = 0; @@ -16395,7 +17328,8 @@ word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz) return SetAlgoIDImpl(algoOID, output, type, curveSz, FALSE); } -word32 SetAlgoIDEx(int algoOID, byte* output, int type, int curveSz, byte absentParams) +word32 SetAlgoIDEx(int algoOID, byte* output, int type, int curveSz, + byte absentParams) { return SetAlgoIDImpl(algoOID, output, type, curveSz, absentParams); } @@ -16819,7 +17753,7 @@ static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID, #endif /* !NO_ASN_CRYPT && !NO_HASH_WRAPPER */ /* Return codes: 0=Success, Negative (see error-crypt.h), ASN_SIG_CONFIRM_E */ -static int ConfirmSignature(SignatureCtx* sigCtx, +int ConfirmSignature(SignatureCtx* sigCtx, const byte* buf, word32 bufSz, const byte* key, word32 keySz, word32 keyOID, const byte* sig, word32 sigSz, word32 sigOID, @@ -17269,6 +18203,10 @@ static int ConfirmSignature(SignatureCtx* sigCtx, level = WC_ML_DSA_87_DRAFT; } #endif + else { + WOLFSSL_MSG("Invalid Dilithium key OID"); + goto exit_cs; + } sigCtx->verify = 0; sigCtx->key.dilithium = (dilithium_key*)XMALLOC( sizeof(dilithium_key), sigCtx->heap, @@ -17833,7 +18771,7 @@ static int ConfirmSignature(SignatureCtx* sigCtx, case DILITHIUM_LEVEL2k: case DILITHIUM_LEVEL3k: case DILITHIUM_LEVEL5k: - #endif + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ case ML_DSA_LEVEL2k: case ML_DSA_LEVEL3k: case ML_DSA_LEVEL5k: @@ -17947,41 +18885,6 @@ static int ConfirmSignature(SignatureCtx* sigCtx, return ret; } -#ifdef WOLFSSL_DUAL_ALG_CERTS -int wc_ConfirmAltSignature( - const byte* buf, word32 bufSz, - const byte* key, word32 keySz, word32 keyOID, - const byte* sig, word32 sigSz, word32 sigOID, - void *heap) -{ - int ret = 0; -#ifdef WOLFSSL_SMALL_STACK - SignatureCtx* sigCtx = (SignatureCtx*)XMALLOC(sizeof(*sigCtx), heap, - DYNAMIC_TYPE_SIGNATURE); - if (sigCtx == NULL) { - ret = MEMORY_E; - } -#else - SignatureCtx sigCtx[1]; - (void)heap; -#endif - - if (ret == 0) { - InitSignatureCtx(sigCtx, heap, INVALID_DEVID); - - ret = ConfirmSignature(sigCtx, buf, bufSz, key, keySz, - keyOID, sig, sigSz, sigOID, NULL, 0, NULL); - - FreeSignatureCtx(sigCtx); - } - -#ifdef WOLFSSL_SMALL_STACK - XFREE(sigCtx, heap, DYNAMIC_TYPE_SIGNATURE); -#endif - return ret; -} -#endif /* WOLFSSL_DUAL_ALG_CERTS */ - #ifndef IGNORE_NAME_CONSTRAINTS static int MatchBaseName(int type, const char* name, int nameSz, @@ -21254,11 +22157,12 @@ static int DecodeAltSigAlg(const byte* input, int sz, DecodedCert* cert) * like a traditional signature in the certificate. */ static int DecodeAltSigVal(const byte* input, int sz, DecodedCert* cert) { - (void)cert; int ret = 0; word32 idx = 0; int len = 0; + (void)cert; + WOLFSSL_ENTER("DecodeAltSigVal"); if (ret == 0) { @@ -21527,16 +22431,19 @@ static int DecodeExtensionType(const byte* input, word32 length, word32 oid, #ifdef WOLFSSL_DUAL_ALG_CERTS case SUBJ_ALT_PUB_KEY_INFO_OID: VERIFY_AND_SET_OID(cert->extSapkiSet); + cert->extSapkiCrit = critical ? 1 : 0; if (DecodeSubjAltPubKeyInfo(&input[idx], length, cert) < 0) return ASN_PARSE_E; break; case ALT_SIG_ALG_OID: VERIFY_AND_SET_OID(cert->extAltSigAlgSet); + cert->extAltSigAlgCrit = critical ? 1 : 0; if (DecodeAltSigAlg(&input[idx], length, cert) < 0) return ASN_PARSE_E; break; case ALT_SIG_VAL_OID: VERIFY_AND_SET_OID(cert->extAltSigValSet); + cert->extAltSigValCrit = critical ? 1 : 0; if (DecodeAltSigVal(&input[idx], length, cert) < 0) return ASN_PARSE_E; break; @@ -23666,6 +24573,19 @@ int wc_CertGetPubKey(const byte* cert, word32 certSz, return ret; } #endif +#ifdef HAVE_OCSP +Signer* findSignerByKeyHash(Signer *list, byte *hash) +{ + Signer *s; + for (s = list; s != NULL; s = s->next) { + if (XMEMCMP(s->subjectKeyHash, hash, KEYID_SIZE) == 0) { + return s; + } + } + return NULL; +} +#endif /* WOLFSSL_OCSP */ + Signer* findSignerByName(Signer *list, byte *hash) { Signer *s; @@ -23677,7 +24597,8 @@ Signer* findSignerByName(Signer *list, byte *hash) return NULL; } -int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm, Signer *extraCAList) +int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm, + Signer *extraCAList) { int ret = 0; #ifndef WOLFSSL_ASN_TEMPLATE @@ -24611,7 +25532,8 @@ int SetSerialNumber(const byte* sn, word32 snSz, byte* output, #endif /* !NO_CERTS */ #if defined(WOLFSSL_ASN_TEMPLATE) || defined(HAVE_PKCS12) || \ - (defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)) + (defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)) || \ + (!defined(NO_RSA) && defined(WOLFSSL_KEY_GEN)) int SetMyVersion(word32 version, byte* output, int header) { int i = 0; @@ -24777,6 +25699,8 @@ wcchar END_CERT = "-----END CERTIFICATE-----"; #endif wcchar BEGIN_X509_CRL = "-----BEGIN X509 CRL-----"; wcchar END_X509_CRL = "-----END X509 CRL-----"; +wcchar BEGIN_TRUSTED_CERT = "-----BEGIN TRUSTED CERTIFICATE-----"; +wcchar END_TRUSTED_CERT = "-----END TRUSTED CERTIFICATE-----"; wcchar BEGIN_RSA_PRIV = "-----BEGIN RSA PRIVATE KEY-----"; wcchar END_RSA_PRIV = "-----END RSA PRIVATE KEY-----"; wcchar BEGIN_RSA_PUB = "-----BEGIN RSA PUBLIC KEY-----"; @@ -25073,6 +25997,11 @@ int wc_PemGetHeaderFooter(int type, const char** header, const char** footer) if (footer) *footer = END_ENC_PRIV_KEY; ret = 0; break; + case TRUSTED_CERT_TYPE: + if (header) *header = BEGIN_TRUSTED_CERT; + if (footer) *footer = END_TRUSTED_CERT; + ret = 0; + break; default: ret = BAD_FUNC_ARG; break; @@ -25318,8 +26247,8 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, char header[MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE]; char footer[MAX_X509_HEADER_SZ]; #endif - int headerLen = MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE; - int footerLen = MAX_X509_HEADER_SZ; + size_t headerLen = MAX_X509_HEADER_SZ + HEADER_ENCRYPTED_KEY_SIZE; + size_t footerLen = MAX_X509_HEADER_SZ; int i; int err; int outLen; /* return length or error */ @@ -25346,9 +26275,9 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, #endif /* build header and footer based on type */ - XSTRNCPY(header, headerStr, (size_t)headerLen - 1); + XSTRNCPY(header, headerStr, headerLen - 1); header[headerLen - 2] = 0; - XSTRNCPY(footer, footerStr, (size_t)footerLen - 1); + XSTRNCPY(footer, footerStr, footerLen - 1); footer[footerLen - 2] = 0; /* add new line to end */ @@ -25356,7 +26285,7 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, XSTRNCAT(footer, "\n", 2); #ifdef WOLFSSL_ENCRYPTED_KEYS - err = wc_EncryptedInfoAppend(header, headerLen, (char*)cipher_info); + err = wc_EncryptedInfoAppend(header, (int)headerLen, (char*)cipher_info); if (err != 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -25366,8 +26295,8 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, } #endif - headerLen = (int)XSTRLEN(header); - footerLen = (int)XSTRLEN(footer); + headerLen = XSTRLEN(header); + footerLen = XSTRLEN(footer); /* if null output and 0 size passed in then return size needed */ if (!output && outSz == 0) { @@ -25381,7 +26310,7 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, WOLFSSL_ERROR_VERBOSE(err); return err; } - return headerLen + footerLen + outLen; + return (int)headerLen + (int)footerLen + outLen; } if (!der || !output) { @@ -25403,14 +26332,14 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, /* header */ XMEMCPY(output, header, (size_t)headerLen); - i = headerLen; + i = (int)headerLen; #ifdef WOLFSSL_SMALL_STACK XFREE(header, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif /* body */ - outLen = (int)outSz - (headerLen + footerLen); /* input to Base64_Encode */ + outLen = (int)outSz - (int)(headerLen + footerLen); /* input to Base64_Encode */ if ( (err = Base64_Encode(der, derSz, output + i, (word32*)&outLen)) < 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -25421,7 +26350,7 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, i += outLen; /* footer */ - if ( (i + footerLen) > (int)outSz) { + if ( (i + (int)footerLen) > (int)outSz) { #ifdef WOLFSSL_SMALL_STACK XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -25433,7 +26362,7 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, XFREE(footer, NULL, DYNAMIC_TYPE_TMP_BUFFER); #endif - return outLen + headerLen + footerLen; + return outLen + (int)headerLen + (int)footerLen; } #endif /* WOLFSSL_DER_TO_PEM */ @@ -25709,10 +26638,27 @@ int PemToDer(const unsigned char* buff, long longSz, int type, } der = *pDer; - if (Base64_Decode((byte*)headerEnd, (word32)neededSz, - der->buffer, &der->length) < 0) { - WOLFSSL_ERROR(BUFFER_E); - return BUFFER_E; + switch (type) { + case PUBLICKEY_TYPE: + case ECC_PUBLICKEY_TYPE: + case RSA_PUBLICKEY_TYPE: + case CERT_TYPE: + case TRUSTED_CERT_TYPE: + case CRL_TYPE: + if (Base64_Decode_nonCT((byte*)headerEnd, (word32)neededSz, + der->buffer, &der->length) < 0) + { + WOLFSSL_ERROR(BUFFER_E); + return BUFFER_E; + } + break; + default: + if (Base64_Decode((byte*)headerEnd, (word32)neededSz, + der->buffer, &der->length) < 0) { + WOLFSSL_ERROR(BUFFER_E); + return BUFFER_E; + } + break; } if ((header == BEGIN_PRIV_KEY @@ -25754,7 +26700,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type, } #ifdef WOLFSSL_SMALL_STACK - password = (char*)XMALLOC(passwordSz, heap, DYNAMIC_TYPE_STRING); + password = (char*)XMALLOC((size_t)passwordSz, heap, DYNAMIC_TYPE_STRING); if (password == NULL) { return MEMORY_E; } @@ -28804,6 +29750,13 @@ int SetNameEx(byte* output, word32 outputSz, CertName* name, void* heap) ret = 0; } + if (items == 0) { + /* if zero items, short-circuit return to avoid frivolous zero-size + * allocations. + */ + return 0; + } + /* Allocate dynamic data items. */ dataASN = (ASNSetData*)XMALLOC(items * sizeof(ASNSetData), heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -28972,6 +29925,7 @@ static const ASNItem static_certExtsASN[] = { /* Basic Constraints Extension - 4.2.1.9 */ /* BC_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 }, /* BC_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* BC_CRIT */ { 1, ASN_BOOLEAN, 0, 0, 0 }, /* BC_STR */ { 1, ASN_OCTET_STRING, 0, 1, 0 }, /* BC_STR_SEQ */ { 2, ASN_SEQUENCE, 1, 1, 0 }, /* cA */ @@ -29020,12 +29974,15 @@ static const ASNItem static_certExtsASN[] = { #ifdef WOLFSSL_DUAL_ALG_CERTS /* SAPKI_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 }, /* SAPKI_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* SAPKI_CRIT */ { 1, ASN_BOOLEAN, 0, 0, 0 }, /* SAPKI_STR */ { 1, ASN_OCTET_STRING, 0, 0, 0 }, /* ALTSIGALG_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 }, /* ALTSIGALG_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* ALTSIGALG_CRIT*/ { 1, ASN_BOOLEAN, 0, 0, 0 }, /* ALTSIGALG_STR */ { 1, ASN_OCTET_STRING, 0, 0, 0 }, /* ALTSIGVAL_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 }, /* ALTSIGVAL_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* ALTSIGVAL_CRIT*/ { 1, ASN_BOOLEAN, 0, 0, 0 }, /* ALTSIGVAL_STR */ { 1, ASN_OCTET_STRING, 0, 0, 0 }, #endif /* WOLFSSL_DUAL_ALG_CERTS */ /* CUSTOM_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 }, @@ -29035,6 +29992,7 @@ static const ASNItem static_certExtsASN[] = { enum { CERTEXTSASN_IDX_BC_SEQ = 0, CERTEXTSASN_IDX_BC_OID, + CERTEXTSASN_IDX_BC_CRIT, CERTEXTSASN_IDX_BC_STR, CERTEXTSASN_IDX_BC_STR_SEQ, CERTEXTSASN_IDX_BC_CA, @@ -29074,12 +30032,15 @@ enum { #ifdef WOLFSSL_DUAL_ALG_CERTS CERTEXTSASN_IDX_SAPKI_SEQ, CERTEXTSASN_IDX_SAPKI_OID, + CERTEXTSASN_IDX_SAPKI_CRIT, CERTEXTSASN_IDX_SAPKI_STR, CERTEXTSASN_IDX_ALTSIGALG_SEQ, CERTEXTSASN_IDX_ALTSIGALG_OID, + CERTEXTSASN_IDX_ALTSIGALG_CRIT, CERTEXTSASN_IDX_ALTSIGALG_STR, CERTEXTSASN_IDX_ALTSIGVAL_SEQ, CERTEXTSASN_IDX_ALTSIGVAL_OID, + CERTEXTSASN_IDX_ALTSIGVAL_CRIT, CERTEXTSASN_IDX_ALTSIGVAL_STR, #endif /* WOLFSSL_DUAL_ALG_CERTS */ CERTEXTSASN_IDX_CUSTOM_SEQ, @@ -29171,6 +30132,12 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, /* Set Basic Constraints to be a Certificate Authority. */ SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CA], 1); SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID)); + if (cert->basicConstCrit) { + SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CRIT], 1); + } + else { + dataASN[CERTEXTSASN_IDX_BC_CRIT].noOut = 1; + } if (cert->pathLenSet #ifdef WOLFSSL_CERT_EXT && ((cert->keyUsage & KEYUSE_KEY_CERT_SIGN) || (!cert->keyUsage)) @@ -29187,12 +30154,24 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, else if (cert->isCaSet) { SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CA], 0); SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID)); + if (cert->basicConstCrit) { + SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CRIT], 1); + } + else { + dataASN[CERTEXTSASN_IDX_BC_CRIT].noOut = 1; + } dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1; } #endif else if (cert->basicConstSet) { /* Set Basic Constraints to be a non Certificate Authority. */ SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_BC_OID], bcOID, sizeof(bcOID)); + if (cert->basicConstCrit) { + SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_BC_CRIT], 1); + } + else { + dataASN[CERTEXTSASN_IDX_BC_CRIT].noOut = 1; + } dataASN[CERTEXTSASN_IDX_BC_CA].noOut = 1; dataASN[CERTEXTSASN_IDX_BC_PATHLEN].noOut = 1; } @@ -29359,9 +30338,16 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, #ifdef WOLFSSL_DUAL_ALG_CERTS if (cert->sapkiDer != NULL) { - /* Set subject alternative public key info OID and data. */ + /* Set subject alternative public key info OID, criticality and + * data. */ SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAPKI_OID], sapkiOID, sizeof(sapkiOID)); + if (cert->sapkiCrit) { + SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_SAPKI_CRIT], 1); + } + else { + dataASN[CERTEXTSASN_IDX_SAPKI_CRIT].noOut = 1; + } SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_SAPKI_STR], cert->sapkiDer, cert->sapkiLen); } @@ -29372,9 +30358,15 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, } if (cert->altSigAlgDer != NULL) { - /* Set alternative signature algorithm OID and data. */ + /* Set alternative signature algorithm OID, criticality and data. */ SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_ALTSIGALG_OID], altSigAlgOID, sizeof(altSigAlgOID)); + if (cert->altSigAlgCrit) { + SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_ALTSIGALG_CRIT], 1); + } + else { + dataASN[CERTEXTSASN_IDX_ALTSIGALG_CRIT].noOut = 1; + } SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_ALTSIGALG_STR], cert->altSigAlgDer, cert->altSigAlgLen); } @@ -29385,9 +30377,15 @@ static int EncodeExtensions(Cert* cert, byte* output, word32 maxSz, } if (cert->altSigValDer != NULL) { - /* Set alternative signature value OID and data. */ + /* Set alternative signature value OID, criticality and data. */ SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_ALTSIGVAL_OID], altSigValOID, sizeof(altSigValOID)); + if (cert->altSigValCrit) { + SetASN_Boolean(&dataASN[CERTEXTSASN_IDX_ALTSIGVAL_CRIT], 1); + } + else { + dataASN[CERTEXTSASN_IDX_ALTSIGVAL_CRIT].noOut = 1; + } SetASN_Buffer(&dataASN[CERTEXTSASN_IDX_ALTSIGVAL_STR], cert->altSigValDer, cert->altSigValLen); } @@ -30976,8 +31974,18 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, #endif } - -/* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */ +/* Make an x509 Certificate v3 from cert input using any + * key type, and write to buffer. + * + * @param [in, out] cert Certificate object. + * @param [out] derBuffer Buffer to write der in. + * @param [in] derSz Der buffer size. + * @param [in] keyType The type of key. + * @param [in] key Key data. + * @param [in] rng Random number generator. + * @return Size of encoded data in bytes on success. + * @return < 0 on error + * */ int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, void* key, WC_RNG* rng) { @@ -32145,6 +33153,21 @@ static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz, } #ifdef WOLFSSL_DUAL_ALG_CERTS +/* Generate a signature from input buffer using + * any key type. + * + * @param [out] sig The signature buffer to write in. + * @param [out] sigsz The signature buffer size. + * @param [in] sType The signature type. + * @param [in] buf The input buf to sign. + * @param [in] bufSz The buffer size + * @param [in] keyType The key type. + * @param [in] key Key data. + * @param [in] rng Random number generator. + * + * @return Size of signature on success. + * @return < 0 on error. + * */ int wc_MakeSigWithBitStr(byte *sig, int sigSz, int sType, byte* buf, word32 bufSz, int keyType, void* key, WC_RNG* rng) { @@ -32155,13 +33178,14 @@ int wc_MakeSigWithBitStr(byte *sig, int sigSz, int sType, byte* buf, falcon_key* falconKey = NULL; dilithium_key* dilithiumKey = NULL; sphincs_key* sphincsKey = NULL; - int ret = 0; int headerSz; void* heap = NULL; CertSignCtx certSignCtx_lcl; CertSignCtx* certSignCtx = &certSignCtx_lcl; + WOLFSSL_ENTER("wc_MakeSigWithBitStr"); + if ((sig == NULL) || (sigSz <= 0)) { return BAD_FUNC_ARG; } @@ -32271,6 +33295,20 @@ int wc_MakeSigWithBitStr(byte *sig, int sigSz, int sType, byte* buf, } #endif /* WOLFSSL_DUAL_ALG_CERTS */ +/* Sign an x509 Certificate v3 from cert input using any + * key type, and write to buffer. + * + * @param [in] requestSz Size of requested data to sign. + * @param [in] sType The signature type. + * @param [in,out] buf Der buffer to sign. + * @param [in] buffSz Der buffer size. + * @param [in] keyType The type of key. + * @param [in] key Key data. + * @param [in] rng Random number generator. + * + * @return Size of signature on success. + * @return < 0 on error + * */ int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz, int keyType, void* key, WC_RNG* rng) { @@ -33779,8 +34817,14 @@ int DecodeECC_DSA_Sig_Bin(const byte* sig, word32 sigLen, byte* r, word32* rLen, ret = GetASNInt(sig, &idx, &len, sigLen); if (ret != 0) return ret; - if (rLen) - *rLen = (word32)len; + if (rLen) { + if (*rLen >= (word32)len) + *rLen = (word32)len; + else { + /* Buffer too small to hold r value */ + return BUFFER_E; + } + } if (r) XMEMCPY(r, (byte*)sig + idx, (size_t)len); idx += (word32)len; @@ -33788,8 +34832,14 @@ int DecodeECC_DSA_Sig_Bin(const byte* sig, word32 sigLen, byte* r, word32* rLen, ret = GetASNInt(sig, &idx, &len, sigLen); if (ret != 0) return ret; - if (sLen) - *sLen = (word32)len; + if (sLen) { + if (*sLen >= (word32)len) + *sLen = (word32)len; + else { + /* Buffer too small to hold s value */ + return BUFFER_E; + } + } if (s) XMEMCPY(s, (byte*)sig + idx, (size_t)len); @@ -34171,23 +35221,26 @@ static int EccSpecifiedECDomainDecode(const byte* input, word32 inSz, } #endif /* WOLFSSL_ECC_CURVE_STATIC */ + if ((ret == 0) && (curveSz)) { + *curveSz = curve->size; + } + if (key) { /* Store parameter set in key. */ - if ((ret == 0) && (wc_ecc_set_custom_curve(key, curve) < 0)) { - ret = ASN_PARSE_E; - } if (ret == 0) { - /* The parameter set was allocated.. */ - key->deallocSet = 1; + if (wc_ecc_set_custom_curve(key, curve) < 0) { + ret = ASN_PARSE_E; + } + else { + /* The parameter set was allocated.. */ + key->deallocSet = 1; + /* Don't deallocate below. */ + curve = NULL; + } } } - if ((ret == 0) && (curveSz)) { - *curveSz = curve->size; - } - - if ((ret != 0) && (curve != NULL)) { - /* Failed to set parameters so free parameter set. */ + if (curve != NULL) { /* NOLINT(clang-analyzer-unix.Malloc) */ wc_ecc_free_curve(curve, heap); } @@ -34343,7 +35396,8 @@ int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, ret = BUFFER_E; else { #ifdef WOLFSSL_SMALL_STACK - pub = (byte*)XMALLOC(pubSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + pub = (byte*)XMALLOC(pubSz, key->heap, + DYNAMIC_TYPE_TMP_BUFFER); if (pub == NULL) ret = MEMORY_E; else @@ -35718,6 +36772,9 @@ int wc_Ed25519PublicKeyDecode(const byte* input, word32* inOutIdx, return BAD_FUNC_ARG; } + /* init pubKey */ + XMEMSET(pubKey, 0, sizeof(pubKey)); + ret = DecodeAsymKeyPublic(input, inOutIdx, inSz, pubKey, &pubKeyLen, ED25519k); if (ret == 0) { @@ -35758,6 +36815,9 @@ int wc_Curve25519PublicKeyDecode(const byte* input, word32* inOutIdx, return BAD_FUNC_ARG; } + /* init pubKey */ + XMEMSET(pubKey, 0, sizeof(pubKey)); + ret = DecodeAsymKeyPublic(input, inOutIdx, inSz, pubKey, &pubKeyLen, X25519k); if (ret == 0) { @@ -35983,7 +37043,8 @@ int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen) #if defined(HAVE_CURVE25519) && defined(HAVE_CURVE25519_KEY_EXPORT) /* Write only private Curve25519 key to DER format, * length on success else < 0 */ -int wc_Curve25519PrivateKeyToDer(curve25519_key* key, byte* output, word32 inLen) +int wc_Curve25519PrivateKeyToDer(curve25519_key* key, byte* output, + word32 inLen) { int ret; byte privKey[CURVE25519_KEYSIZE]; @@ -36025,7 +37086,8 @@ int wc_Curve25519PublicKeyToDer(curve25519_key* key, byte* output, word32 inLen, /* Export Curve25519 key to DER format - handles private only, public only, * or private+public key pairs based on what's set in the key structure. * Returns length written on success, negative on error */ -int wc_Curve25519KeyToDer(curve25519_key* key, byte* output, word32 inLen, int withAlg) +int wc_Curve25519KeyToDer(curve25519_key* key, byte* output, word32 inLen, + int withAlg) { int ret; byte privKey[CURVE25519_KEYSIZE]; @@ -36158,6 +37220,9 @@ int wc_Curve448PublicKeyDecode(const byte* input, word32* inOutIdx, return BAD_FUNC_ARG; } + /* init pubKey */ + XMEMSET(pubKey, 0, sizeof(pubKey)); + ret = DecodeAsymKeyPublic(input, inOutIdx, inSz, pubKey, &pubKeyLen, X448k); if (ret == 0) { @@ -36305,17 +37370,7 @@ static int GetEnumerated(const byte* input, word32* inOutIdx, int *value, static const ASNItem singleResponseASN[] = { /* SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 }, /* certId */ -/* CID_SEQ */ { 1, ASN_SEQUENCE, 1, 1, 0 }, - /* hashAlgorithm */ -/* CID_HASHALGO_SEQ */ { 2, ASN_SEQUENCE, 1, 1, 0 }, -/* CID_HASHALGO_OID */ { 3, ASN_OBJECT_ID, 0, 0, 0 }, -/* CID_HASHALGO_NULL */ { 3, ASN_TAG_NULL, 0, 0, 1 }, - /* issuerNameHash */ -/* CID_ISSUERHASH */ { 2, ASN_OCTET_STRING, 0, 0, 0 }, - /* issuerKeyHash */ -/* CID_ISSUERKEYHASH */ { 2, ASN_OCTET_STRING, 0, 0, 0 }, - /* serialNumber */ -/* CID_SERIAL */ { 2, ASN_INTEGER, 0, 0, 0 }, +/* CID_SEQ */ { 1, ASN_SEQUENCE, 1, 0, 0 }, /* certStatus - CHOICE */ /* good [0] IMPLICIT NULL */ /* CS_GOOD */ { 1, ASN_CONTEXT_SPECIFIC | 0, 0, 0, 2 }, @@ -36341,12 +37396,6 @@ static const ASNItem singleResponseASN[] = { enum { SINGLERESPONSEASN_IDX_SEQ = 0, SINGLERESPONSEASN_IDX_CID_SEQ, - SINGLERESPONSEASN_IDX_CID_HASHALGO_SEQ, - SINGLERESPONSEASN_IDX_CID_HASHALGO_OID, - SINGLERESPONSEASN_IDX_CID_HASHALGO_NULL, - SINGLERESPONSEASN_IDX_CID_ISSUERHASH, - SINGLERESPONSEASN_IDX_CID_ISSUERKEYHASH, - SINGLERESPONSEASN_IDX_CID_SERIAL, SINGLERESPONSEASN_IDX_CS_GOOD, SINGLERESPONSEASN_IDX_CS_REVOKED, SINGLERESPONSEASN_IDX_CS_REVOKED_TIME, @@ -36361,13 +37410,139 @@ enum { /* Number of items in ASN.1 template for OCSP single response. */ #define singleResponseASN_Length (sizeof(singleResponseASN) / sizeof(ASNItem)) + +static const ASNItem certIDASNItems[] = { + /* hashAlgorithm */ +/* CID_HASHALGO_SEQ */ { 0, ASN_SEQUENCE, 1, 1, 0 }, +/* CID_HASHALGO_OID */ { 1, ASN_OBJECT_ID, 0, 0, 0 }, +/* CID_HASHALGO_NULL */ { 1, ASN_TAG_NULL, 0, 0, 1 }, + /* issuerNameHash */ +/* CID_ISSUERHASH */ { 0, ASN_OCTET_STRING, 0, 0, 0 }, + /* issuerKeyHash */ +/* CID_ISSUERKEYHASH */ { 0, ASN_OCTET_STRING, 0, 0, 0 }, + /* serialNumber */ +/* CID_SERIAL */ { 0, ASN_INTEGER, 0, 0, 0 }, +}; + +enum { + CERTIDASN_IDX_CID_HASHALGO_SEQ, + CERTIDASN_IDX_CID_HASHALGO_OID, + CERTIDASN_IDX_CID_HASHALGO_NULL, + CERTIDASN_IDX_CID_ISSUERHASH, + CERTIDASN_IDX_CID_ISSUERKEYHASH, + CERTIDASN_IDX_CID_SERIAL, +}; + +#define certidasn_Length (sizeof(certIDASNItems) / sizeof(ASNItem)) +#endif + +#ifndef WOLFSSL_ASN_TEMPLATE +static int OcspDecodeCertIDInt(const byte* input, word32* inOutIdx, word32 inSz, + OcspEntry* entry) +{ + int length; + word32 oid; + int ret; + /* Hash algorithm */ + ret = GetAlgoId(input, inOutIdx, &oid, oidHashType, inSz); + if (ret < 0) + return ret; + entry->hashAlgoOID = oid; + /* Save reference to the hash of CN */ + ret = GetOctetString(input, inOutIdx, &length, inSz); + if (ret < 0) + return ret; + if (length != OCSP_DIGEST_SIZE) + return ASN_PARSE_E; + XMEMCPY(entry->issuerHash, input + *inOutIdx, length); + *inOutIdx += length; + /* Save reference to the hash of the issuer public key */ + ret = GetOctetString(input, inOutIdx, &length, inSz); + if (ret < 0) + return ret; + if (length != OCSP_DIGEST_SIZE) + return ASN_PARSE_E; + XMEMCPY(entry->issuerKeyHash, input + *inOutIdx, length); + *inOutIdx += length; + + /* Get serial number */ + if (wc_GetSerialNumber(input, inOutIdx, entry->status->serial, + &entry->status->serialSz, inSz) < 0) + return ASN_PARSE_E; + return 0; +} +#else +static int OcspDecodeCertIDInt(const byte* input, word32* inOutIdx, word32 inSz, + OcspEntry* entry) +{ + DECL_ASNGETDATA(dataASN, certidasn_Length); + word32 issuerKeyHashLen = OCSP_DIGEST_SIZE; + word32 issuerHashLen = OCSP_DIGEST_SIZE; + word32 serialSz = EXTERNAL_SERIAL_SIZE; + word32 digestSz; + int ret = 0; + + WOLFSSL_ENTER("DecodeCertIdTemplate"); + CALLOC_ASNGETDATA(dataASN, certidasn_Length, ret, NULL); + if (ret != 0) + return ret; + + GetASN_OID(&dataASN[CERTIDASN_IDX_CID_HASHALGO_OID], oidHashType); + GetASN_Buffer(&dataASN[CERTIDASN_IDX_CID_ISSUERHASH], entry->issuerHash, + &issuerHashLen); + GetASN_Buffer(&dataASN[CERTIDASN_IDX_CID_ISSUERKEYHASH], + entry->issuerKeyHash, &issuerKeyHashLen); + GetASN_Buffer(&dataASN[CERTIDASN_IDX_CID_SERIAL], entry->status->serial, + &serialSz); + ret = GetASN_Items(certIDASNItems, dataASN, certidasn_Length, + 1, input, inOutIdx, inSz); + if (ret != 0) { + goto out; + } + entry->status->serialSz = serialSz; + entry->hashAlgoOID = + dataASN[CERTIDASN_IDX_CID_HASHALGO_OID].data.oid.sum; + digestSz = wc_HashGetDigestSize(wc_OidGetHash(entry->hashAlgoOID)); + if (issuerKeyHashLen != digestSz || issuerHashLen != digestSz) { + ret = ASN_PARSE_E; + goto out; + } +out: + FREE_ASNGETDATA(dataASN, NULL); + return ret; +} #endif +int OcspDecodeCertID(const byte *input, word32 *inOutIdx, word32 inSz, + OcspEntry *entry) +{ + word32 seqIdx = 0; + int len = inSz; + int ret; + +#ifndef WOLFSSL_ASN_TEMPLATE + ret = GetSequence(input, inOutIdx, &len, inSz); +#else + ret = GetASN_Sequence(input, inOutIdx, &len, inSz, 0); +#endif + if (ret < 0) + return ASN_PARSE_E; + ret = OcspDecodeCertIDInt(input + *inOutIdx, &seqIdx, len, entry); + if (ret < 0) + return ASN_PARSE_E; + if (seqIdx != (word32)len) + return ASN_PARSE_E; + *inOutIdx += len; + + return 0; +} + + static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, int wrapperSz, OcspEntry* single) { #ifndef WOLFSSL_ASN_TEMPLATE - word32 idx = *ioIndex, prevIndex, oid, localIdx, certIdIdx; + word32 idx = *ioIndex, prevIndex, localIdx, certIdIdx; int length; int ret; byte tag; @@ -36385,31 +37560,8 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, if (GetSequence(source, &idx, &length, size) < 0) return ASN_PARSE_E; single->rawCertId = source + certIdIdx; - /* Hash algorithm */ - ret = GetAlgoId(source, &idx, &oid, oidIgnoreType, size); - if (ret < 0) - return ret; - single->hashAlgoOID = oid; - /* Save reference to the hash of CN */ - ret = GetOctetString(source, &idx, &length, size); - if (ret < 0) - return ret; - if (length > (int)sizeof(single->issuerHash)) - return BUFFER_E; - XMEMCPY(single->issuerHash, source + idx, length); - idx += length; - /* Save reference to the hash of the issuer public key */ - ret = GetOctetString(source, &idx, &length, size); + ret = OcspDecodeCertIDInt(source, &idx, size, single); if (ret < 0) - return ret; - if (length > (int)sizeof(single->issuerKeyHash)) - return BUFFER_E; - XMEMCPY(single->issuerKeyHash, source + idx, length); - idx += length; - - /* Get serial number */ - if (wc_GetSerialNumber(source, &idx, single->status->serial, - &single->status->serialSz, size) < 0) return ASN_PARSE_E; single->rawCertIdSize = idx - certIdIdx; @@ -36456,12 +37608,13 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, single->status->thisDateParsed.length); #endif if (GetBasicDate(source, &idx, single->status->thisDate, - &single->status->thisDateFormat, size) < 0) + &single->status->thisDateFormat, size) < 0) return ASN_PARSE_E; #ifndef NO_ASN_TIME_CHECK #ifndef WOLFSSL_NO_OCSP_DATE_CHECK - if (!XVALIDATE_DATE(single->status->thisDate, single->status->thisDateFormat, ASN_BEFORE)) + if (!XVALIDATE_DATE(single->status->thisDate, + single->status->thisDateFormat, ASN_BEFORE)) return ASN_BEFORE_DATE_E; #endif #endif @@ -36492,7 +37645,7 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, single->status->nextDateParsed.length); #endif if (GetBasicDate(source, &idx, single->status->nextDate, - &single->status->nextDateFormat, size) < 0) + &single->status->nextDateFormat, size) < 0) return ASN_PARSE_E; #ifndef NO_ASN_TIME_CHECK @@ -36521,13 +37674,10 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, #else /* WOLFSSL_ASN_TEMPLATE */ DECL_ASNGETDATA(dataASN, singleResponseASN_Length); int ret = 0; - word32 ocspDigestSize = OCSP_DIGEST_SIZE; CertStatus* cs = NULL; - word32 serialSz; - word32 issuerHashLen; - word32 issuerKeyHashLen; word32 thisDateLen; word32 nextDateLen; + word32 certIdSeqIdx; (void)wrapperSz; @@ -36536,25 +37686,12 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, CALLOC_ASNGETDATA(dataASN, singleResponseASN_Length, ret, NULL); if (ret == 0) { - /* Certificate Status field. */ cs = single->status; - /* Set maximum lengths for data. */ - issuerHashLen = OCSP_DIGEST_SIZE; - issuerKeyHashLen = OCSP_DIGEST_SIZE; - serialSz = EXTERNAL_SERIAL_SIZE; thisDateLen = MAX_DATE_SIZE; nextDateLen = MAX_DATE_SIZE; /* Set OID type, buffers to hold data and variables to hold size. */ - GetASN_OID(&dataASN[SINGLERESPONSEASN_IDX_CID_HASHALGO_OID], - oidHashType); - GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_ISSUERHASH], - single->issuerHash, &issuerHashLen); - GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_ISSUERKEYHASH], - single->issuerKeyHash, &issuerKeyHashLen); - GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_CID_SERIAL], cs->serial, - &serialSz); GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_THISUPDATE_GT], cs->thisDate, &thisDateLen); GetASN_Buffer(&dataASN[SINGLERESPONSEASN_IDX_NEXTUPDATE_GT], @@ -36565,27 +37702,11 @@ static int DecodeSingleResponse(byte* source, word32* ioIndex, word32 size, 1, source, ioIndex, size); } if (ret == 0) { - single->hashAlgoOID = - dataASN[SINGLERESPONSEASN_IDX_CID_HASHALGO_OID].data.oid.sum; - ocspDigestSize = (word32)wc_HashGetDigestSize( - wc_OidGetHash((int)single->hashAlgoOID)); - } - /* Validate the issuer hash length is the size required. */ - if ((ret == 0) && (issuerHashLen != ocspDigestSize)) { - ret = ASN_PARSE_E; - } - /* Validate the issuer key hash length is the size required. */ - if (ret == 0) { - if (issuerKeyHashLen != ocspDigestSize) { - ret = ASN_PARSE_E; - } + certIdSeqIdx = 0; + ret = OcspDecodeCertIDInt(dataASN[SINGLERESPONSEASN_IDX_CID_SEQ].data.ref.data, + &certIdSeqIdx, dataASN[SINGLERESPONSEASN_IDX_CID_SEQ].data.ref.length, single); } if (ret == 0) { - /* Store serial size. */ - cs->serialSz = (int)serialSz; - /* Set the hash algorithm OID */ - single->hashAlgoOID = - dataASN[SINGLERESPONSEASN_IDX_CID_HASHALGO_OID].data.oid.sum; /* Determine status by which item was found. */ if (dataASN[SINGLERESPONSEASN_IDX_CS_GOOD].tag != 0) { @@ -36821,7 +37942,8 @@ static const ASNItem ocspRespDataASN[] = { /* byName */ /* BYNAME */ { 1, ASN_CONTEXT_SPECIFIC | 1, 1, 0, 2 }, /* byKey */ -/* BYKEY */ { 1, ASN_CONTEXT_SPECIFIC | 2, 1, 0, 2 }, +/* BYKEY */ { 1, ASN_CONTEXT_SPECIFIC | 2, 1, 1, 2 }, +/* BYKEY_OCT */ { 2, ASN_OCTET_STRING, 0, 0, 0 }, /* producedAt */ /* PA */ { 1, ASN_GENERALIZED_TIME, 0, 0, 0, }, /* responses */ @@ -36835,6 +37957,7 @@ enum { OCSPRESPDATAASN_IDX_VER, OCSPRESPDATAASN_IDX_BYNAME, OCSPRESPDATAASN_IDX_BYKEY, + OCSPRESPDATAASN_IDX_BYKEY_OCT, OCSPRESPDATAASN_IDX_PA, OCSPRESPDATAASN_IDX_RESP, OCSPRESPDATAASN_IDX_RESPEXT, @@ -36879,16 +38002,40 @@ static int DecodeResponseData(byte* source, word32* ioIndex, version = 0; localIdx = idx; - if (GetASNTag(source, &localIdx, &tag, size) == 0 && - ( tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1) || - tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2) )) + if (GetASNTag(source, &localIdx, &tag, size) != 0) + return ASN_PARSE_E; + + resp->responderIdType = OCSP_RESPONDER_ID_INVALID; + /* parse byName */ + if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1)) { idx++; /* advance past ASN tag */ if (GetLength(source, &idx, &length, size) < 0) return ASN_PARSE_E; + /* compute the hash of the name */ + resp->responderIdType = OCSP_RESPONDER_ID_NAME; + ret = CalcHashId_ex(source + idx, length, + resp->responderId.nameHash, OCSP_RESPONDER_ID_HASH_TYPE); + if (ret != 0) + return ret; idx += length; } - else + else if (tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 2)) + { + idx++; /* advance past ASN tag */ + if (GetLength(source, &idx, &length, size) < 0) + return ASN_PARSE_E; + + if (GetOctetString(source, &idx, &length, size) < 0) + return ASN_PARSE_E; + + if (length != OCSP_RESPONDER_ID_KEY_SZ) + return ASN_PARSE_E; + resp->responderIdType = OCSP_RESPONDER_ID_KEY; + XMEMCPY(resp->responderId.keyHash, source + idx, length); + idx += length; + } + if (resp->responderIdType == OCSP_RESPONDER_ID_INVALID) return ASN_PARSE_E; /* save pointer to the producedAt time */ @@ -36924,6 +38071,7 @@ static int DecodeResponseData(byte* source, word32* ioIndex, XMEMSET(single->next->status, 0, sizeof(CertStatus)); single->next->isDynamic = 1; + single->next->ownStatus = 1; single = single->next; } @@ -36944,6 +38092,7 @@ static int DecodeResponseData(byte* source, word32* ioIndex, int ret = 0; byte version; word32 dateSz = 0; + word32 responderByKeySz = OCSP_RESPONDER_ID_KEY_SZ; word32 idx = *ioIndex; OcspEntry* single = NULL; @@ -36962,6 +38111,8 @@ static int DecodeResponseData(byte* source, word32* ioIndex, GetASN_Int8Bit(&dataASN[OCSPRESPDATAASN_IDX_VER], &version); GetASN_Buffer(&dataASN[OCSPRESPDATAASN_IDX_PA], resp->producedDate, &dateSz); + GetASN_Buffer(&dataASN[OCSPRESPDATAASN_IDX_BYKEY_OCT], + resp->responderId.keyHash, &responderByKeySz); /* Decode the ResponseData. */ ret = GetASN_Items(ocspRespDataASN, dataASN, ocspRespDataASN_Length, 1, source, ioIndex, size); @@ -36979,7 +38130,23 @@ static int DecodeResponseData(byte* source, word32* ioIndex, } } if (ret == 0) { - /* TODO: use byName/byKey fields. */ + if (dataASN[OCSPRESPDATAASN_IDX_BYNAME].tag != 0) { + resp->responderIdType = OCSP_RESPONDER_ID_NAME; + ret = CalcHashId_ex( + dataASN[OCSPRESPDATAASN_IDX_BYNAME].data.ref.data, + dataASN[OCSPRESPDATAASN_IDX_BYNAME].data.ref.length, + resp->responderId.nameHash, OCSP_RESPONDER_ID_HASH_TYPE); + } else { + resp->responderIdType = OCSP_RESPONDER_ID_KEY; + if (dataASN[OCSPRESPDATAASN_IDX_BYKEY_OCT].length + != OCSP_RESPONDER_ID_KEY_SZ) { + ret = ASN_PARSE_E; + } else { + resp->responderIdType = OCSP_RESPONDER_ID_KEY; + } + } + } + if (ret == 0) { /* Store size of response. */ resp->responseSz = *ioIndex - idx; /* Store date format/tag. */ @@ -37013,6 +38180,7 @@ static int DecodeResponseData(byte* source, word32* ioIndex, /* Entry to be freed. */ single->next->isDynamic = 1; + single->next->ownStatus = 1; /* used will be 0 (false) */ single = single->next; @@ -37121,8 +38289,139 @@ enum { #define ocspBasicRespASN_Length (sizeof(ocspBasicRespASN) / sizeof(ASNItem)) #endif /* WOLFSSL_ASN_TEMPLATE */ +static int OcspRespIdMatch(OcspResponse *resp, const byte *NameHash, + const byte *keyHash) +{ + if (resp->responderIdType == OCSP_RESPONDER_ID_INVALID) + return 0; + if (resp->responderIdType == OCSP_RESPONDER_ID_NAME) + return XMEMCMP(NameHash, resp->responderId.nameHash, + SIGNER_DIGEST_SIZE) == 0; + /* OCSP_RESPONDER_ID_KEY */ + return ((int)KEYID_SIZE == OCSP_RESPONDER_ID_KEY_SZ) && + XMEMCMP(keyHash, resp->responderId.keyHash, KEYID_SIZE) == 0; +} + +#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK +static int OcspRespCheck(OcspResponse *resp, Signer *responder) +{ + OcspEntry *s; + + s = resp->single; + if (s == NULL) + return -1; + + /* singles responses must have the same issuer */ + for (; s != NULL; s = s->next) { + if (XMEMCMP(s->issuerKeyHash, responder->subjectKeyHash, + KEYID_SIZE) != 0) + return -1; + } + + return 0; +} +#endif + +static Signer *OcspFindSigner(OcspResponse *resp, WOLFSSL_CERT_MANAGER *cm) +{ + Signer *s; + + if (cm == NULL) + return NULL; + + if (resp->responderIdType == OCSP_RESPONDER_ID_NAME) { +#ifndef NO_SKID + s = GetCAByName(cm, resp->responderId.nameHash); +#else + s = GetCA(cm, resp->responderId.nameHash); +#endif + if (s) + return s; + } + else if ((int)KEYID_SIZE == OCSP_RESPONDER_ID_KEY_SZ) { + s = GetCAByKeyHash(cm, resp->responderId.keyHash); + if (s) + return s; + } +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) + if (resp->pendingCAs == NULL) + return NULL; + + if (resp->responderIdType == OCSP_RESPONDER_ID_NAME) { + s = findSignerByName(resp->pendingCAs, resp->responderId.nameHash); + if (s) + return s; + } + else { + s = findSignerByKeyHash(resp->pendingCAs, resp->responderId.keyHash); + if (s) + return s; + } +#endif + return NULL; +} + +static int OcspCheckCert(OcspResponse *resp, int noVerify, + int noVerifySignature, WOLFSSL_CERT_MANAGER *cm, void *heap) +{ + int ret = 0; +#ifdef WOLFSSL_SMALL_STACK + DecodedCert *cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (cert == NULL) + return MEMORY_E; +#else + DecodedCert cert[1]; +#endif + + InitDecodedCert(cert, resp->cert, resp->certSz, heap); + ret = ParseCertRelative(cert, CERT_TYPE, + noVerify ? NO_VERIFY : VERIFY_OCSP_CERT, + cm, resp->pendingCAs); + if (ret < 0) { + WOLFSSL_MSG("\tOCSP Responder certificate parsing failed"); + } + + if (ret == 0 && + OcspRespIdMatch(resp, + cert->subjectHash, cert->subjectKeyHash) == 0) { + WOLFSSL_MSG("\tInternal check doesn't match responder ID, ignoring\n"); + ret = BAD_OCSP_RESPONDER; + goto err; + } + +#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK + if (ret == 0 && !noVerify) { + ret = CheckOcspResponder(resp, cert, cm); + if (ret != 0) { + WOLFSSL_MSG("\tOCSP Responder certificate issuer check failed"); + goto err; + } + } +#endif /* WOLFSSL_NO_OCSP_ISSUER_CHECK */ + if (ret == 0 && !noVerifySignature) { + ret = ConfirmSignature( + &cert->sigCtx, + resp->response, resp->responseSz, + cert->publicKey, cert->pubKeySize, cert->keyOID, + resp->sig, resp->sigSz, resp->sigOID, resp->sigParams, + resp->sigParamsSz, NULL); + } +err: + FreeDecodedCert(cert); + +#ifdef WOLFSSL_SMALL_STACK + if (cert != NULL) { + XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + + return ret; +} + static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, - OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify) + OcspResponse* resp, word32 size, void* cm, void* heap, int noVerify, + int noVerifySignature) { #ifndef WOLFSSL_ASN_TEMPLATE int length; @@ -37132,8 +38431,7 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, #endif int ret; int sigLength; - const byte* sigParams = NULL; - word32 sigParamsSz = 0; + int sigValid = 0; WOLFSSL_ENTER("DecodeBasicOcspResponse"); (void)heap; @@ -37157,16 +38455,16 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, else if (resp->sigOID == CTC_RSASSAPSS) { word32 sz; int len; - const byte* params; + byte* params; sz = idx; params = source + idx; if (GetSequence(source, &idx, &len, size) < 0) - ret = ASN_PARSE_E; + return ASN_PARSE_E; if (ret == 0) { idx += len; - sigParams = params; - sigParamsSz = idx - sz; + resp->sigParams = params; + resp->sigParamsSz = idx - sz; } } #endif @@ -37186,107 +38484,44 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS if (idx < end_index) { - int cert_inited = 0; -#ifdef WOLFSSL_SMALL_STACK - DecodedCert *cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, - DYNAMIC_TYPE_TMP_BUFFER); - if (cert == NULL) - return MEMORY_E; -#else - DecodedCert cert[1]; -#endif - - do { - if (DecodeCerts(source, &idx, resp, size) < 0) { - ret = ASN_PARSE_E; - break; - } - - InitDecodedCert(cert, resp->cert, resp->certSz, heap); - cert_inited = 1; - - /* Don't verify if we don't have access to Cert Manager. */ - ret = ParseCertRelative(cert, CERT_TYPE, - noVerify ? NO_VERIFY : VERIFY_OCSP_CERT, - cm, resp->pendingCAs); - if (ret < 0) { - WOLFSSL_MSG("\tOCSP Responder certificate parsing failed"); - break; - } - -#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK - if ((cert->extExtKeyUsage & EXTKEYUSE_OCSP_SIGN) == 0) { - if (XMEMCMP(cert->subjectHash, - resp->single->issuerHash, OCSP_DIGEST_SIZE) == 0) { - WOLFSSL_MSG("\tOCSP Response signed by issuer"); - } - else { - WOLFSSL_MSG("\tOCSP Responder key usage check failed"); - #ifdef OPENSSL_EXTRA - resp->verifyError = OCSP_BAD_ISSUER; - #else - ret = BAD_OCSP_RESPONDER; - break; - #endif - } - } -#endif - - /* ConfirmSignature is blocking here */ - ret = ConfirmSignature( - &cert->sigCtx, - resp->response, resp->responseSz, - cert->publicKey, cert->pubKeySize, cert->keyOID, - resp->sig, resp->sigSz, resp->sigOID, sigParams, sigParamsSz, - NULL); - - if (ret != 0) { - WOLFSSL_MSG("\tOCSP Confirm signature failed"); - ret = ASN_OCSP_CONFIRM_E; - break; - } - } while(0); - - if (cert_inited) - FreeDecodedCert(cert); -#ifdef WOLFSSL_SMALL_STACK - XFREE(cert, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif + if (DecodeCerts(source, &idx, resp, size) < 0) + return ASN_PARSE_E; - if (ret != 0) - return ret; + ret = OcspCheckCert(resp, noVerify, noVerifySignature, + (WOLFSSL_CERT_MANAGER*)cm, heap); + if (ret == 0) { + sigValid = 1; + } + else { + WOLFSSL_MSG("OCSP Internal cert can't verify the response\n"); + /* try to verify the OCSP response with CA certs */ + ret = 0; + } } else #endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */ - { + if (!noVerifySignature && !sigValid) { Signer* ca; - int sigValid = -1; + SignatureCtx sigCtx; + ca = OcspFindSigner(resp, (WOLFSSL_CERT_MANAGER*)cm); + if (ca == NULL) + return ASN_NO_SIGNER_E; - #ifndef NO_SKID - ca = GetCAByKeyHash(cm, resp->single->issuerKeyHash); - #else - ca = GetCA(cm, resp->single->issuerHash); - #endif -#if defined(HAVE_CERTIFICATE_STATUS_V2) - if (ca == NULL && resp->pendingCAs != NULL) { - ca = findSignerByName(resp->pendingCAs, resp->single->issuerHash); - } +#ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK + if (OcspRespCheck(resp, ca) != 0) + return BAD_OCSP_RESPONDER; #endif - if (ca) { - SignatureCtx sigCtx; - InitSignatureCtx(&sigCtx, heap, INVALID_DEVID); + InitSignatureCtx(&sigCtx, heap, INVALID_DEVID); - /* ConfirmSignature is blocking here */ - sigValid = ConfirmSignature(&sigCtx, resp->response, - resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID, - resp->sig, resp->sigSz, resp->sigOID, sigParams, sigParamsSz, - NULL); - } - if (ca == NULL || sigValid != 0) { + /* ConfirmSignature is blocking here */ + sigValid = ConfirmSignature(&sigCtx, resp->response, + resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID, + resp->sig, resp->sigSz, resp->sigOID, resp->sigParams, + resp->sigParamsSz, NULL); + if (sigValid != 0) { WOLFSSL_MSG("\tOCSP Confirm signature failed"); return ASN_OCSP_CONFIRM_E; } - (void)noVerify; } @@ -37296,16 +38531,8 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, DECL_ASNGETDATA(dataASN, ocspBasicRespASN_Length); int ret = 0; word32 idx = *ioIndex; - const byte* sigParams = NULL; - word32 sigParamsSz = 0; -#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS - #ifdef WOLFSSL_SMALL_STACK - DecodedCert* cert = NULL; - #else - DecodedCert cert[1]; - #endif - int certInit = 0; -#endif + Signer* ca = NULL; + int sigValid = 0; WOLFSSL_ENTER("DecodeBasicOcspResponse"); (void)heap; @@ -37330,10 +38557,10 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, } #ifdef WC_RSA_PSS if (ret == 0 && (dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS].tag != 0)) { - sigParams = GetASNItem_Addr( + resp->sigParams = GetASNItem_Addr( dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS], source); - sigParamsSz = + resp->sigParamsSz = GetASNItem_Length(dataASN[OCSPBASICRESPASN_IDX_SIGNATURE_PARAMS], source); } @@ -37344,6 +38571,7 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_SIGNATURE], &resp->sig, &resp->sigSz); } + resp->certSz = 0; #ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS if ((ret == 0) && (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) { @@ -37351,106 +38579,52 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, /* Store reference to certificate BER data. */ GetASN_GetRef(&dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ], &resp->cert, &resp->certSz); + } - /* Allocate a certificate object to decode cert into. */ - #ifdef WOLFSSL_SMALL_STACK - cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (cert == NULL) { - ret = MEMORY_E; + if ((ret == 0) && resp->certSz > 0) { + ret = OcspCheckCert(resp, noVerify, noVerifySignature, + (WOLFSSL_CERT_MANAGER*)cm, heap); + if (ret == 0) { + sigValid = 1; } + ret = 0; /* try to verify the OCSP response with CA certs */ } - if ((ret == 0) && - (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) { - #endif - /* Initialize the certificate object. */ - InitDecodedCert(cert, resp->cert, resp->certSz, heap); - certInit = 1; - /* Parse the certificate and don't verify if we don't have access to - * Cert Manager. */ - ret = ParseCertRelative(cert, CERT_TYPE, noVerify ? NO_VERIFY : VERIFY, - cm, resp->pendingCAs); - if (ret < 0) { - WOLFSSL_MSG("\tOCSP Responder certificate parsing failed"); - } +#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */ + /* try to verify using cm certs */ + if (ret == 0 && !noVerifySignature && !sigValid) + { + ca = OcspFindSigner(resp, (WOLFSSL_CERT_MANAGER*)cm); + if (ca == NULL) + ret = ASN_NO_SIGNER_E; } #ifndef WOLFSSL_NO_OCSP_ISSUER_CHECK - if ((ret == 0) && - (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL) && - !noVerify) { - ret = CheckOcspResponder(resp, cert, cm); - } -#endif /* WOLFSSL_NO_OCSP_ISSUER_CHECK */ - if ((ret == 0) && - (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data != NULL)) { - /* TODO: ConfirmSignature is blocking here */ - /* Check the signature of the response. */ - ret = ConfirmSignature(&cert->sigCtx, resp->response, resp->responseSz, - cert->publicKey, cert->pubKeySize, cert->keyOID, resp->sig, - resp->sigSz, resp->sigOID, NULL, 0, NULL); - if (ret != 0) { - WOLFSSL_MSG("\tOCSP Confirm signature failed"); - ret = ASN_OCSP_CONFIRM_E; + if (ret == 0 && !noVerifySignature && !sigValid) { + if (OcspRespCheck(resp, ca) != 0) { + ret = BAD_OCSP_RESPONDER; } } - if ((ret == 0) && - (dataASN[OCSPBASICRESPASN_IDX_CERTS_SEQ].data.ref.data == NULL)) -#else - if (ret == 0) -#endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */ - { - Signer* ca; - int sigValid = -1; - - /* Response didn't have a certificate - lookup CA. */ - #ifndef NO_SKID - ca = GetCAByKeyHash(cm, resp->single->issuerKeyHash); - #else - ca = GetCA(cm, resp->single->issuerHash); - #endif - - #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) - if (ca == NULL && resp->pendingCAs != NULL) { - ca = findSignerByName(resp->pendingCAs, resp->single->issuerHash); - } - #endif - - if (ca) { - SignatureCtx sigCtx; - - /* Initialize he signature context. */ - InitSignatureCtx(&sigCtx, heap, INVALID_DEVID); +#endif + if (ret == 0 && !noVerifySignature && !sigValid) { + SignatureCtx sigCtx; + /* Initialize the signature context. */ + InitSignatureCtx(&sigCtx, heap, INVALID_DEVID); - /* TODO: ConfirmSignature is blocking here */ - /* Check the signature of the response CA public key. */ - sigValid = ConfirmSignature(&sigCtx, resp->response, - resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID, - resp->sig, resp->sigSz, resp->sigOID, sigParams, sigParamsSz, - NULL); - } - if ((ca == NULL) || (sigValid != 0)) { - /* Didn't find certificate or signature verificate failed. */ + /* TODO: ConfirmSignature is blocking here */ + /* Check the signature of the response CA public key. */ + sigValid = ConfirmSignature(&sigCtx, resp->response, + resp->responseSz, ca->publicKey, ca->pubKeySize, ca->keyOID, + resp->sig, resp->sigSz, resp->sigOID, resp->sigParams, + resp->sigParamsSz, NULL); + if (sigValid != 0) { WOLFSSL_MSG("\tOCSP Confirm signature failed"); ret = ASN_OCSP_CONFIRM_E; } } - if (ret == 0) { /* Update the position to after response data. */ *ioIndex = idx; } -#ifndef WOLFSSL_NO_OCSP_OPTIONAL_CERTS - if (certInit) { - FreeDecodedCert(cert); - } - #ifdef WOLFSSL_SMALL_STACK - if (cert != NULL) { - /* Dispose of certificate object. */ - XFREE(cert, heap, DYNAMIC_TYPE_TMP_BUFFER); - } - #endif -#endif FREE_ASNGETDATA(dataASN, heap); return ret; #endif /* WOLFSSL_ASN_TEMPLATE */ @@ -37473,6 +38647,9 @@ void InitOcspResponse(OcspResponse* resp, OcspEntry* single, CertStatus* status, resp->maxIdx = inSz; resp->heap = heap; resp->pendingCAs = NULL; + resp->sigParams = NULL; + resp->sigParamsSz = 0; + resp->responderIdType = OCSP_RESPONDER_ID_INVALID; } void FreeOcspResponse(OcspResponse* resp) @@ -37526,7 +38703,8 @@ enum { #define ocspResponseASN_Length (sizeof(ocspResponseASN) / sizeof(ASNItem)) #endif /* WOLFSSL_ASN_TEMPLATE */ -int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify) +int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, + int noVerifyCert, int noVerifySignature) { #ifndef WOLFSSL_ASN_TEMPLATE int ret; @@ -37595,7 +38773,8 @@ int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify) return ret; } - ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, noVerify); + ret = DecodeBasicOcspResponse(source, &idx, resp, size, cm, heap, + noVerifyCert, noVerifySignature); if (ret < 0) { WOLFSSL_LEAVE("OcspResponseDecode", ret); return ret; @@ -37635,7 +38814,7 @@ int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, int noVerify) idx = 0; /* Decode BasicOCSPResponse. */ ret = DecodeBasicOcspResponse(basic, &idx, resp, basicSz, cm, heap, - noVerify); + noVerifyCert, noVerifySignature); } /* Only support BasicOCSPResponse. */ else { @@ -38653,7 +39832,7 @@ static int ParseCRL_CertList(RevokedCert* rcert, DecodedCRL* dcrl, { #if !defined(NO_ASN_TIME) && !defined(WOLFSSL_NO_CRL_DATE_CHECK) if (verify != NO_VERIFY && - !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER)) { + !XVALIDATE_DATE(dcrl->nextDate, dcrl->nextDateFormat, ASN_AFTER)) { WOLFSSL_MSG("CRL after date is no longer valid"); WOLFSSL_ERROR_VERBOSE(CRL_CERT_DATE_ERR); return CRL_CERT_DATE_ERR; @@ -39758,8 +40937,8 @@ int wc_MIME_header_strip(char* in, char** out, size_t start, size_t end) } /***************************************************************************** -* wc_MIME_find_header_name - Searches through all given headers until a header with -* a name matching the provided name is found. +* wc_MIME_find_header_name - Searches through all given headers until a header +* with a name matching the provided name is found. * * RETURNS: * returns a pointer to the found header, if no match was found, returns NULL. @@ -39837,8 +41016,8 @@ char* wc_MIME_single_canonicalize(const char* line, word32* len) } /***************************************************************************** -* wc_MIME_free_hdrs - Frees all MIME headers, parameters and strings starting from -* the provided header pointer. +* wc_MIME_free_hdrs - Frees all MIME headers, parameters and strings starting +* from the provided header pointer. * * RETURNS: * returns zero on success, non-zero on error. @@ -40694,9 +41873,9 @@ int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, #endif /* !NO_RSA && (!NO_BIG_INT || WOLFSSL_SP_MATH) */ #if defined(WOLFSSL_ACERT) && defined(WOLFSSL_ASN_TEMPLATE) -/* Initialize decoded certificate object with buffer of DER encoding. +/* Initialize decoded attribute certificate object with buffer of DER encoding. * - * @param [in, out] cert Decoded certificate object. + * @param [in, out] acert Decoded attribute certificate object. * @param [in] source Buffer containing DER encoded certificate. * @param [in] inSz Size of DER data in buffer in bytes. * @param [in] heap Dynamic memory hint. @@ -40723,7 +41902,7 @@ void InitDecodedAcert(DecodedAcert* acert, const byte* source, word32 inSz, /* Free the decoded attribute cert object's dynamic data. * - * @param [in, out] acert Attribute Decoded certificate object. + * @param [in, out] acert Decoded attribute certificate object. */ void FreeDecodedAcert(DecodedAcert * acert) { @@ -40760,7 +41939,7 @@ void FreeDecodedAcert(DecodedAcert * acert) * @param [in, out] inOutIdx On in, the index of the start of the OtherName. * On out, index after OtherName. * @param [in] len Length of data in buffer. - * @param [in] cert Decoded attribute certificate object. + * @param [in] acert Decoded attribute certificate object. * @param [in, out] entries Linked list of DNS name entries. * * @return 0 on success. @@ -40901,7 +42080,7 @@ static int DecodeAcertGeneralName(const byte* input, word32* inOutIdx, * @param [in] input Buffer holding encoded data. * @param [in] sz Size of encoded data in bytes. * @param [in] tag ASN.1 tag value expected in header. - * @param [in, out] cert Decoded certificate object. + * @param [in, out] acert Decoded attribute certificate object. * @param [in, out] entries Linked list of DNS name entries. * * @return 0 on success. @@ -41027,11 +42206,10 @@ enum { #define HolderASN_Length (sizeof(HolderASN) / sizeof(ASNItem)) /* Decode the Holder field of an x509 attribute certificate. - * * * @param [in] input Buffer containing encoded Holder field. * @param [in] len Length of Holder field. - * @param [in] cert Decoded certificate object. + * @param [in, out] acert Decoded attribute certificate object. * * @return 0 on success. * @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or @@ -41195,7 +42373,7 @@ enum { * * @param [in] input Buffer containing encoded AttCertIssuer field. * @param [in] len Length of Holder field. - * @param [in] cert Decoded certificate object. + * @param [in,out] acert Decoded attribute certificate object. * * @return 0 on success. * @return ASN_PARSE_E when BER encoded data does not match ASN.1 items or @@ -41371,8 +42549,10 @@ enum { * - extensions * - attributes * - * Returns 0 on success. - * Returns negative error code on error/failure. + * @param [in, out] acert Decoded attribute certificate object. + * @param [in] verify Whether to verify dates. + * @return 0 on success. + * @return negative error code on error/fail. * */ int ParseX509Acert(DecodedAcert* acert, int verify) { @@ -41582,7 +42762,6 @@ int ParseX509Acert(DecodedAcert* acert, int verify) } /* Given the parsed attribute cert info, verify the signature. - * * The sigCtx is alloced and freed here. * * @param [in] acinfo the parsed acinfo sequence @@ -41673,7 +42852,7 @@ int VerifyX509Acert(const byte* der, word32 derSz, const byte * sigParams = NULL; word32 sigParamsSz = 0; - WOLFSSL_MSG("ParseX509Acert"); + WOLFSSL_MSG("VerifyX509Acert"); if (der == NULL || pubKey == NULL || derSz == 0 || pubKeySz == 0) { WOLFSSL_MSG("error: VerifyX509Acert: bad args"); @@ -41762,6 +42941,10 @@ int VerifyX509Acert(const byte* der, word32 derSz, return ret; } +/** + * Wrapper API to expose Acert ASN functions. See Acert ASN functions + * for comments. + * */ void wc_InitDecodedAcert(DecodedAcert* acert, const byte* source, word32 inSz, void* heap) { diff --git a/src/wolfcrypt/src/bio.c b/src/wolfcrypt/src/bio.c index b265456..0b52a6c 100644 --- a/src/wolfcrypt/src/bio.c +++ b/src/wolfcrypt/src/bio.c @@ -1,6 +1,6 @@ /* bio.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif +#include -#include #if defined(OPENSSL_EXTRA) && !defined(_WIN32) && !defined(_GNU_SOURCE) /* turn on GNU extensions for XVASPRINTF with wolfSSL_BIO_printf */ #define _GNU_SOURCE 1 @@ -142,7 +139,7 @@ static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len) return WOLFSSL_BIO_ERROR; } - XMEMCPY(buf, bio->mem_buf->data + bio->rdIdx, sz); + XMEMCPY(buf, bio->mem_buf->data + bio->rdIdx, (size_t)sz); bio->rdIdx += sz; if (bio->rdIdx >= bio->wrSz) { @@ -167,14 +164,14 @@ static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len) /* Resize the memory so we are not taking up more than necessary. * memmove reverts internally to memcpy if areas don't overlap */ XMEMMOVE(bio->mem_buf->data, bio->mem_buf->data + bio->rdIdx, - bio->wrSz - bio->rdIdx); + (long unsigned int)bio->wrSz - (size_t)bio->rdIdx); bio->wrSz -= bio->rdIdx; bio->rdIdx = 0; /* Resize down to WOLFSSL_BIO_RESIZE_THRESHOLD for fewer * allocations. */ if (wolfSSL_BUF_MEM_resize(bio->mem_buf, - bio->wrSz > WOLFSSL_BIO_RESIZE_THRESHOLD ? bio->wrSz : - WOLFSSL_BIO_RESIZE_THRESHOLD) == 0) { + bio->wrSz > WOLFSSL_BIO_RESIZE_THRESHOLD ? + (size_t)bio->wrSz : WOLFSSL_BIO_RESIZE_THRESHOLD) == 0) { WOLFSSL_MSG("wolfSSL_BUF_MEM_resize error"); return WOLFSSL_BIO_ERROR; } @@ -389,6 +386,10 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) #endif break; + case WOLFSSL_BIO_NULL: + ret = 0; + break; + } /* switch */ } @@ -564,7 +565,7 @@ static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data, WOLFSSL_MSG("Error in wolfSSL_BIO_nwrite"); return sz1; } - XMEMCPY(buf, data, sz1); + XMEMCPY(buf, data, (size_t)sz1); data = (char*)data + sz1; len -= sz1; @@ -572,7 +573,7 @@ static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data, /* try again to see if maybe we wrapped around the ring buffer */ sz2 = wolfSSL_BIO_nwrite(bio, &buf, len); if (sz2 > 0) { - XMEMCPY(buf, data, sz2); + XMEMCPY(buf, data, (size_t)sz2); sz1 += sz2; if (len > sz2) bio->flags |= WOLFSSL_BIO_FLAG_WRITE|WOLFSSL_BIO_FLAG_RETRY; @@ -610,8 +611,8 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data, if (len == 0) return WOLFSSL_SUCCESS; /* Return early to make logic simpler */ - if (wolfSSL_BUF_MEM_grow_ex(bio->mem_buf, bio->wrSz + len, 0) - == 0) { + if (wolfSSL_BUF_MEM_grow_ex(bio->mem_buf, ((size_t)bio->wrSz) + + ((size_t)len), 0) == 0) { WOLFSSL_MSG("Error growing memory area"); return WOLFSSL_FAILURE; } @@ -621,7 +622,7 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data, return WOLFSSL_FAILURE; } - XMEMCPY(bio->mem_buf->data + bio->wrSz, data, len); + XMEMCPY(bio->mem_buf->data + bio->wrSz, data, (size_t)len); bio->ptr.mem_buf_data = (byte *)bio->mem_buf->data; bio->num.length = bio->mem_buf->max; bio->wrSz += len; @@ -813,6 +814,10 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) #endif break; + case WOLFSSL_BIO_NULL: + ret = len; + break; + } /* switch */ } @@ -1138,7 +1143,7 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz) ret = wolfSSL_BIO_nread(bio, &c, cSz); if (ret > 0 && ret < sz) { - XMEMCPY(buf, c, ret); + XMEMCPY(buf, c, (size_t)ret); } break; } @@ -1161,6 +1166,10 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz) break; #endif /* WOLFCRYPT_ONLY */ + case WOLFSSL_BIO_NULL: + ret = 0; + break; + default: WOLFSSL_MSG("BIO type not supported yet with wolfSSL_BIO_gets"); } @@ -1256,13 +1265,13 @@ size_t wolfSSL_BIO_wpending(const WOLFSSL_BIO *bio) return 0; if (bio->type == WOLFSSL_BIO_MEMORY) { - return bio->wrSz; + return (size_t)bio->wrSz; } /* type BIO_BIO then check paired buffer */ if (bio->type == WOLFSSL_BIO_BIO && bio->pair != NULL) { WOLFSSL_BIO* pair = bio->pair; - return pair->wrIdx; + return (size_t)pair->wrIdx; } return 0; @@ -1308,12 +1317,12 @@ size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio) #ifndef WOLFCRYPT_ONLY if (bio->type == WOLFSSL_BIO_SSL && bio->ptr.ssl != NULL) { - return (long)wolfSSL_pending(bio->ptr.ssl); + return (size_t)wolfSSL_pending(bio->ptr.ssl); } #endif if (bio->type == WOLFSSL_BIO_MEMORY) { - return bio->wrSz - bio->rdIdx; + return (size_t)(bio->wrSz - bio->rdIdx); } /* type BIO_BIO then check paired buffer */ @@ -1322,11 +1331,12 @@ size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio) if (pair->wrIdx > 0 && pair->wrIdx <= pair->rdIdx) { /* in wrap around state where beginning of buffer is being * overwritten */ - return pair->wrSz - pair->rdIdx + pair->wrIdx; + return ((size_t)pair->wrSz) - ((size_t)pair->rdIdx) + + ((size_t)pair->wrIdx); } else { /* simple case where has not wrapped around */ - return pair->wrIdx - pair->rdIdx; + return (size_t)(pair->wrIdx - pair->rdIdx); } } return 0; @@ -1423,7 +1433,7 @@ int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size) XFREE(bio->ptr.mem_buf_data, bio->heap, DYNAMIC_TYPE_OPENSSL); } - bio->ptr.mem_buf_data = (byte*)XMALLOC(size, bio->heap, + bio->ptr.mem_buf_data = (byte*)XMALLOC((size_t)size, bio->heap, DYNAMIC_TYPE_OPENSSL); if (bio->ptr.mem_buf_data == NULL) { WOLFSSL_MSG("Memory allocation error"); @@ -1439,7 +1449,7 @@ int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size) return WOLFSSL_FAILURE; } bio->wrSz = (int)size; - bio->num.length = size; + bio->num.length = (size_t)size; bio->wrIdx = 0; bio->rdIdx = 0; if (bio->mem_buf != NULL) { @@ -1908,7 +1918,7 @@ long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v) int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio) { - int len; + int len = 0; #ifndef NO_FILESYSTEM long memSz = 0; XFILE file; @@ -2309,6 +2319,15 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) return &meth; } + WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_null(void) + { + static WOLFSSL_BIO_METHOD meth = + WOLFSSL_BIO_METHOD_INIT(WOLFSSL_BIO_NULL); + + WOLFSSL_ENTER("wolfSSL_BIO_s_null"); + + return &meth; + } WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void) { @@ -2353,7 +2372,6 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) WOLFSSL_ENTER("wolfSSL_BIO_new_dgram"); if (bio) { - bio->type = WOLFSSL_BIO_DGRAM; bio->shutdown = (byte)closeF; bio->num.fd = (SOCKET_T)fd; } @@ -2381,10 +2399,11 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) else port = str + XSTRLEN(str); /* point to null terminator */ - bio->ip = (char*)XMALLOC((port - str) + 1, /* +1 for null char */ + bio->ip = (char*)XMALLOC( + (size_t)(port - str) + 1, /* +1 for null char */ bio->heap, DYNAMIC_TYPE_OPENSSL); if (bio->ip != NULL) { - XMEMCPY(bio->ip, str, port - str); + XMEMCPY(bio->ip, str, (size_t)(port - str)); bio->ip[port - str] = '\0'; bio->type = WOLFSSL_BIO_SOCKET; } @@ -2770,9 +2789,23 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) } else { size_t currLen = XSTRLEN(b->ip); + #ifdef WOLFSSL_NO_REALLOC + char* tmp = NULL; + #endif + if (currLen != newLen) { + #ifdef WOLFSSL_NO_REALLOC + tmp = b->ip; + b->ip = (char*)XMALLOC(newLen+1, b->heap, DYNAMIC_TYPE_OPENSSL); + if (b->ip != NULL && tmp != NULL) { + XMEMCPY(b->ip, tmp, newLen); + XFREE(tmp, b->heap, DYNAMIC_TYPE_OPENSSL); + tmp = NULL; + } + #else b->ip = (char*)XREALLOC(b->ip, newLen + 1, b->heap, DYNAMIC_TYPE_OPENSSL); + #endif if (b->ip == NULL) { WOLFSSL_MSG("Hostname realloc failed."); return WOLFSSL_FAILURE; @@ -2926,7 +2959,7 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) bio->wrSz = len; bio->ptr.mem_buf_data = (byte *)bio->mem_buf->data; if (len > 0 && bio->ptr.mem_buf_data != NULL) { - XMEMCPY(bio->ptr.mem_buf_data, buf, len); + XMEMCPY(bio->ptr.mem_buf_data, buf, (size_t)len); bio->flags |= WOLFSSL_BIO_FLAG_MEM_RDONLY; bio->wrSzReset = bio->wrSz; } @@ -3295,11 +3328,11 @@ int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args) count = XVSNPRINTF(NULL, 0, format, args); if (count >= 0) { - pt = (char*)XMALLOC(count + 1, bio->heap, + pt = (char*)XMALLOC((size_t)count + 1, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); if (pt != NULL) { - count = XVSNPRINTF(pt, count + 1, format, copy); + count = XVSNPRINTF(pt, (size_t)count + 1, format, copy); if (count >= 0) { ret = wolfSSL_BIO_write(bio, pt, count); @@ -3369,18 +3402,20 @@ int wolfSSL_BIO_dump(WOLFSSL_BIO *bio, const char *buf, int length) o = 7; for (i = 0; i < BIO_DUMP_LINE_LEN; i++) { if (i < length) - (void)XSNPRINTF(line + o, (int)sizeof(line) - o, + (void)XSNPRINTF(line + o, (size_t)((int)sizeof(line) - o), "%02x ", (unsigned char)buf[i]); else - (void)XSNPRINTF(line + o, (int)sizeof(line) - o, " "); + (void)XSNPRINTF(line + o, (size_t)((int)sizeof(line) - o), + " "); if (i == 7) - (void)XSNPRINTF(line + o + 2, (int)sizeof(line) - (o + 2), "-"); + (void)XSNPRINTF(line + o + 2, (size_t)((int)sizeof(line) - + (o + 2)), "-"); o += 3; } - (void)XSNPRINTF(line + o, (int)sizeof(line) - o, " "); + (void)XSNPRINTF(line + o, (size_t)((int)sizeof(line) - o), " "); o += 2; for (i = 0; (i < BIO_DUMP_LINE_LEN) && (i < length); i++) { - (void)XSNPRINTF(line + o, (int)sizeof(line) - o, "%c", + (void)XSNPRINTF(line + o, (size_t)((int)sizeof(line) - o), "%c", ((31 < buf[i]) && (buf[i] < 127)) ? buf[i] : '.'); o++; } diff --git a/src/wolfcrypt/src/blake2b.c b/src/wolfcrypt/src/blake2b.c index bce74b3..c1f3e7a 100644 --- a/src/wolfcrypt/src/blake2b.c +++ b/src/wolfcrypt/src/blake2b.c @@ -12,7 +12,7 @@ */ /* blake2b.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -31,20 +31,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef HAVE_BLAKE2 #include #include -#include - static const word64 blake2b_IV[8] = { @@ -491,6 +483,16 @@ int wc_InitBlake2b_WithKey(Blake2b* b2b, word32 digestSz, const byte *key, word3 /* Blake2b Update */ int wc_Blake2bUpdate(Blake2b* b2b, const byte* data, word32 sz) { + if (b2b == NULL){ + return BAD_FUNC_ARG; + } + if (data == NULL && sz != 0){ + return BAD_FUNC_ARG; + } + if (sz == 0){ + return 0; + } + return blake2b_update(b2b->S, data, sz); } @@ -498,7 +500,16 @@ int wc_Blake2bUpdate(Blake2b* b2b, const byte* data, word32 sz) /* Blake2b Final, if pass in zero size we use init digestSz */ int wc_Blake2bFinal(Blake2b* b2b, byte* final, word32 requestSz) { - word32 sz = requestSz ? requestSz : b2b->digestSz; + word32 sz; + + if (b2b == NULL){ + return BAD_FUNC_ARG; + } + if (final == NULL){ + return BAD_FUNC_ARG; + } + + sz = requestSz ? requestSz : b2b->digestSz; return blake2b_final(b2b->S, final, (byte)sz); } diff --git a/src/wolfcrypt/src/blake2s.c b/src/wolfcrypt/src/blake2s.c index 7e36d6e..7f9d3ff 100644 --- a/src/wolfcrypt/src/blake2s.c +++ b/src/wolfcrypt/src/blake2s.c @@ -12,7 +12,7 @@ */ /* blake2s.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -31,20 +31,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef HAVE_BLAKE2S #include #include -#include - static const word32 blake2s_IV[8] = { @@ -487,6 +479,16 @@ int wc_InitBlake2s_WithKey(Blake2s* b2s, word32 digestSz, const byte *key, word3 /* Blake2s Update */ int wc_Blake2sUpdate(Blake2s* b2s, const byte* data, word32 sz) { + if (b2s == NULL){ + return BAD_FUNC_ARG; + } + if (data == NULL && sz != 0){ + return BAD_FUNC_ARG; + } + if (sz == 0){ + return 0; + } + return blake2s_update(b2s->S, data, sz); } @@ -494,7 +496,16 @@ int wc_Blake2sUpdate(Blake2s* b2s, const byte* data, word32 sz) /* Blake2s Final, if pass in zero size we use init digestSz */ int wc_Blake2sFinal(Blake2s* b2s, byte* final, word32 requestSz) { - word32 sz = requestSz ? requestSz : b2s->digestSz; + word32 sz; + + if (b2s == NULL){ + return BAD_FUNC_ARG; + } + if (final == NULL){ + return BAD_FUNC_ARG; + } + + sz = requestSz ? requestSz : b2s->digestSz; return blake2s_final(b2s->S, final, (byte)sz); } diff --git a/src/wolfcrypt/src/camellia.c b/src/wolfcrypt/src/camellia.c index bd9ae1b..c1ff47e 100644 --- a/src/wolfcrypt/src/camellia.c +++ b/src/wolfcrypt/src/camellia.c @@ -27,7 +27,7 @@ /* camellia.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -52,18 +52,11 @@ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef HAVE_CAMELLIA #include -#include -#include #ifdef NO_INLINE #include #else diff --git a/src/wolfcrypt/src/chacha.c b/src/wolfcrypt/src/chacha.c index ba9aa53..1a1d676 100644 --- a/src/wolfcrypt/src/chacha.c +++ b/src/wolfcrypt/src/chacha.c @@ -1,6 +1,6 @@ /* chacha.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -29,15 +29,10 @@ Public domain. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef HAVE_CHACHA #include - #include #ifdef NO_INLINE #include @@ -72,10 +67,10 @@ Public domain. #endif /* HAVE_CHACHA */ -#if defined(WOLFSSL_ARMASM) +#if defined(WOLFSSL_ARMASM) && !defined(NO_CHACHA_ASM) /* implementation is located in wolfcrypt/src/port/arm/armv8-chacha.c */ -#elif defined(WOLFSSL_RISCV_ASM) +#elif defined(WOLFSSL_RISCV_ASM) && !defined(NO_CHACHA_ASM) /* implementation located in wolfcrypt/src/port/riscv/riscv-64-chacha.c */ #else @@ -83,7 +78,6 @@ Public domain. /* BEGIN ChaCha C implementation */ #if defined(HAVE_CHACHA) -#include #include #ifdef CHACHA_AEAD_TEST diff --git a/src/wolfcrypt/src/chacha20_poly1305.c b/src/wolfcrypt/src/chacha20_poly1305.c index a29a18f..09d522d 100644 --- a/src/wolfcrypt/src/chacha20_poly1305.c +++ b/src/wolfcrypt/src/chacha20_poly1305.c @@ -1,6 +1,6 @@ /* chacha.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -27,17 +27,11 @@ or Authenticated Encryption with Additional Data (AEAD) algorithm. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) #include -#include -#include #ifdef NO_INLINE #include diff --git a/src/wolfcrypt/src/cmac.c b/src/wolfcrypt/src/cmac.c index 2f5d5d4..b83214c 100644 --- a/src/wolfcrypt/src/cmac.c +++ b/src/wolfcrypt/src/cmac.c @@ -1,6 +1,6 @@ /* cmac.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include -#ifdef HAVE_CONFIG_H - #include -#endif - -#include #ifdef WOLFSSL_QNX_CAAM #include #endif @@ -51,7 +47,6 @@ #include #endif -#include #include #include @@ -212,7 +207,7 @@ int wc_CmacUpdate(Cmac* cmac, const byte* in, word32 inSz) #endif { ret = wc_CryptoCb_Cmac(cmac, NULL, 0, in, inSz, - NULL, NULL, cmac->type, NULL); + NULL, NULL, (int)cmac->type, NULL); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) return ret; /* fall-through when unavailable */ @@ -294,8 +289,8 @@ int wc_CmacFinalNoFree(Cmac* cmac, byte* out, word32* outSz) if (cmac->devId != INVALID_DEVID) #endif { - ret = wc_CryptoCb_Cmac(cmac, NULL, 0, NULL, 0, out, outSz, cmac->type, - NULL); + ret = wc_CryptoCb_Cmac(cmac, NULL, 0, NULL, 0, out, outSz, + (int)cmac->type, NULL); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) return ret; diff --git a/src/wolfcrypt/src/coding.c b/src/wolfcrypt/src/coding.c index 7071796..739fde5 100644 --- a/src/wolfcrypt/src/coding.c +++ b/src/wolfcrypt/src/coding.c @@ -1,6 +1,6 @@ /* coding.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,18 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifndef NO_CODING #include -#include -#include #ifndef NO_ASN #include /* For PEM_LINE_SZ */ #endif @@ -59,23 +52,33 @@ enum { #ifdef WOLFSSL_BASE64_DECODE -#ifdef BASE64_NO_TABLE -static WC_INLINE byte Base64_Char2Val(byte c) +static WC_INLINE byte Base64_Char2Val_CT(byte c) { - word16 v = 0x0000; + int v; + int smallEnd = (int)c - 0x7b; + int smallStart = (int)c - 0x61; + int bigEnd = (int)c - 0x5b; + int bigStart = (int)c - 0x41; + int numEnd = (int)c - 0x3a; + int numStart = (int)c - 0x30; + int slashEnd = (int)c - 0x30; + int slashStart = (int)c - 0x2f; + int plusEnd = (int)c - 0x2c; + int plusStart = (int)c - 0x2b; + + v = ((smallStart >> 8) ^ (smallEnd >> 8)) & (smallStart + 26 + 1); + v |= ((bigStart >> 8) ^ (bigEnd >> 8)) & (bigStart + 0 + 1); + v |= ((numStart >> 8) ^ (numEnd >> 8)) & (numStart + 52 + 1); + v |= ((slashStart >> 8) ^ (slashEnd >> 8)) & (slashStart + 63 + 1); + v |= ((plusStart >> 8) ^ (plusEnd >> 8)) & (plusStart + 62 + 1); + + return (byte)(v - 1); +} - v |= 0xff3E & ctMask16Eq(c, 0x2b); - v |= 0xff3F & ctMask16Eq(c, 0x2f); - v |= (c + 0xff04) & ctMask16GTE(c, 0x30) & ctMask16LTE(c, 0x39); - v |= (0xff00 + c - 0x41) & ctMask16GTE(c, 0x41) & ctMask16LTE(c, 0x5a); - v |= (0xff00 + c - 0x47) & ctMask16GTE(c, 0x61) & ctMask16LTE(c, 0x7a); - v |= ~(v >> 8); +#ifndef BASE64_NO_TABLE - return (byte)v; -} -#else static -ALIGN64 const byte base64Decode[] = { /* + starts at 0x2B */ +ALIGN64 const byte base64Decode_table[] = { /* + starts at 0x2B */ /* 0x28: + , - . / */ 62, BAD, BAD, BAD, 63, /* 0x30: 0 1 2 3 4 5 6 7 */ 52, 53, 54, 55, 56, 57, 58, 59, /* 0x38: 8 9 : ; < = > ? */ 60, 61, BAD, BAD, BAD, BAD, BAD, BAD, @@ -88,11 +91,11 @@ ALIGN64 const byte base64Decode[] = { /* + starts at 0x2B */ /* 0x70: p q r s t u v w */ 41, 42, 43, 44, 45, 46, 47, 48, /* 0x78: x y z */ 49, 50, 51 }; -#define BASE64DECODE_SZ (byte)(sizeof(base64Decode)) +#define BASE64DECODE_TABLE_SZ (byte)(sizeof(base64Decode_table)) -static WC_INLINE byte Base64_Char2Val(byte c) +static WC_INLINE byte Base64_Char2Val_by_table(byte c) { -#ifndef WC_NO_CACHE_RESISTANT +#ifdef WC_CACHE_RESISTANT_BASE64_TABLE /* 80 characters in table. * 64 bytes in a cache line - first line has 64, second has 16 */ @@ -102,16 +105,17 @@ static WC_INLINE byte Base64_Char2Val(byte c) c = (byte)(c - BASE64_MIN); mask = (byte)((((byte)(0x3f - c)) >> 7) - 1); /* Load a value from the first cache line and use when mask set. */ - v = (byte)(base64Decode[ c & 0x3f ] & mask); + v = (byte)(base64Decode_table[ c & 0x3f ] & mask); /* Load a value from the second cache line and use when mask not set. */ - v |= (byte)(base64Decode[(c & 0x0f) | 0x40] & (~mask)); + v |= (byte)(base64Decode_table[(c & 0x0f) | 0x40] & (~mask)); return v; #else - return base64Decode[c - BASE64_MIN]; + return base64Decode_table[c - BASE64_MIN]; #endif } -#endif + +#endif /* !BASE64_NO_TABLE */ int Base64_SkipNewline(const byte* in, word32 *inLen, word32 *outJ) @@ -161,15 +165,15 @@ int Base64_SkipNewline(const byte* in, word32 *inLen, return 0; } -int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) +#ifndef BASE64_NO_TABLE + +int Base64_Decode_nonCT(const byte* in, word32 inLen, byte* out, word32* outLen) { word32 i = 0; word32 j = 0; word32 plainSz = inLen - ((inLen + (BASE64_LINE_SZ - 1)) / BASE64_LINE_SZ ); int ret; -#ifndef BASE64_NO_TABLE - const byte maxIdx = BASE64DECODE_SZ + BASE64_MIN - 1; -#endif + const byte maxIdx = BASE64DECODE_TABLE_SZ + BASE64_MIN - 1; plainSz = (plainSz * 3 + 3) / 4; if (plainSz > *outLen) return BAD_FUNC_ARG; @@ -216,7 +220,6 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) if (pad3 && !pad4) return ASN_INPUT_E; -#ifndef BASE64_NO_TABLE if (e1 < BASE64_MIN || e2 < BASE64_MIN || e3 < BASE64_MIN || e4 < BASE64_MIN) { WOLFSSL_MSG("Bad Base64 Decode data, too small"); @@ -227,17 +230,16 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) WOLFSSL_MSG("Bad Base64 Decode data, too big"); return ASN_INPUT_E; } -#endif if (i + 1 + !pad3 + !pad4 > *outLen) { WOLFSSL_MSG("Bad Base64 Decode out buffer, too small"); return BAD_FUNC_ARG; } - e1 = Base64_Char2Val(e1); - e2 = Base64_Char2Val(e2); - e3 = (byte)((e3 == PAD) ? 0 : Base64_Char2Val(e3)); - e4 = (byte)((e4 == PAD) ? 0 : Base64_Char2Val(e4)); + e1 = Base64_Char2Val_by_table(e1); + e2 = Base64_Char2Val_by_table(e2); + e3 = (byte)((e3 == PAD) ? 0 : Base64_Char2Val_by_table(e3)); + e4 = (byte)((e4 == PAD) ? 0 : Base64_Char2Val_by_table(e4)); if (e1 == BAD || e2 == BAD || e3 == BAD || e4 == BAD) { WOLFSSL_MSG("Bad Base64 Decode bad character"); @@ -256,7 +258,8 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) else break; } -/* If the output buffer has a room for an extra byte, add a null terminator */ + + /* If the output buffer has a room for an extra byte, add a null terminator */ if (out && *outLen > i) out[i]= '\0'; @@ -265,6 +268,103 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) return 0; } +#endif /* !BASE64_NO_TABLE */ + +int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) +{ + word32 i = 0; + word32 j = 0; + word32 plainSz = inLen - ((inLen + (BASE64_LINE_SZ - 1)) / BASE64_LINE_SZ ); + int ret; + + plainSz = (plainSz * 3 + 3) / 4; + if (plainSz > *outLen) return BAD_FUNC_ARG; + + while (inLen > 3) { + int pad3 = 0; + int pad4 = 0; + byte b1, b2, b3; + byte e1, e2, e3, e4; + + if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { + if (ret == WC_NO_ERR_TRACE(BUFFER_E)) { + /* Running out of buffer here is not an error */ + break; + } + return ret; + } + e1 = in[j++]; + if (e1 == '\0') { + break; + } + inLen--; + if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { + return ret; + } + e2 = in[j++]; + inLen--; + if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { + return ret; + } + e3 = in[j++]; + inLen--; + if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { + return ret; + } + e4 = in[j++]; + inLen--; + + if (e3 == PAD) + pad3 = 1; + if (e4 == PAD) + pad4 = 1; + + if (pad3 && !pad4) + return ASN_INPUT_E; + + if (i + 1 + !pad3 + !pad4 > *outLen) { + WOLFSSL_MSG("Bad Base64 Decode out buffer, too small"); + return BAD_FUNC_ARG; + } + + e1 = Base64_Char2Val_CT(e1); + e2 = Base64_Char2Val_CT(e2); + e3 = (byte)((e3 == PAD) ? 0 : Base64_Char2Val_CT(e3)); + e4 = (byte)((e4 == PAD) ? 0 : Base64_Char2Val_CT(e4)); + + if (e1 == BAD || e2 == BAD || e3 == BAD || e4 == BAD) { + WOLFSSL_MSG("Bad Base64 Decode bad character"); + return ASN_INPUT_E; + } + + b1 = (byte)((e1 << 2) | (e2 >> 4)); + b2 = (byte)(((e2 & 0xF) << 4) | (e3 >> 2)); + b3 = (byte)(((e3 & 0x3) << 6) | e4); + + out[i++] = b1; + if (!pad3) + out[i++] = b2; + if (!pad4) + out[i++] = b3; + else + break; + } + + /* If the output buffer has a room for an extra byte, add a null terminator */ + if (out && *outLen > i) + out[i]= '\0'; + + *outLen = i; + + return 0; +} + +#ifdef BASE64_NO_TABLE +int Base64_Decode_nonCT(const byte* in, word32 inLen, byte* out, word32* outLen) { + return Base64_Decode(in, inLen, out, outLen); +} +#endif /* BASE64_NO_TABLE */ + #endif /* WOLFSSL_BASE64_DECODE */ #if defined(WOLFSSL_BASE64_ENCODE) @@ -490,7 +590,7 @@ int Base64_Encode_NoNl(const byte* in, word32 inLen, byte* out, word32* outLen) #ifdef WOLFSSL_BASE16 static -const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +const ALIGN64 byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, BAD, BAD, BAD, BAD, BAD, BAD, BAD, 10, 11, 12, 13, 14, 15, /* upper case A-F */ BAD, BAD, BAD, BAD, BAD, BAD, BAD, BAD, @@ -556,6 +656,11 @@ int Base16_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) return 0; } +static +const ALIGN64 byte hexEncode[] = { '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' +}; + int Base16_Encode(const byte* in, word32 inLen, byte* out, word32* outLen) { word32 outIdx = 0; @@ -571,15 +676,8 @@ int Base16_Encode(const byte* in, word32 inLen, byte* out, word32* outLen) byte hb = in[i] >> 4; byte lb = in[i] & 0x0f; - /* ASCII value */ - hb = (byte)(hb + '0'); - if (hb > '9') - hb = (byte)(hb + 7U); - - /* ASCII value */ - lb = (byte)(lb + '0'); - if (lb>'9') - lb = (byte)(lb + 7U); + hb = hexEncode[hb]; + lb = hexEncode[lb]; out[outIdx++] = hb; out[outIdx++] = lb; diff --git a/src/wolfcrypt/src/compress.c b/src/wolfcrypt/src/compress.c index 941596e..e3c42cc 100644 --- a/src/wolfcrypt/src/compress.c +++ b/src/wolfcrypt/src/compress.c @@ -1,6 +1,6 @@ /* compress.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,20 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef HAVE_LIBZ #include -#include -#include #ifdef NO_INLINE #include #else diff --git a/src/wolfcrypt/src/cpuid.c b/src/wolfcrypt/src/cpuid.c index a9f1533..37fe855 100644 --- a/src/wolfcrypt/src/cpuid.c +++ b/src/wolfcrypt/src/cpuid.c @@ -1,6 +1,6 @@ /* cpuid.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #include @@ -60,7 +55,8 @@ int got_intel_cpu = 0; int got_amd_cpu = 0; unsigned int reg[5]; - reg[4] = '\0'; + + XMEMSET(reg, '\0', sizeof(reg)); cpuid(reg, 0, 0); /* check for Intel cpu */ @@ -163,23 +159,36 @@ if (!cpuid_check) { word64 hwcaps = getauxval(AT_HWCAP); + #ifndef WOLFSSL_ARMASM_NO_HW_CRYPTO if (hwcaps & HWCAP_AES) cpuid_flags |= CPUID_AES; if (hwcaps & HWCAP_PMULL) cpuid_flags |= CPUID_PMULL; if (hwcaps & HWCAP_SHA2) cpuid_flags |= CPUID_SHA256; + #endif + #ifdef WOLFSSL_ARMASM_CRYPTO_SHA512 if (hwcaps & HWCAP_SHA512) cpuid_flags |= CPUID_SHA512; + #endif + #if defined(HWCAP_ASIMDRDM) && !defined(WOLFSSL_AARCH64_NO_SQRDMLSH) if (hwcaps & HWCAP_ASIMDRDM) cpuid_flags |= CPUID_RDM; + #endif + #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3 if (hwcaps & HWCAP_SHA3) cpuid_flags |= CPUID_SHA3; + #endif + #ifdef WOLFSSL_ARMASM_CRYPTO_SM3 if (hwcaps & HWCAP_SM3) cpuid_flags |= CPUID_SM3; + #endif + #ifdef WOLFSSL_ARMASM_CRYPTO_SM4 if (hwcaps & HWCAP_SM4) cpuid_flags |= CPUID_SM4; + #endif + (void)hwcaps; cpuid_check = 1; } } @@ -259,8 +268,10 @@ if (features & CPUID_AARCH64_FEAT_AES) cpuid_flags |= CPUID_AES; - if (features & CPUID_AARCH64_FEAT_PMULL) + if (features & CPUID_AARCH64_FEAT_AES_PMULL) { + cpuid_flags |= CPUID_AES; cpuid_flags |= CPUID_PMULL; + } if (features & CPUID_AARCH64_FEAT_SHA256) cpuid_flags |= CPUID_SHA256; if (features & CPUID_AARCH64_FEAT_SHA256_512) @@ -289,7 +300,7 @@ #ifdef WOLFSSL_ARMASM_CRYPTO_SHA512 cpuid_flags |= CPUID_SHA512; #endif - #ifndef WOLFSSL_AARCH64_NO_SQRMLSH + #ifndef WOLFSSL_AARCH64_NO_SQRDMLSH cpuid_flags |= CPUID_RDM; #endif #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3 diff --git a/src/wolfcrypt/src/cryptocb.c b/src/wolfcrypt/src/cryptocb.c index 973b4f9..a83e529 100644 --- a/src/wolfcrypt/src/cryptocb.c +++ b/src/wolfcrypt/src/cryptocb.c @@ -1,6 +1,6 @@ /* cryptocb.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -36,17 +36,11 @@ * DEBUG_CRYPTOCB */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLF_CRYPTO_CB #include -#include -#include #ifdef HAVE_ARIA #include @@ -207,6 +201,8 @@ WOLFSSL_API void wc_CryptoCb_InfoString(wc_CryptoInfo* info) info->cipher.type, info->cipher.ctx); } #endif /* !NO_AES || !NO_DES3 */ +#if !defined(NO_SHA) || !defined(NO_SHA256) || \ + defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA3) else if (info->algo_type == WC_ALGO_TYPE_HASH) { printf("Crypto CB: %s %s (%d) (%p ctx) %s\n", GetAlgoTypeStr(info->algo_type), @@ -214,6 +210,8 @@ WOLFSSL_API void wc_CryptoCb_InfoString(wc_CryptoInfo* info) info->hash.type, info->hash.ctx, (info->hash.in != NULL) ? "Update" : "Final"); } +#endif +#ifndef NO_HMAC else if (info->algo_type == WC_ALGO_TYPE_HMAC) { printf("Crypto CB: %s %s (%d) (%p ctx) %s\n", GetAlgoTypeStr(info->algo_type), @@ -221,6 +219,7 @@ WOLFSSL_API void wc_CryptoCb_InfoString(wc_CryptoInfo* info) info->hmac.macType, info->hmac.hmac, (info->hmac.in != NULL) ? "Update" : "Final"); } +#endif #ifdef WOLFSSL_CMAC else if (info->algo_type == WC_ALGO_TYPE_CMAC) { printf("Crypto CB: %s %s (%d) (%p ctx) %s %s %s\n", @@ -865,7 +864,7 @@ int wc_CryptoCb_Ed25519Verify(const byte* sig, word32 sigLen, } #endif /* HAVE_ED25519 */ -#if defined(WOLFSSL_HAVE_KYBER) +#if defined(WOLFSSL_HAVE_MLKEM) int wc_CryptoCb_PqcKemGetDevId(int type, void* key) { int devId = INVALID_DEVID; @@ -984,7 +983,7 @@ int wc_CryptoCb_PqcDecapsulate(const byte* ciphertext, word32 ciphertextLen, return wc_CryptoCb_TranslateErrorCode(ret); } -#endif /* WOLFSSL_HAVE_KYBER */ +#endif /* WOLFSSL_HAVE_MLKEM */ #if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) int wc_CryptoCb_PqcSigGetDevId(int type, void* key) @@ -1043,7 +1042,8 @@ int wc_CryptoCb_MakePqcSignatureKey(WC_RNG* rng, int type, int keySize, } int wc_CryptoCb_PqcSign(const byte* in, word32 inlen, byte* out, word32 *outlen, - WC_RNG* rng, int type, void* key) + const byte* context, byte contextLen, word32 preHashType, WC_RNG* rng, + int type, void* key) { int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); int devId = INVALID_DEVID; @@ -1068,6 +1068,9 @@ int wc_CryptoCb_PqcSign(const byte* in, word32 inlen, byte* out, word32 *outlen, cryptoInfo.pk.pqc_sign.inlen = inlen; cryptoInfo.pk.pqc_sign.out = out; cryptoInfo.pk.pqc_sign.outlen = outlen; + cryptoInfo.pk.pqc_sign.context = context; + cryptoInfo.pk.pqc_sign.contextLen = contextLen; + cryptoInfo.pk.pqc_sign.preHashType = preHashType; cryptoInfo.pk.pqc_sign.rng = rng; cryptoInfo.pk.pqc_sign.key = key; cryptoInfo.pk.pqc_sign.type = type; @@ -1079,7 +1082,8 @@ int wc_CryptoCb_PqcSign(const byte* in, word32 inlen, byte* out, word32 *outlen, } int wc_CryptoCb_PqcVerify(const byte* sig, word32 siglen, const byte* msg, - word32 msglen, int* res, int type, void* key) + word32 msglen, const byte* context, byte contextLen, word32 preHashType, + int* res, int type, void* key) { int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE); int devId = INVALID_DEVID; @@ -1104,6 +1108,9 @@ int wc_CryptoCb_PqcVerify(const byte* sig, word32 siglen, const byte* msg, cryptoInfo.pk.pqc_verify.siglen = siglen; cryptoInfo.pk.pqc_verify.msg = msg; cryptoInfo.pk.pqc_verify.msglen = msglen; + cryptoInfo.pk.pqc_verify.context = context; + cryptoInfo.pk.pqc_verify.contextLen = contextLen; + cryptoInfo.pk.pqc_verify.preHashType = preHashType; cryptoInfo.pk.pqc_verify.res = res; cryptoInfo.pk.pqc_verify.key = key; cryptoInfo.pk.pqc_verify.type = type; @@ -1874,6 +1881,12 @@ int wc_CryptoCb_DefaultDevID(void) { int ret; +/* Explicitly disable the "default devId" behavior. Ensures that any devId + * will only be used if explicitly passed as an argument to crypto functions, + * and never automatically selected. */ +#ifdef WC_NO_DEFAULT_DEVID + ret = INVALID_DEVID; +#else /* conditional macro selection based on build */ #ifdef WOLFSSL_CAAM_DEVID ret = WOLFSSL_CAAM_DEVID; @@ -1885,6 +1898,7 @@ int wc_CryptoCb_DefaultDevID(void) /* try first available */ ret = wc_CryptoCb_GetDevIdAtIndex(0); #endif +#endif /* WC_NO_DEFAULT_DEVID */ return ret; } diff --git a/src/wolfcrypt/src/curve25519.c b/src/wolfcrypt/src/curve25519.c index 8f409da..ae2a6b4 100644 --- a/src/wolfcrypt/src/curve25519.c +++ b/src/wolfcrypt/src/curve25519.c @@ -1,6 +1,6 @@ /* curve25519.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -22,17 +22,11 @@ /* Based On Daniel J Bernstein's curve25519 Public Domain ref10 work. */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef HAVE_CURVE25519 #include -#include #ifdef NO_INLINE #include #else @@ -51,6 +45,14 @@ #include #endif +#if defined(WOLFSSL_CURVE25519_BLINDING) + #if defined(CURVE25519_SMALL) + #error "Blinding not needed nor available for small implementation" + #elif defined(USE_INTEL_SPEEDUP) || defined(WOLFSSL_ARMASM) + #error "Blinding not needed nor available for assembly implementation" + #endif +#endif + #if defined(WOLFSSL_LINUXKM) && !defined(USE_INTEL_SPEEDUP) /* force off unneeded vector register save/restore. */ #undef SAVE_VECTOR_REGISTERS @@ -143,6 +145,7 @@ int wc_curve25519_make_pub(int public_size, byte* pub, int private_size, XMEMCPY(pub, wc_pub.point, CURVE25519_KEYSIZE); } #else +#ifndef WOLFSSL_CURVE25519_BLINDING fe_init(); SAVE_VECTOR_REGISTERS(return _svr_ret;); @@ -150,10 +153,119 @@ int wc_curve25519_make_pub(int public_size, byte* pub, int private_size, ret = curve25519(pub, priv, (byte*)kCurve25519BasePoint); RESTORE_VECTOR_REGISTERS(); +#else + { + WC_RNG rng; + + ret = wc_InitRng(&rng); + if (ret == 0) { + ret = wc_curve25519_make_pub_blind(public_size, pub, private_size, + priv, &rng); + + wc_FreeRng(&rng); + } + } +#endif /* !WOLFSSL_CURVE25519_BLINDING */ +#endif /* FREESCALE_LTC_ECC */ + + return ret; +} + +#ifdef WOLFSSL_CURVE25519_BLINDING +#ifndef FREESCALE_LTC_ECC +#ifndef WOLFSSL_CURVE25519_BLINDING_RAND_CNT + #define WOLFSSL_CURVE25519_BLINDING_RAND_CNT 10 +#endif +static int curve25519_smul_blind(byte* rp, const byte* n, const byte* p, + WC_RNG* rng) +{ + int ret; + byte a[CURVE25519_KEYSIZE]; + byte n_a[CURVE25519_KEYSIZE]; + byte rz[CURVE25519_KEYSIZE]; + int i; + int cnt; + + SAVE_VECTOR_REGISTERS(return _svr_ret;); + + /* Generate random z. */ + for (cnt = 0; cnt < WOLFSSL_CURVE25519_BLINDING_RAND_CNT; cnt++) { + ret = wc_RNG_GenerateBlock(rng, rz, sizeof(rz)); + if (ret < 0) { + return ret; + } + for (i = CURVE25519_KEYSIZE; i > 0; i--) { + if (rz[i] != 0xff) + break; + } + if ((i != 0) || (rz[0] <= 0xec)) { + break; + } + } + if (cnt == WOLFSSL_CURVE25519_BLINDING_RAND_CNT) { + return RNG_FAILURE_E; + } + + /* Generate 253 random bits. */ + ret = wc_RNG_GenerateBlock(rng, a, sizeof(a)); + if (ret != 0) + return ret; + a[CURVE25519_KEYSIZE-1] &= 0x7f; + /* k' = k ^ 2k ^ a */ + n_a[0] = n[0] ^ (n[0] << 1) ^ a[0]; + for (i = 1; i < CURVE25519_KEYSIZE; i++) { + byte b1, b2, b3; + b1 = n[i] ^ a[i]; + b2 = (n[i] << 1) ^ a[i]; + b3 = (n[i-1] >> 7) ^ a[i]; + n_a[i] = b1 ^ b2 ^ b3; + } + /* Scalar multiple blinded scalar with blinding value. */ + ret = curve25519_blind(rp, n_a, a, p, rz); + + RESTORE_VECTOR_REGISTERS(); + + return ret; +} +#endif + +int wc_curve25519_make_pub_blind(int public_size, byte* pub, int private_size, + const byte* priv, WC_RNG* rng) +{ + int ret; +#ifdef FREESCALE_LTC_ECC + const ECPoint* basepoint = nxp_ltc_curve25519_GetBasePoint(); + ECPoint wc_pub; +#endif + + if ( (public_size != CURVE25519_KEYSIZE) || + (private_size != CURVE25519_KEYSIZE)) { + return ECC_BAD_ARG_E; + } + if ((pub == NULL) || (priv == NULL)) { + return ECC_BAD_ARG_E; + } + + /* check clamping */ + ret = curve25519_priv_clamp_check(priv); + if (ret != 0) + return ret; + +#ifdef FREESCALE_LTC_ECC + /* input basepoint on Weierstrass curve */ + ret = nxp_ltc_curve25519(&wc_pub, priv, basepoint, kLTC_Weierstrass); + if (ret == 0) { + XMEMCPY(pub, wc_pub.point, CURVE25519_KEYSIZE); + } +#else + fe_init(); + + ret = curve25519_smul_blind(pub, priv, (byte*)kCurve25519BasePoint, rng); #endif return ret; } +#endif /* compute the public key from an existing private key, with supplied basepoint, * using bare vectors. @@ -170,6 +282,7 @@ int wc_curve25519_generic(int public_size, byte* pub, * nxp_ltc_curve25519_GetBasePoint() */ return WC_HW_E; #else +#ifndef WOLFSSL_CURVE25519_BLINDING int ret; if ((public_size != CURVE25519_KEYSIZE) || @@ -194,9 +307,64 @@ int wc_curve25519_generic(int public_size, byte* pub, RESTORE_VECTOR_REGISTERS(); return ret; +#else + WC_RNG rng; + int ret; + + ret = wc_InitRng(&rng); + if (ret == 0) { + ret = wc_curve25519_generic_blind(public_size, pub, private_size, priv, + basepoint_size, basepoint, &rng); + + wc_FreeRng(&rng); + } + + return ret; +#endif #endif /* FREESCALE_LTC_ECC */ } +#ifdef WOLFSSL_CURVE25519_BLINDING +/* compute the public key from an existing private key, with supplied basepoint, + * using bare vectors. + * + * return value is propagated from curve25519() (0 on success), + * and the byte vectors are little endian. + */ +int wc_curve25519_generic_blind(int public_size, byte* pub, + int private_size, const byte* priv, + int basepoint_size, const byte* basepoint, + WC_RNG* rng) +{ +#ifdef FREESCALE_LTC_ECC + /* unsupported with NXP LTC, only supports single basepoint with + * nxp_ltc_curve25519_GetBasePoint() */ + return WC_HW_E; +#else + int ret; + + if ((public_size != CURVE25519_KEYSIZE) || + (private_size != CURVE25519_KEYSIZE) || + (basepoint_size != CURVE25519_KEYSIZE)) { + return ECC_BAD_ARG_E; + } + if ((pub == NULL) || (priv == NULL) || (basepoint == NULL)) + return ECC_BAD_ARG_E; + + /* check clamping */ + ret = curve25519_priv_clamp_check(priv); + if (ret != 0) + return ret; + + fe_init(); + + ret = curve25519_smul_blind(pub, priv, basepoint, rng); + + return ret; +#endif /* FREESCALE_LTC_ECC */ +} +#endif + /* generate a new private key, as a bare vector. * * return value is propagated from wc_RNG_GenerateBlock(() (0 on success), @@ -250,8 +418,14 @@ int wc_curve25519_make_key(WC_RNG* rng, int keysize, curve25519_key* key) ret = wc_curve25519_make_priv(rng, keysize, key->k); if (ret == 0) { key->privSet = 1; +#ifdef WOLFSSL_CURVE25519_BLINDING + ret = wc_curve25519_make_pub_blind((int)sizeof(key->p.point), + key->p.point, (int)sizeof(key->k), + key->k, rng); +#else ret = wc_curve25519_make_pub((int)sizeof(key->p.point), key->p.point, (int)sizeof(key->k), key->k); +#endif key->pubSet = (ret == 0); } #endif @@ -320,11 +494,16 @@ int wc_curve25519_shared_secret_ex(curve25519_key* private_key, else #endif { +#ifndef WOLFSSL_CURVE25519_BLINDING SAVE_VECTOR_REGISTERS(return _svr_ret;); ret = curve25519(o.point, private_key->k, public_key->p.point); RESTORE_VECTOR_REGISTERS(); +#else + ret = curve25519_smul_blind(o.point, private_key->k, public_key->p.point, + private_key->rng); +#endif } #endif #ifdef WOLFSSL_ECDHX_SHARED_NOT_ZERO @@ -379,8 +558,14 @@ int wc_curve25519_export_public_ex(curve25519_key* key, byte* out, /* calculate public if missing */ if (!key->pubSet) { +#ifdef WOLFSSL_CURVE25519_BLINDING + ret = wc_curve25519_make_pub_blind((int)sizeof(key->p.point), + key->p.point, (int)sizeof(key->k), + key->k, key->rng); +#else ret = wc_curve25519_make_pub((int)sizeof(key->p.point), key->p.point, (int)sizeof(key->k), key->k); +#endif key->pubSet = (ret == 0); } /* export public point with endianness */ @@ -639,6 +824,9 @@ int wc_curve25519_import_private_ex(const byte* priv, word32 privSz, } #ifdef WOLFSSL_SE050 +#ifdef WOLFSSL_SE050_AUTO_ERASE + wc_se050_erase_object(key->keyId); +#endif /* release NXP resources if set */ se050_curve25519_free_key(key); #endif @@ -739,6 +927,16 @@ void wc_curve25519_free(curve25519_key* key) #endif } +#ifdef WOLFSSL_CURVE25519_BLINDING +int wc_curve25519_set_rng(curve25519_key* key, WC_RNG* rng) +{ + if (key == NULL) + return BAD_FUNC_ARG; + key->rng = rng; + return 0; +} +#endif + /* get key size */ int wc_curve25519_size(curve25519_key* key) { diff --git a/src/wolfcrypt/src/curve448.c b/src/wolfcrypt/src/curve448.c index 3cbf577..f3cf9f3 100644 --- a/src/wolfcrypt/src/curve448.c +++ b/src/wolfcrypt/src/curve448.c @@ -1,6 +1,6 @@ /* curve448.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -25,16 +25,11 @@ * Reworked for curve448 by Sean Parkinson. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef HAVE_CURVE448 #include -#include #ifdef NO_INLINE #include #else diff --git a/src/wolfcrypt/src/des3.c b/src/wolfcrypt/src/des3.c index d6c3923..7a9ba3b 100644 --- a/src/wolfcrypt/src/des3.c +++ b/src/wolfcrypt/src/des3.c @@ -1,6 +1,6 @@ /* des3.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,15 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include -#include -#include - +#include #ifndef NO_DES3 @@ -448,8 +440,6 @@ #elif defined(HAVE_COLDFIRE_SEC) - #include - #include "sec.h" #include "mcf5475_sec.h" #include "mcf5475_siu.h" diff --git a/src/wolfcrypt/src/dh.c b/src/wolfcrypt/src/dh.c index 5258e82..8869c03 100644 --- a/src/wolfcrypt/src/dh.c +++ b/src/wolfcrypt/src/dh.c @@ -1,6 +1,6 @@ /* dh.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifndef NO_DH @@ -41,8 +36,6 @@ #endif #include -#include -#include #ifdef WOLFSSL_HAVE_SP_DH #include @@ -2036,19 +2029,21 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, #ifndef WOLFSSL_SP_NO_2048 if (mp_count_bits(&key->p) == 2048) { if (mp_init(y) != MP_OKAY) - return MP_INIT_E; + ret = MP_INIT_E; - SAVE_VECTOR_REGISTERS(ret = _svr_ret;); + if (ret == 0) { + SAVE_VECTOR_REGISTERS(ret = _svr_ret;); - if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY) - ret = MP_READ_E; + if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY) + ret = MP_READ_E; - if (ret == 0) - ret = sp_DhExp_2048(y, priv, privSz, &key->p, agree, agreeSz); + if (ret == 0) + ret = sp_DhExp_2048(y, priv, privSz, &key->p, agree, agreeSz); - mp_clear(y); + mp_clear(y); - RESTORE_VECTOR_REGISTERS(); + RESTORE_VECTOR_REGISTERS(); + } /* make sure agree is > 1 (SP800-56A, 5.7.1.1) */ if ((ret == 0) && @@ -2070,19 +2065,21 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, #ifndef WOLFSSL_SP_NO_3072 if (mp_count_bits(&key->p) == 3072) { if (mp_init(y) != MP_OKAY) - return MP_INIT_E; + ret = MP_INIT_E; - SAVE_VECTOR_REGISTERS(ret = _svr_ret;); + if (ret == 0) { + SAVE_VECTOR_REGISTERS(ret = _svr_ret;); - if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY) - ret = MP_READ_E; + if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY) + ret = MP_READ_E; - if (ret == 0) - ret = sp_DhExp_3072(y, priv, privSz, &key->p, agree, agreeSz); + if (ret == 0) + ret = sp_DhExp_3072(y, priv, privSz, &key->p, agree, agreeSz); - mp_clear(y); + mp_clear(y); - RESTORE_VECTOR_REGISTERS(); + RESTORE_VECTOR_REGISTERS(); + } /* make sure agree is > 1 (SP800-56A, 5.7.1.1) */ if ((ret == 0) && @@ -2104,19 +2101,21 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, #ifdef WOLFSSL_SP_4096 if (mp_count_bits(&key->p) == 4096) { if (mp_init(y) != MP_OKAY) - return MP_INIT_E; + ret = MP_INIT_E; - SAVE_VECTOR_REGISTERS(ret = _svr_ret;); + if (ret == 0) { + SAVE_VECTOR_REGISTERS(ret = _svr_ret;); - if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY) - ret = MP_READ_E; + if (ret == 0 && mp_read_unsigned_bin(y, otherPub, pubSz) != MP_OKAY) + ret = MP_READ_E; - if (ret == 0) - ret = sp_DhExp_4096(y, priv, privSz, &key->p, agree, agreeSz); + if (ret == 0) + ret = sp_DhExp_4096(y, priv, privSz, &key->p, agree, agreeSz); - mp_clear(y); + mp_clear(y); - RESTORE_VECTOR_REGISTERS(); + RESTORE_VECTOR_REGISTERS(); + } /* make sure agree is > 1 (SP800-56A, 5.7.1.1) */ if ((ret == 0) && @@ -2544,10 +2543,56 @@ static int _DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, if (ret == 0 && !trusted) { int isPrime = 0; - if (rng != NULL) - ret = mp_prime_is_prime_ex(keyP, 8, &isPrime, rng); + + /* Short-circuit the primality check for p if it is one of the named + * public moduli (known primes) from RFC 7919. + */ + #ifdef HAVE_FFDHE_2048 + if ((pSz == sizeof(dh_ffdhe2048_p)) && + (XMEMCMP(p, dh_ffdhe2048_p, sizeof(dh_ffdhe2048_p)) == 0)) + { + isPrime = 1; + } + else + #endif + #ifdef HAVE_FFDHE_3072 + if ((pSz == sizeof(dh_ffdhe3072_p)) && + (XMEMCMP(p, dh_ffdhe3072_p, sizeof(dh_ffdhe3072_p)) == 0)) + { + isPrime = 1; + } + else + #endif + #ifdef HAVE_FFDHE_4096 + if ((pSz == sizeof(dh_ffdhe4096_p)) && + (XMEMCMP(p, dh_ffdhe4096_p, sizeof(dh_ffdhe4096_p)) == 0)) + { + isPrime = 1; + } + else + #endif + #ifdef HAVE_FFDHE_6144 + if ((pSz == sizeof(dh_ffdhe6144_p)) && + (XMEMCMP(p, dh_ffdhe6144_p, sizeof(dh_ffdhe6144_p)) == 0)) + { + isPrime = 1; + } else - ret = mp_prime_is_prime(keyP, 8, &isPrime); + #endif + #ifdef HAVE_FFDHE_8192 + if ((pSz == sizeof(dh_ffdhe8192_p)) && + (XMEMCMP(p, dh_ffdhe8192_p, sizeof(dh_ffdhe8192_p)) == 0)) + { + isPrime = 1; + } + else + #endif + { + if (rng != NULL) + ret = mp_prime_is_prime_ex(keyP, 8, &isPrime, rng); + else + ret = mp_prime_is_prime(keyP, 8, &isPrime); + } if (ret == 0 && isPrime == 0) ret = DH_CHECK_PUB_E; diff --git a/src/wolfcrypt/src/dilithium.c b/src/wolfcrypt/src/dilithium.c index 6391da4..1aa2750 100644 --- a/src/wolfcrypt/src/dilithium.c +++ b/src/wolfcrypt/src/dilithium.c @@ -1,6 +1,6 @@ /* dilithium.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -130,13 +130,7 @@ * shift equivalent. */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -/* in case user set HAVE_PQC there */ -#include +#include #ifndef WOLFSSL_DILITHIUM_NO_ASN1 #include @@ -151,7 +145,6 @@ #include #include #include -#include #ifdef NO_INLINE #include #else @@ -2195,7 +2188,7 @@ static int dilithium_rej_ntt_poly_ex(wc_Shake* shake128, byte* seed, sword32* a, static int dilithium_rej_ntt_poly(wc_Shake* shake128, byte* seed, sword32* a, void* heap) { - int ret; + int ret = 0; #if defined(WOLFSSL_SMALL_STACK) byte* h = NULL; #else @@ -2212,7 +2205,8 @@ static int dilithium_rej_ntt_poly(wc_Shake* shake128, byte* seed, sword32* a, } #endif - ret = dilithium_rej_ntt_poly_ex(shake128, seed, a, h); + if (ret == 0) + ret = dilithium_rej_ntt_poly_ex(shake128, seed, a, h); #if defined(WOLFSSL_SMALL_STACK) XFREE(h, heap, DYNAMIC_TYPE_DILITHIUM); @@ -6076,6 +6070,7 @@ static int dilithium_sign_with_seed_mu(dilithium_key* key, ret = MEMORY_E; } else { + XMEMSET(key->s1, 0, params->aSz); key->s2 = key->s1 + params->s1Sz / sizeof(*s1); key->t0 = key->s2 + params->s2Sz / sizeof(*s2); } @@ -7223,6 +7218,9 @@ static int dilithium_verify_mu(dilithium_key* key, const byte* mu, if (key->a == NULL) { ret = MEMORY_E; } + else { + XMEMSET(key->a, 0, params->aSz); + } } #endif if (ret == 0) { @@ -7237,6 +7235,9 @@ static int dilithium_verify_mu(dilithium_key* key, const byte* mu, if (key->t1 == NULL) { ret = MEMORY_E; } + else { + XMEMSET(key->t1, 0, params->s2Sz); + } } #endif if (ret == 0) { @@ -7259,6 +7260,7 @@ static int dilithium_verify_mu(dilithium_key* key, const byte* mu, ret = MEMORY_E; } else { + XMEMSET(z, 0, allocSz); c = z + params->s1Sz / sizeof(*z); w = c + DILITHIUM_N; #ifndef WC_DILITHIUM_CACHE_PUB_VECTORS @@ -7387,6 +7389,7 @@ static int dilithium_verify_mu(dilithium_key* key, const byte* mu, ret = MEMORY_E; } else { + XMEMSET(z, 0, allocSz); c = z + params->s1Sz / sizeof(*t1); w = c + DILITHIUM_N; t1 = w + DILITHIUM_N; @@ -8014,8 +8017,8 @@ int wc_dilithium_sign_ctx_msg(const byte* ctx, byte ctxLen, const byte* msg, if (key->devId != INVALID_DEVID) #endif { - ret = wc_CryptoCb_PqcSign(msg, msgLen, sig, sigLen, rng, - WC_PQC_SIG_TYPE_DILITHIUM, key); + ret = wc_CryptoCb_PqcSign(msg, msgLen, sig, sigLen, ctx, ctxLen, + WC_HASH_TYPE_NONE, rng, WC_PQC_SIG_TYPE_DILITHIUM, key); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) return ret; /* fall-through when unavailable */ @@ -8065,8 +8068,8 @@ int wc_dilithium_sign_msg(const byte* msg, word32 msgLen, byte* sig, if (key->devId != INVALID_DEVID) #endif { - ret = wc_CryptoCb_PqcSign(msg, msgLen, sig, sigLen, rng, - WC_PQC_SIG_TYPE_DILITHIUM, key); + ret = wc_CryptoCb_PqcSign(msg, msgLen, sig, sigLen, NULL, 0, + WC_HASH_TYPE_NONE, rng, WC_PQC_SIG_TYPE_DILITHIUM, key); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) return ret; /* fall-through when unavailable */ @@ -8117,6 +8120,22 @@ int wc_dilithium_sign_ctx_hash(const byte* ctx, byte ctxLen, int hashAlg, ret = BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + if (ret == 0) { + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_PqcSign(hash, hashLen, sig, sigLen, ctx, ctxLen, + hashAlg, rng, WC_PQC_SIG_TYPE_DILITHIUM, key); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when unavailable */ + ret = 0; + } + } +#endif + if (ret == 0) { /* Sign message. */ #ifdef WOLFSSL_WC_DILITHIUM @@ -8291,6 +8310,22 @@ int wc_dilithium_verify_ctx_msg(const byte* sig, word32 sigLen, const byte* ctx, ret = BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + if (ret == 0) { + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_PqcVerify(sig, sigLen, msg, msgLen, ctx, ctxLen, + WC_HASH_TYPE_NONE, res, WC_PQC_SIG_TYPE_DILITHIUM, key); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when unavailable */ + ret = 0; + } + } +#endif + if (ret == 0) { /* Verify message with signature. */ #ifdef WOLFSSL_WC_DILITHIUM @@ -8329,21 +8364,21 @@ int wc_dilithium_verify_msg(const byte* sig, word32 sigLen, const byte* msg, ret = BAD_FUNC_ARG; } - #ifdef WOLF_CRYPTO_CB +#ifdef WOLF_CRYPTO_CB if (ret == 0) { - #ifndef WOLF_CRYPTO_CB_FIND + #ifndef WOLF_CRYPTO_CB_FIND if (key->devId != INVALID_DEVID) - #endif + #endif { - ret = wc_CryptoCb_PqcVerify(sig, sigLen, msg, msgLen, res, - WC_PQC_SIG_TYPE_DILITHIUM, key); + ret = wc_CryptoCb_PqcVerify(sig, sigLen, msg, msgLen, NULL, 0, + WC_HASH_TYPE_NONE, res, WC_PQC_SIG_TYPE_DILITHIUM, key); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) return ret; /* fall-through when unavailable */ ret = 0; } } - #endif +#endif if (ret == 0) { /* Verify message with signature. */ @@ -8387,6 +8422,22 @@ int wc_dilithium_verify_ctx_hash(const byte* sig, word32 sigLen, ret = BAD_FUNC_ARG; } +#ifdef WOLF_CRYPTO_CB + if (ret == 0) { + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_PqcVerify(sig, sigLen, hash, hashLen, ctx, ctxLen, + hashAlg, res, WC_PQC_SIG_TYPE_DILITHIUM, key); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when unavailable */ + ret = 0; + } + } +#endif + if (ret == 0) { /* Verify message with signature. */ #ifdef WOLFSSL_WC_DILITHIUM @@ -8892,9 +8943,10 @@ int wc_dilithium_check_key(dilithium_key* key) */ if (ret == 0) { - params = key->params; unsigned int allocSz; + params = key->params; + /* s1-L, s2-K, t0-K, t-K, t1-K */ allocSz = params->s1Sz + 4 * params->s2Sz; #if !defined(WC_DILITHIUM_CACHE_MATRIX_A) @@ -8908,6 +8960,7 @@ int wc_dilithium_check_key(dilithium_key* key) ret = MEMORY_E; } else { + XMEMSET(s1, 0, allocSz); s2 = s1 + params->s1Sz / sizeof(*s1); t0 = s2 + params->s2Sz / sizeof(*s2); t = t0 + params->s2Sz / sizeof(*t0); @@ -9197,6 +9250,9 @@ int wc_dilithium_import_public(const byte* in, word32 inLen, dilithium_key* key) if (key->t1 == NULL) { ret = MEMORY_E; } + else { + XMEMSET(key->t1, 0, key->params->s2Sz); + } } #endif } @@ -9213,6 +9269,9 @@ int wc_dilithium_import_public(const byte* in, word32 inLen, dilithium_key* key) if (key->a == NULL) { ret = MEMORY_E; } + else { + XMEMSET(key->a, 0, key->params->aSz); + } } #endif } @@ -9282,6 +9341,9 @@ static int dilithium_set_priv_key(const byte* priv, word32 privSz, if (key->a == NULL) { ret = MEMORY_E; } + else { + XMEMSET(key->a, 0, params->aSz); + } } } #endif @@ -9303,6 +9365,9 @@ static int dilithium_set_priv_key(const byte* priv, word32 privSz, if (key->s1 == NULL) { ret = MEMORY_E; } + else { + XMEMSET(key->s1, 0, params->s1Sz + params->s2Sz + params->s2Sz); + } if (ret == 0) { /* Set pointers into allocated memory. */ key->s2 = key->s1 + params->s1Sz / sizeof(*key->s1); @@ -9524,6 +9589,42 @@ static int mapOidToSecLevel(word32 oid) } } +/* Get OID sum from dilithium key */ +int dilithium_get_oid_sum(dilithium_key* key, int* keyFormat) { + int ret = 0; + + #if defined(WOLFSSL_DILITHIUM_FIPS204_DRAFT) + if (key->params == NULL) { + ret = BAD_FUNC_ARG; + } + else if (key->params->level == WC_ML_DSA_44_DRAFT) { + *keyFormat = DILITHIUM_LEVEL2k; + } + else if (key->params->level == WC_ML_DSA_65_DRAFT) { + *keyFormat = DILITHIUM_LEVEL3k; + } + else if (key->params->level == WC_ML_DSA_87_DRAFT) { + *keyFormat = DILITHIUM_LEVEL5k; + } + else + #endif /* WOLFSSL_DILITHIUM_FIPS204_DRAFT */ + if (key->level == WC_ML_DSA_44) { + *keyFormat = ML_DSA_LEVEL2k; + } + else if (key->level == WC_ML_DSA_65) { + *keyFormat = ML_DSA_LEVEL3k; + } + else if (key->level == WC_ML_DSA_87) { + *keyFormat = ML_DSA_LEVEL5k; + } + else { + /* Level is not set */ + ret = ALGO_ID_E; + } + + return ret; +} + #if defined(WOLFSSL_DILITHIUM_PRIVATE_KEY) /* Decode the DER encoded Dilithium key. @@ -9563,8 +9664,13 @@ int wc_Dilithium_PrivateKeyDecode(const byte* input, word32* inOutIdx, if (ret == 0) { /* Get OID sum for level. */ + if (key->level == 0) { /* Check first, because key->params will be NULL + * when key->level = 0 */ + /* Level not set by caller, decode from DER */ + keytype = ANONk; + } #if defined(WOLFSSL_DILITHIUM_FIPS204_DRAFT) - if (key->params == NULL) { + else if (key->params == NULL) { ret = BAD_FUNC_ARG; } else if (key->params->level == WC_ML_DSA_44_DRAFT) { @@ -9576,9 +9682,8 @@ int wc_Dilithium_PrivateKeyDecode(const byte* input, word32* inOutIdx, else if (key->params->level == WC_ML_DSA_87_DRAFT) { keytype = DILITHIUM_LEVEL5k; } - else #endif - if (key->level == WC_ML_DSA_44) { + else if (key->level == WC_ML_DSA_44) { keytype = ML_DSA_LEVEL2k; } else if (key->level == WC_ML_DSA_65) { @@ -9588,8 +9693,7 @@ int wc_Dilithium_PrivateKeyDecode(const byte* input, word32* inOutIdx, keytype = ML_DSA_LEVEL5k; } else { - /* Level not set by caller, decode from DER */ - keytype = ANONk; /* 0, not a valid key type in this situation*/ + ret = BAD_FUNC_ARG; } } diff --git a/src/wolfcrypt/src/dsa.c b/src/wolfcrypt/src/dsa.c index 7fb7945..5be431a 100644 --- a/src/wolfcrypt/src/dsa.c +++ b/src/wolfcrypt/src/dsa.c @@ -1,6 +1,6 @@ /* dsa.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,19 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifndef NO_DSA #include #include -#include -#include #include #include diff --git a/src/wolfcrypt/src/ecc.c b/src/wolfcrypt/src/ecc.c index f010568..6d4cd4d 100644 --- a/src/wolfcrypt/src/ecc.c +++ b/src/wolfcrypt/src/ecc.c @@ -1,6 +1,6 @@ /* ecc.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,14 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -/* in case user set HAVE_ECC there */ -#include +#include #ifdef WOLFSSL_ECC_NO_SMALL_STACK #undef WOLFSSL_SMALL_STACK @@ -161,9 +154,6 @@ ECC Curve Sizes: #include #include -#include -#include -#include #ifdef WOLFSSL_HAVE_SP_ECC #include @@ -257,12 +247,12 @@ ECC Curve Sizes: /* macro guard for ecc_check_pubkey_order functionality */ -#if !defined(WOLFSSL_SP_MATH) && \ - !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ - !defined(WOLFSSL_SE050) && !defined(WOLFSSL_STM32_PKA) && \ - (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_IMXRT1170_CAAM) || \ - defined(WOLFSSL_QNX_CAAM)) +#if (!defined(NO_ECC_CHECK_PUBKEY_ORDER) && \ + !defined(WOLF_CRYPTO_CB_ONLY_ECC) && \ + !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ + !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ + !defined(WOLFSSL_SE050) && !defined(WOLFSSL_STM32_PKA)) || \ + defined(WOLFSSL_IMXRT1170_CAAM) || defined(WOLFSSL_QNX_CAAM) /* CAAM builds use public key validation as a means to check if an * imported private key is an encrypted black key or not */ @@ -1441,7 +1431,7 @@ size_t wc_ecc_get_sets_count(void) { #if defined(HAVE_COMP_KEY) && defined(HAVE_ECC_KEY_EXPORT) static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen); #endif -#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER +#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH) static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a, mp_int* prime, mp_int* order); #endif @@ -1576,7 +1566,7 @@ static int xil_mpi_import(mp_int *mpi, #endif #define DECLARE_CURVE_SPECS(intcount) ecc_curve_spec* curve = NULL - #define ALLOC_CURVE_SPECS(intcount, err) WC_DO_NOTHING + #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY #define FREE_CURVE_SPECS() WC_DO_NOTHING #elif defined(WOLFSSL_SMALL_STACK) #ifdef WOLFSSL_SP_MATH_ALL @@ -1588,13 +1578,17 @@ static int xil_mpi_import(mp_int *mpi, curve->spec_count = intcount #define ALLOC_CURVE_SPECS(intcount, err) \ + do { \ spec_ints = (unsigned char*)XMALLOC(MP_INT_SIZEOF(MP_BITS_CNT( \ MAX_ECC_BITS_USE)) * (intcount), NULL, \ DYNAMIC_TYPE_ECC); \ if (spec_ints == NULL) \ (err) = MEMORY_E; \ - else \ - curve->spec_ints = spec_ints + else { \ + curve->spec_ints = spec_ints; \ + (err) = MP_OKAY; \ + } \ + } while (0) #else #define DECLARE_CURVE_SPECS(intcount) \ mp_int* spec_ints = NULL; \ @@ -1604,12 +1598,16 @@ static int xil_mpi_import(mp_int *mpi, curve->spec_count = intcount #define ALLOC_CURVE_SPECS(intcount, err) \ + do { \ spec_ints = (mp_int*)XMALLOC(sizeof(mp_int) * (intcount), NULL, \ DYNAMIC_TYPE_ECC); \ if (spec_ints == NULL) \ (err) = MEMORY_E; \ - else \ - curve->spec_ints = spec_ints + else { \ + curve->spec_ints = spec_ints; \ + (err) = MP_OKAY; \ + } \ + } while (0) #endif #define FREE_CURVE_SPECS() \ XFREE(spec_ints, NULL, DYNAMIC_TYPE_ECC) @@ -1632,7 +1630,7 @@ static int xil_mpi_import(mp_int *mpi, curve->spec_ints = spec_ints; \ curve->spec_count = (intcount) #endif - #define ALLOC_CURVE_SPECS(intcount, err) WC_DO_NOTHING + #define ALLOC_CURVE_SPECS(intcount, err) (err) = MP_OKAY #define FREE_CURVE_SPECS() WC_DO_NOTHING #endif /* ECC_CACHE_CURVE */ @@ -6653,6 +6651,10 @@ static int wc_ecc_sign_hash_async(const byte* in, word32 inlen, byte* out, #if !defined(WOLFSSL_ASYNC_CRYPT_SW) && defined(HAVE_ECC_CDH) DECLARE_CURVE_SPECS(1); ALLOC_CURVE_SPECS(1, err); + if (err != MP_OKAY) { + WOLFSSL_MSG("ALLOC_CURVE_SPECS failed"); + break; + } /* get curve order */ err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ORDER); @@ -7508,7 +7510,7 @@ static int _HMAC_K(byte* K, word32 KSz, byte* V, word32 VSz, ret = init = wc_HmacInit(&hmac, heap, INVALID_DEVID); if (ret == 0) - ret = wc_HmacSetKey(&hmac, hashType, K, KSz); + ret = wc_HmacSetKey(&hmac, (int)hashType, K, KSz); if (ret == 0) ret = wc_HmacUpdate(&hmac, V, VSz); @@ -7938,6 +7940,9 @@ int wc_ecc_free(ecc_key* key) #endif #ifdef WOLFSSL_SE050 +#ifdef WOLFSSL_SE050_AUTO_ERASE + wc_se050_erase_object(key->keyId); +#endif se050_ecc_free_key(key); #endif @@ -9213,6 +9218,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, #elif defined(WOLFSSL_XILINX_CRYPT_VERSAL) byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2]; byte hashcopy[ECC_MAX_CRYPTO_HW_SIZE] = {0}; +#elif defined(WOLFSSL_SE050) #else int curveLoaded = 0; DECLARE_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); @@ -9380,7 +9386,6 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, #if !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC) if (!curveLoaded) { - err = 0; /* potential for NOT_COMPILED_IN error from SP attempt */ ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT, err); if (err != 0) { return err; @@ -9929,11 +9934,7 @@ int wc_ecc_export_x963_ex(ecc_key* key, byte* out, word32* outLen, #endif /* HAVE_ECC_KEY_EXPORT */ -#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ - !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050) && \ - !defined(WOLFSSL_STM32_PKA) && \ - (!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_QNX_CAAM) || \ - defined(WOLFSSL_IMXRT1170_CAAM)) +#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER /* is ecc point on curve described by dp ? */ static int _ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime) @@ -10134,6 +10135,10 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime) return BAD_FUNC_ARG; ALLOC_CURVE_SPECS(3, err); + if (err != MP_OKAY) { + WOLFSSL_MSG("ALLOC_CURVE_SPECS failed"); + return err; + } #ifdef WOLFSSL_NO_MALLOC res = &lcl_res; @@ -10275,7 +10280,6 @@ static int ecc_check_privkey_gen_helper(ecc_key* key) /* Hardware based private key, so this operation is not supported */ err = MP_OKAY; /* just report success */ #else - err = MP_OKAY; ALLOC_CURVE_SPECS(2, err); /* load curve info */ @@ -10367,9 +10371,10 @@ static int _ecc_pairwise_consistency_test(ecc_key* key, WC_RNG* rng) return err; } -#endif /* (FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN) &&!WOLFSSL_KCAPI_ECC */ +#endif /* (FIPS v5 or later || WOLFSSL_VALIDATE_ECC_KEYGEN) && \ + !WOLFSSL_KCAPI_ECC */ -#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER +#ifndef WOLFSSL_SP_MATH /* validate order * pubkey = point at infinity, 0 on success */ static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a, mp_int* prime, mp_int* order) @@ -10442,12 +10447,8 @@ static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a, return err; } #endif /* !WOLFSSL_SP_MATH */ +#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */ -#endif /* !WOLFSSL_ATECC508A && !WOLFSSL_ATECC608A && - !WOLFSSL_CRYPTOCELL && !WOLFSSL_SE050 && !WOLFSSL_STM32_PKA && - (!WOLF_CRYPTO_CB_ONLY_ECC || WOLFSSL_QNX_CAAM || - WOLFSSL_IMXRT1170_CAAM) - */ #ifdef OPENSSL_EXTRA int wc_ecc_get_generator(ecc_point* ecp, int curve_idx) @@ -10475,7 +10476,7 @@ int wc_ecc_get_generator(ecc_point* ecp, int curve_idx) return err; } -#endif /* OPENSSLALL */ +#endif /* OPENSSL_EXTRA */ /* Validate the public key per SP 800-56Ar3 section 5.6.2.3.3, @@ -10487,7 +10488,7 @@ int wc_ecc_get_generator(ecc_point* ecp, int curve_idx) static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) { int err = MP_OKAY; -#ifdef HAVE_ECC_CHECK_PUBKEY_ORDER +#if defined(HAVE_ECC_CHECK_PUBKEY_ORDER) && !defined(WOLFSSL_SP_MATH) mp_int* b = NULL; #ifdef USE_ECC_B_PARAM DECLARE_CURVE_SPECS(4); @@ -10497,13 +10498,23 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) #endif DECLARE_CURVE_SPECS(3); #endif /* USE_ECC_B_PARAM */ -#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */ +#endif ASSERT_SAVED_VECTOR_REGISTERS(); if (key == NULL) return BAD_FUNC_ARG; +#ifndef HAVE_ECC_CHECK_PUBKEY_ORDER + /* consider key check success on HW crypto + * ex: ATECC508/608A, CryptoCell and Silabs + * + * consider key check success on most Crypt Cb only builds + */ + err = MP_OKAY; + +#else + #ifdef WOLFSSL_HAVE_SP_ECC #ifndef WOLFSSL_SP_NO_256 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { @@ -10538,15 +10549,6 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) #endif #ifndef WOLFSSL_SP_MATH -#ifndef HAVE_ECC_CHECK_PUBKEY_ORDER - /* consider key check success on HW crypto - * ex: ATECC508/608A, CryptoCell and Silabs - * - * consider key check success on most Crypt Cb only builds - */ - err = MP_OKAY; - -#else #ifdef USE_ECC_B_PARAM ALLOC_CURVE_SPECS(4, err); #else @@ -10670,11 +10672,13 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv) #endif FREE_CURVE_SPECS(); -#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */ #else + /* The single precision math curve is not available */ err = WC_KEY_SIZE_E; #endif /* !WOLFSSL_SP_MATH */ +#endif /* HAVE_ECC_CHECK_PUBKEY_ORDER */ + (void)partial; (void)priv; return err; @@ -11352,7 +11356,7 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, #endif #ifdef WOLFSSL_MAXQ10XX_CRYPTO - if (ret == 0) { + if ((ret == 0) && (key->devId != INVALID_DEVID)) { ret = wc_MAXQ10XX_EccSetKey(key, key->dp->size); } #elif defined(WOLFSSL_SILABS_SE_ACCEL) diff --git a/src/wolfcrypt/src/eccsi.c b/src/wolfcrypt/src/eccsi.c index 79b7a65..537e64c 100644 --- a/src/wolfcrypt/src/eccsi.c +++ b/src/wolfcrypt/src/eccsi.c @@ -1,6 +1,6 @@ /* eccsi.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,13 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef NO_INLINE #include @@ -36,7 +30,6 @@ #ifdef WOLFCRYPT_HAVE_ECCSI -#include #include #include #ifdef WOLFSSL_HAVE_SP_ECC diff --git a/src/wolfcrypt/src/ed25519.c b/src/wolfcrypt/src/ed25519.c index fd80f86..85f7f8a 100644 --- a/src/wolfcrypt/src/ed25519.c +++ b/src/wolfcrypt/src/ed25519.c @@ -1,6 +1,6 @@ /* ed25519.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -28,12 +28,7 @@ * Check that the private key didn't change during the signing operations. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -/* in case user set HAVE_ED25519 there */ -#include +#include #ifdef HAVE_ED25519 #if FIPS_VERSION3_GE(6,0,0) @@ -48,8 +43,6 @@ #include #include -#include -#include #include #ifdef NO_INLINE #include @@ -1104,6 +1097,9 @@ void wc_ed25519_free(ed25519_key* key) #endif #ifdef WOLFSSL_SE050 +#ifdef WOLFSSL_SE050_AUTO_ERASE + wc_se050_erase_object(key->keyId); +#endif se050_ed25519_free_key(key); #endif diff --git a/src/wolfcrypt/src/ed448.c b/src/wolfcrypt/src/ed448.c index 1598c9c..a5e63a1 100644 --- a/src/wolfcrypt/src/ed448.c +++ b/src/wolfcrypt/src/ed448.c @@ -1,6 +1,6 @@ /* ed448.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -30,12 +30,7 @@ * Check that the private key didn't change during the signing operations. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -/* in case user set HAVE_ED448 there */ -#include +#include #ifdef HAVE_ED448 #if FIPS_VERSION3_GE(6,0,0) @@ -49,7 +44,6 @@ #endif #include -#include #include #ifdef NO_INLINE #include diff --git a/src/wolfcrypt/src/error.c b/src/wolfcrypt/src/error.c index 0deb668..af5ba36 100644 --- a/src/wolfcrypt/src/error.c +++ b/src/wolfcrypt/src/error.c @@ -1,6 +1,6 @@ /* error.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,14 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#include +#include #ifdef _MSC_VER /* 4996 warning to use MS extensions e.g., strcpy_s instead of XSTRNCPY */ @@ -645,9 +638,15 @@ const char* wc_GetErrorString(int error) case PBKDF2_KAT_FIPS_E: return "wolfCrypt FIPS PBKDF2 Known Answer Test Failure"; + case WC_KEY_MISMATCH_E: + return "key values mismatch"; + case DEADLOCK_AVERTED_E: return "Deadlock averted -- retry the call"; + case ASCON_AUTH_E: + return "ASCON Authentication check fail"; + case MAX_CODE_E: case WC_SPAN1_MIN_CODE_E: case MIN_CODE_E: diff --git a/src/wolfcrypt/src/evp.c b/src/wolfcrypt/src/evp.c index c3eb12e..7054f80 100644 --- a/src/wolfcrypt/src/evp.c +++ b/src/wolfcrypt/src/evp.c @@ -1,6 +1,6 @@ /* evp.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if !defined(WOLFSSL_EVP_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN @@ -52,67 +47,67 @@ static const struct s_ent { const char *name; } md_tbl[] = { #ifndef NO_MD4 - {WC_HASH_TYPE_MD4, WC_NID_md4, "MD4"}, + {WC_HASH_TYPE_MD4, WC_NID_md4, WC_SN_md4}, #endif /* NO_MD4 */ #ifndef NO_MD5 - {WC_HASH_TYPE_MD5, WC_NID_md5, "MD5"}, + {WC_HASH_TYPE_MD5, WC_NID_md5, WC_SN_md5}, #endif /* NO_MD5 */ #ifndef NO_SHA - {WC_HASH_TYPE_SHA, WC_NID_sha1, "SHA1"}, + {WC_HASH_TYPE_SHA, WC_NID_sha1, WC_SN_sha1}, {WC_HASH_TYPE_SHA, WC_NID_sha1, "SHA"}, /* Leave for backwards compatibility */ #endif /* NO_SHA */ #ifdef WOLFSSL_SHA224 - {WC_HASH_TYPE_SHA224, WC_NID_sha224, "SHA224"}, + {WC_HASH_TYPE_SHA224, WC_NID_sha224, WC_SN_sha224}, #endif /* WOLFSSL_SHA224 */ #ifndef NO_SHA256 - {WC_HASH_TYPE_SHA256, WC_NID_sha256, "SHA256"}, + {WC_HASH_TYPE_SHA256, WC_NID_sha256, WC_SN_sha256}, #endif #ifdef WOLFSSL_SHA384 - {WC_HASH_TYPE_SHA384, WC_NID_sha384, "SHA384"}, + {WC_HASH_TYPE_SHA384, WC_NID_sha384, WC_SN_sha384}, #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA512 - {WC_HASH_TYPE_SHA512, WC_NID_sha512, "SHA512"}, + {WC_HASH_TYPE_SHA512, WC_NID_sha512, WC_SN_sha512}, #endif /* WOLFSSL_SHA512 */ #if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224) - {WC_HASH_TYPE_SHA512_224, WC_NID_sha512_224, "SHA512_224"}, + {WC_HASH_TYPE_SHA512_224, WC_NID_sha512_224, WC_SN_sha512_224}, #endif /* WOLFSSL_SHA512 && !WOLFSSL_NOSHA512_224 */ #if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256) - {WC_HASH_TYPE_SHA512_256, WC_NID_sha512_256, "SHA512_256"}, + {WC_HASH_TYPE_SHA512_256, WC_NID_sha512_256, WC_SN_sha512_256}, #endif /* WOLFSSL_SHA512 && !WOLFSSL_NOSHA512_256 */ #ifndef WOLFSSL_NOSHA3_224 - {WC_HASH_TYPE_SHA3_224, WC_NID_sha3_224, "SHA3_224"}, + {WC_HASH_TYPE_SHA3_224, WC_NID_sha3_224, WC_SN_sha3_224}, #endif #ifndef WOLFSSL_NOSHA3_256 - {WC_HASH_TYPE_SHA3_256, WC_NID_sha3_256, "SHA3_256"}, + {WC_HASH_TYPE_SHA3_256, WC_NID_sha3_256, WC_SN_sha3_256}, #endif #ifndef WOLFSSL_NOSHA3_384 - {WC_HASH_TYPE_SHA3_384, WC_NID_sha3_384, "SHA3_384"}, + {WC_HASH_TYPE_SHA3_384, WC_NID_sha3_384, WC_SN_sha3_384}, #endif #ifndef WOLFSSL_NOSHA3_512 - {WC_HASH_TYPE_SHA3_512, WC_NID_sha3_512, "SHA3_512"}, + {WC_HASH_TYPE_SHA3_512, WC_NID_sha3_512, WC_SN_sha3_512}, #endif #ifdef WOLFSSL_SM3 - {WC_HASH_TYPE_SM3, WC_NID_sm3, "SM3"}, + {WC_HASH_TYPE_SM3, WC_NID_sm3, WC_SN_sm3}, #endif /* WOLFSSL_SHA512 */ #ifdef HAVE_BLAKE2 - {WC_HASH_TYPE_BLAKE2B, WC_NID_blake2b512, "BLAKE2B512"}, + {WC_HASH_TYPE_BLAKE2B, WC_NID_blake2b512, WC_SN_blake2b512}, #endif #ifdef HAVE_BLAKE2S - {WC_HASH_TYPE_BLAKE2S, WC_NID_blake2s256, "BLAKE2S256"}, + {WC_HASH_TYPE_BLAKE2S, WC_NID_blake2s256, WC_SN_blake2s256}, #endif #ifdef WOLFSSL_SHAKE128 - {WC_HASH_TYPE_SHAKE128, WC_NID_shake128, "SHAKE128"}, + {WC_HASH_TYPE_SHAKE128, WC_NID_shake128, WC_SN_shake128}, #endif #ifdef WOLFSSL_SHAKE256 - {WC_HASH_TYPE_SHAKE256, WC_NID_shake256, "SHAKE256"}, + {WC_HASH_TYPE_SHAKE256, WC_NID_shake256, WC_SN_shake256}, #endif {WC_HASH_TYPE_NONE, 0, NULL} }; @@ -1059,6 +1054,14 @@ int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, } switch (ctx->cipherType) { + case WC_NULL_CIPHER_TYPE: + if (out == NULL) { + WOLFSSL_MSG("Bad argument"); + return WOLFSSL_FAILURE; + } + XMEMMOVE(out, in, inl); + *outl = inl; + return WOLFSSL_SUCCESS; #if !defined(NO_AES) && defined(HAVE_AESGCM) case WC_AES_128_GCM_TYPE: case WC_AES_192_GCM_TYPE: @@ -2046,6 +2049,165 @@ static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher) else return 0; } +/* Getter function for cipher type string + * + * cipherType cipherType enum value to get string for + * + * Returns string representation of the cipher type or NULL if not found + */ +const char* wolfSSL_EVP_CIPHER_type_string(unsigned int cipherType) +{ + WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_type_string"); + + switch (cipherType) { +#ifndef NO_DES3 + case WC_DES_CBC_TYPE: return EVP_DES_CBC; + case WC_DES_EDE3_CBC_TYPE: return EVP_DES_EDE3_CBC; + case WC_DES_ECB_TYPE: return EVP_DES_ECB; + case WC_DES_EDE3_ECB_TYPE: return EVP_DES_EDE3_ECB; +#endif +#if !defined(NO_AES) + #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_CBC_TYPE: return EVP_AES_128_CBC; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_CBC_TYPE: return EVP_AES_192_CBC; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_CBC_TYPE: return EVP_AES_256_CBC; + #endif + #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */ + #if defined(WOLFSSL_AES_CFB) + #ifndef WOLFSSL_NO_AES_CFB_1_8 + #ifdef WOLFSSL_AES_128 + case WC_AES_128_CFB1_TYPE: return EVP_AES_128_CFB1; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_CFB1_TYPE: return EVP_AES_192_CFB1; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_CFB1_TYPE: return EVP_AES_256_CFB1; + #endif + #ifdef WOLFSSL_AES_128 + case WC_AES_128_CFB8_TYPE: return EVP_AES_128_CFB8; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_CFB8_TYPE: return EVP_AES_192_CFB8; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_CFB8_TYPE: return EVP_AES_256_CFB8; + #endif + #endif /* !WOLFSSL_NO_AES_CFB_1_8 */ + #ifdef WOLFSSL_AES_128 + case WC_AES_128_CFB128_TYPE: return EVP_AES_128_CFB128; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_CFB128_TYPE: return EVP_AES_192_CFB128; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_CFB128_TYPE: return EVP_AES_256_CFB128; + #endif + #endif /* WOLFSSL_AES_CFB */ + #if defined(WOLFSSL_AES_OFB) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_OFB_TYPE: return EVP_AES_128_OFB; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_OFB_TYPE: return EVP_AES_192_OFB; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_OFB_TYPE: return EVP_AES_256_OFB; + #endif + #endif /* WOLFSSL_AES_OFB */ + #if defined(WOLFSSL_AES_XTS) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_XTS_TYPE: return EVP_AES_128_XTS; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_XTS_TYPE: return EVP_AES_256_XTS; + #endif + #endif /* WOLFSSL_AES_XTS && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) */ + #if defined(HAVE_AESGCM) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_GCM_TYPE: return EVP_AES_128_GCM; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_GCM_TYPE: return EVP_AES_192_GCM; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_GCM_TYPE: return EVP_AES_256_GCM; + #endif + #endif /* HAVE_AESGCM */ + #if defined(HAVE_AESCCM) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_CCM_TYPE: return EVP_AES_128_CCM; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_CCM_TYPE: return EVP_AES_192_CCM; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_CCM_TYPE: return EVP_AES_256_CCM; + #endif + #endif /* HAVE_AESCCM */ + #if defined(WOLFSSL_AES_COUNTER) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_CTR_TYPE: return EVP_AES_128_CTR; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_CTR_TYPE: return EVP_AES_192_CTR; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_CTR_TYPE: return EVP_AES_256_CTR; + #endif + #endif /* WOLFSSL_AES_COUNTER */ + #if defined(HAVE_AES_ECB) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_ECB_TYPE: return EVP_AES_128_ECB; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_ECB_TYPE: return EVP_AES_192_ECB; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_ECB_TYPE: return EVP_AES_256_ECB; + #endif + #endif /* HAVE_AES_ECB */ +#endif /* !NO_AES */ +#if defined(HAVE_ARIA) + case WC_ARIA_128_GCM_TYPE: return EVP_ARIA_128_GCM; + case WC_ARIA_192_GCM_TYPE: return EVP_ARIA_192_GCM; + case WC_ARIA_256_GCM_TYPE: return EVP_ARIA_256_GCM; +#endif /* HAVE_ARIA */ +#ifndef NO_RC4 + case WC_ARC4_TYPE: return EVP_ARC4; +#endif +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + case WC_CHACHA20_POLY1305_TYPE: return EVP_CHACHA20_POLY1305; +#endif +#ifdef HAVE_CHACHA + case WC_CHACHA20_TYPE: return EVP_CHACHA20; +#endif +#ifdef WOLFSSL_SM4_ECB + case WC_SM4_ECB_TYPE: return EVP_SM4_ECB; +#endif +#ifdef WOLFSSL_SM4_CBC + case WC_SM4_CBC_TYPE: return EVP_SM4_CBC; +#endif +#ifdef WOLFSSL_SM4_CTR + case WC_SM4_CTR_TYPE: return EVP_SM4_CTR; +#endif +#ifdef WOLFSSL_SM4_GCM + case WC_SM4_GCM_TYPE: return EVP_SM4_GCM; +#endif +#ifdef WOLFSSL_SM4_CCM + case WC_SM4_CCM_TYPE: return EVP_SM4_CCM; +#endif + case WC_NULL_CIPHER_TYPE: return EVP_NULL; + default: + return NULL; + } +} + int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher) { if (cipher == NULL) @@ -2633,7 +2795,7 @@ int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_ return WOLFSSL_FAILURE; } if (ctx->pkey->hkdfMode == WOLFSSL_EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND) { - if (wc_HKDF(hkdfHashType, ctx->pkey->hkdfKey, ctx->pkey->hkdfKeySz, + if (wc_HKDF((int)hkdfHashType, ctx->pkey->hkdfKey, ctx->pkey->hkdfKeySz, ctx->pkey->hkdfSalt, ctx->pkey->hkdfSaltSz, ctx->pkey->hkdfInfo, ctx->pkey->hkdfInfoSz, key, (word32)*keylen) != 0) { @@ -2642,7 +2804,7 @@ int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_ } } else if (ctx->pkey->hkdfMode == WOLFSSL_EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) { - if (wc_HKDF_Extract(hkdfHashType, ctx->pkey->hkdfSalt, + if (wc_HKDF_Extract((int)hkdfHashType, ctx->pkey->hkdfSalt, ctx->pkey->hkdfSaltSz, ctx->pkey->hkdfKey, ctx->pkey->hkdfKeySz, key) != 0) { WOLFSSL_MSG("wc_HKDF_Extract failed."); @@ -2659,7 +2821,7 @@ int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_ } } else if (ctx->pkey->hkdfMode == WOLFSSL_EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) { - if (wc_HKDF_Expand(hkdfHashType, ctx->pkey->hkdfKey, + if (wc_HKDF_Expand((int)hkdfHashType, ctx->pkey->hkdfKey, ctx->pkey->hkdfKeySz, ctx->pkey->hkdfInfo, ctx->pkey->hkdfInfoSz, key, (word32)*keylen) != 0) { @@ -3316,14 +3478,44 @@ int wolfSSL_EVP_PKEY_verify(WOLFSSL_EVP_PKEY_CTX *ctx, const unsigned char *sig, */ int wolfSSL_EVP_PKEY_bits(const WOLFSSL_EVP_PKEY *pkey) { - int bytes; + int ret = 0; - if (pkey == NULL) return 0; - WOLFSSL_ENTER("wolfSSL_EVP_PKEY_bits"); - if ((bytes = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey)) ==0) return 0; - if (bytes < 0) + if (pkey == NULL) return 0; - return bytes*8; + + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_bits"); + + switch (pkey->type) { +#ifndef NO_RSA + case WC_EVP_PKEY_RSA: + ret = (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(pkey->rsa)); + break; +#endif /* !NO_RSA */ + +#ifndef NO_DSA + case WC_EVP_PKEY_DSA: + if (pkey->dsa == NULL || + (!pkey->dsa->exSet && + SetDsaExternal(pkey->dsa) != WOLFSSL_SUCCESS)) + break; + ret = wolfSSL_BN_num_bytes(pkey->dsa->p); + break; +#endif + +#ifdef HAVE_ECC + case WC_EVP_PKEY_EC: + if (pkey->ecc == NULL || pkey->ecc->internal == NULL) { + WOLFSSL_MSG("No ECC key has been set"); + break; + } + ret = wc_ecc_size((ecc_key*)(pkey->ecc->internal)); + break; +#endif /* HAVE_ECC */ + + default: + break; + } + return ret > 0 ? ret * 8 : 0; } @@ -3530,12 +3722,11 @@ int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx, return ret; } -/* Get the size in bytes for WOLFSSL_EVP_PKEY key +/* Get the maximum suitable size for the operations that can be done with pkey * * pkey WOLFSSL_EVP_PKEY structure to get key size of * - * returns the size of a key on success which is the maximum size of a - * signature + * returns the recommended size of buffers */ int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey) { @@ -3563,7 +3754,7 @@ int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey) WOLFSSL_MSG("No ECC key has been set"); break; } - return wc_ecc_size((ecc_key*)(pkey->ecc->internal)); + return wc_ecc_sig_size((ecc_key*)(pkey->ecc->internal)); #endif /* HAVE_ECC */ default: @@ -3732,7 +3923,6 @@ int wolfSSL_EVP_PKEY_missing_parameters(WOLFSSL_EVP_PKEY *pkey) int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b) { int ret = -1; /* failure */ - int a_sz = 0, b_sz = 0; if (a == NULL || b == NULL) return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); @@ -3745,40 +3935,47 @@ int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b) switch (a->type) { #ifndef NO_RSA case WC_EVP_PKEY_RSA: - a_sz = (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(a->rsa)); - b_sz = (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(b->rsa)); + if (wolfSSL_RSA_size((const WOLFSSL_RSA*)(a->rsa)) <= 0 || + wolfSSL_RSA_size((const WOLFSSL_RSA*)(b->rsa)) <= 0) { + return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); + } + + if (mp_cmp(&((RsaKey*)a->rsa->internal)->n, + &((RsaKey*)b->rsa->internal)->n) != MP_EQ) { + return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); + } + + if (mp_cmp(&((RsaKey*)a->rsa->internal)->e, + &((RsaKey*)b->rsa->internal)->e) != MP_EQ) { + return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); + } break; #endif /* !NO_RSA */ #ifdef HAVE_ECC case WC_EVP_PKEY_EC: if (a->ecc == NULL || a->ecc->internal == NULL || - b->ecc == NULL || b->ecc->internal == NULL) { + b->ecc == NULL || b->ecc->internal == NULL || + wc_ecc_size((ecc_key*)a->ecc->internal) <= 0 || + wc_ecc_size((ecc_key*)b->ecc->internal) <= 0 || + a->ecc->group == NULL || b->ecc->group == NULL) { return ret; } - a_sz = wc_ecc_size((ecc_key*)(a->ecc->internal)); - b_sz = wc_ecc_size((ecc_key*)(b->ecc->internal)); + + /* check curve */ + if (a->ecc->group->curve_idx != b->ecc->group->curve_idx) { + return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); + } + + if (wc_ecc_cmp_point(&((ecc_key*)a->ecc->internal)->pubkey, + &((ecc_key*)b->ecc->internal)->pubkey) != 0) { + return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); + } break; #endif /* HAVE_ECC */ default: return WS_RETURN_CODE(ret, -2); } /* switch (a->type) */ - /* check size */ - if (a_sz <= 0 || b_sz <= 0 || a_sz != b_sz) { - return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); - } - - /* check public key size */ - if (a->pkey_sz > 0 && b->pkey_sz > 0 && a->pkey_sz != b->pkey_sz) { - return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); - } - - /* check public key */ - if (a->pkey.ptr && b->pkey.ptr) { - if (XMEMCMP(a->pkey.ptr, b->pkey.ptr, (size_t)a->pkey_sz) != 0) { - return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); - } - } #if defined(WOLFSSL_ERROR_CODE_OPENSSL) ret = 1; /* the keys match */ #else @@ -3795,18 +3992,11 @@ int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b) static int DH_param_check(WOLFSSL_DH* dh_key) { int ret = WOLFSSL_SUCCESS; - WOLFSSL_BN_CTX* ctx = NULL; WOLFSSL_BIGNUM *num1 = NULL; WOLFSSL_BIGNUM *num2 = NULL; WOLFSSL_ENTER("DH_param_check"); - ctx = wolfSSL_BN_CTX_new(); - if (ctx == NULL) { - WOLFSSL_MSG("failed to allocate memory"); - return WOLFSSL_FAILURE; - } - num1 = wolfSSL_BN_new(); num2 = wolfSSL_BN_new(); if (num1 == NULL || num2 == NULL) { @@ -3840,7 +4030,7 @@ static int DH_param_check(WOLFSSL_DH* dh_key) dh_key->q != NULL) { if (ret == WOLFSSL_SUCCESS && - wolfSSL_BN_mod_exp(num1, dh_key->g, dh_key->q, dh_key->p, ctx) + wolfSSL_BN_mod_exp(num1, dh_key->g, dh_key->q, dh_key->p, NULL) == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) { WOLFSSL_MSG("BN_mod_exp failed"); @@ -3855,7 +4045,7 @@ static int DH_param_check(WOLFSSL_DH* dh_key) #if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) /* test if the number q is prime. */ if (ret == WOLFSSL_SUCCESS && - (wolfSSL_BN_is_prime_ex(dh_key->q, 64, ctx, NULL) <= 0)) { + (wolfSSL_BN_is_prime_ex(dh_key->q, 64, NULL, NULL) <= 0)) { WOLFSSL_MSG("dh_key->q is not prime or error during check."); ret = WOLFSSL_FAILURE; } /* else TODO check q div q - 1. need BN_div */ @@ -3863,7 +4053,6 @@ static int DH_param_check(WOLFSSL_DH* dh_key) } /* clean up */ - wolfSSL_BN_CTX_free(ctx); wolfSSL_BN_free(num1); wolfSSL_BN_free(num2); @@ -4043,9 +4232,13 @@ int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret, pkey->ecc); if (ecdsaSig == NULL) return WOLFSSL_FAILURE; + /* get signature length only */ ret = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, NULL); - if (ret <= 0 || ret > (int)*siglen) + if (ret <= 0 || ret > (int)*siglen) { + wolfSSL_ECDSA_SIG_free(ecdsaSig); return WOLFSSL_FAILURE; + } + /* perform validation of signature */ ret = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sigret); wolfSSL_ECDSA_SIG_free(ecdsaSig); if (ret <= 0 || ret > (int)*siglen) @@ -4262,69 +4455,69 @@ static int wolfssl_evp_md_to_hash_type(const WOLFSSL_EVP_MD *type, int ret = 0; #ifndef NO_SHA256 - if (XSTRCMP(type, "SHA256") == 0) { + if (XSTRCMP(type, WC_SN_sha256) == 0) { *hashType = WC_SHA256; } else #endif #ifndef NO_SHA - if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, "SHA1") == 0)) { + if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, WC_SN_sha1) == 0)) { *hashType = WC_SHA; } else #endif /* NO_SHA */ #ifdef WOLFSSL_SHA224 - if (XSTRCMP(type, "SHA224") == 0) { + if (XSTRCMP(type, WC_SN_sha224) == 0) { *hashType = WC_SHA224; } else #endif #ifdef WOLFSSL_SHA384 - if (XSTRCMP(type, "SHA384") == 0) { + if (XSTRCMP(type, WC_SN_sha384) == 0) { *hashType = WC_SHA384; } else #endif #ifdef WOLFSSL_SHA512 - if (XSTRCMP(type, "SHA512") == 0) { + if (XSTRCMP(type, WC_SN_sha512) == 0) { *hashType = WC_SHA512; } else #endif #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 - if (XSTRCMP(type, "SHA3_224") == 0) { + if (XSTRCMP(type, WC_SN_sha3_224) == 0) { *hashType = WC_SHA3_224; } else #endif #ifndef WOLFSSL_NOSHA3_256 - if (XSTRCMP(type, "SHA3_256") == 0) { + if (XSTRCMP(type, WC_SN_sha3_256) == 0) { *hashType = WC_SHA3_256; } else #endif #ifndef WOLFSSL_NOSHA3_384 - if (XSTRCMP(type, "SHA3_384") == 0) { + if (XSTRCMP(type, WC_SN_sha3_384) == 0) { *hashType = WC_SHA3_384; } else #endif #ifndef WOLFSSL_NOSHA3_512 - if (XSTRCMP(type, "SHA3_512") == 0) { + if (XSTRCMP(type, WC_SN_sha3_512) == 0) { *hashType = WC_SHA3_512; } else #endif #endif #ifdef WOLFSSL_SM3 - if (XSTRCMP(type, "SM3") == 0) { + if (XSTRCMP(type, WC_SN_sm3) == 0) { *hashType = WC_SM3; } else #endif #ifndef NO_MD5 - if (XSTRCMP(type, "MD5") == 0) { + if (XSTRCMP(type, WC_SN_md5) == 0) { *hashType = WC_MD5; } else @@ -4644,7 +4837,9 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, ctx->pctx->pkey->ecc); if (ecdsaSig == NULL) break; - len = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig); + len = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, NULL); + if (len > 0 && (size_t)len <= *siglen) + len = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig); wolfSSL_ECDSA_SIG_free(ecdsaSig); if (len == 0) break; @@ -4867,6 +5062,7 @@ int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen, { const char *nostring = ""; int ret = 0; + enum wc_HashType pbkdf2HashType; if (pass == NULL) { passlen = 0; @@ -4875,8 +5071,10 @@ int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen, passlen = (int)XSTRLEN(pass); } + pbkdf2HashType = EvpMd2MacType(digest); + ret = wc_PBKDF2((byte*)out, (byte*)pass, passlen, (byte*)salt, saltlen, - iter, keylen, EvpMd2MacType(digest)); + iter, keylen, pbkdf2HashType); if (ret == 0) return WOLFSSL_SUCCESS; else @@ -6299,14 +6497,16 @@ void wolfSSL_EVP_init(void) case WC_AES_256_OFB_TYPE: #endif wc_AesFree(&ctx->cipher.aes); - ctx->flags &= ~WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + ctx->flags &= + (unsigned long)~WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; break; #if defined(WOLFSSL_AES_XTS) && \ (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) case WC_AES_128_XTS_TYPE: case WC_AES_256_XTS_TYPE: wc_AesXtsFree(&ctx->cipher.xts); - ctx->flags &= ~WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + ctx->flags &= + (unsigned long)~WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; break; #endif #endif /* AES */ @@ -6875,7 +7075,7 @@ void wolfSSL_EVP_init(void) ret = wc_AriaInitCrypt(&ctx->cipher.aria, MC_ALGID_ARIA_256BITKEY); break; default: - WOLFSSL_MSG("Not implemented cipherType"); + WOLFSSL_MSG("Unimplemented cipherType"); return WOLFSSL_NOT_IMPLEMENTED; /* This should never happen */ } if (ret != 0) { @@ -8258,9 +8458,9 @@ void wolfSSL_EVP_init(void) } #endif /* !NO_AES || !NO_DES3 */ - static int IsCipherTypeAEAD(unsigned char cipherType) + static int IsCipherTypeAEAD(unsigned int type) { - switch (cipherType) { + switch (type) { case WC_AES_128_GCM_TYPE: case WC_AES_192_GCM_TYPE: case WC_AES_256_GCM_TYPE: @@ -9367,22 +9567,22 @@ int wolfSSL_EVP_MD_pkey_type(const WOLFSSL_EVP_MD* type) WOLFSSL_ENTER("wolfSSL_EVP_MD_pkey_type"); if (type != NULL) { - if (XSTRCMP(type, "MD5") == 0) { + if (XSTRCMP(type, WC_SN_md5) == 0) { ret = WC_NID_md5WithRSAEncryption; } - else if (XSTRCMP(type, "SHA1") == 0) { + else if (XSTRCMP(type, WC_SN_sha1) == 0) { ret = WC_NID_sha1WithRSAEncryption; } - else if (XSTRCMP(type, "SHA224") == 0) { + else if (XSTRCMP(type, WC_SN_sha224) == 0) { ret = WC_NID_sha224WithRSAEncryption; } - else if (XSTRCMP(type, "SHA256") == 0) { + else if (XSTRCMP(type, WC_SN_sha256) == 0) { ret = WC_NID_sha256WithRSAEncryption; } - else if (XSTRCMP(type, "SHA384") == 0) { + else if (XSTRCMP(type, WC_SN_sha384) == 0) { ret = WC_NID_sha384WithRSAEncryption; } - else if (XSTRCMP(type, "SHA512") == 0) { + else if (XSTRCMP(type, WC_SN_sha512) == 0) { ret = WC_NID_sha512WithRSAEncryption; } } @@ -9936,54 +10136,44 @@ static const struct alias { const char *alias; } digest_alias_tbl[] = { - {"MD4", "md4"}, - {"MD5", "md5"}, - {"SHA1", "sha1"}, - {"SHA1", "SHA"}, - {"SHA224", "sha224"}, - {"SHA256", "sha256"}, - {"SHA384", "sha384"}, - {"SHA512", "sha512"}, - {"SHA512_224", "sha512_224"}, - {"SHA3_224", "sha3_224"}, - {"SHA3_256", "sha3_256"}, - {"SHA3_384", "sha3_384"}, - {"SHA3_512", "sha3_512"}, - {"SM3", "sm3"}, - {"BLAKE2B512", "blake2b512"}, - {"BLAKE2S256", "blake2s256"}, - {"SHAKE128", "shake128"}, - {"SHAKE256", "shake256"}, + {WC_SN_md4, "md4"}, + {WC_SN_md5, "md5"}, + {WC_SN_sha1, "sha1"}, + {WC_SN_sha1, "SHA"}, + {WC_SN_sha224, "sha224"}, + {WC_SN_sha256, "sha256"}, + {WC_SN_sha384, "sha384"}, + {WC_SN_sha512, "sha512"}, + {WC_SN_sha512_224, "sha512_224"}, + {WC_SN_sha3_224, "sha3_224"}, + {WC_SN_sha3_256, "sha3_256"}, + {WC_SN_sha3_384, "sha3_384"}, + {WC_SN_sha3_512, "sha3_512"}, + {WC_SN_sm3, "sm3"}, + {WC_SN_blake2b512, "blake2b512"}, + {WC_SN_blake2s256, "blake2s256"}, + {WC_SN_shake128, "shake128"}, + {WC_SN_shake256, "shake256"}, { NULL, NULL} }; const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name) { - char nameUpper[15]; /* 15 bytes should be enough for any name */ - size_t i; - const struct alias *al; const struct s_ent *ent; - for (i = 0; i < sizeof(nameUpper) && name[i] != '\0'; i++) { - nameUpper[i] = (char)XTOUPPER((unsigned char) name[i]); - } - if (i < sizeof(nameUpper)) - nameUpper[i] = '\0'; - else - return NULL; - - name = nameUpper; - for (al = digest_alias_tbl; al->name != NULL; al++) + for (al = digest_alias_tbl; al->name != NULL; al++) { if(XSTRCMP(name, al->alias) == 0) { name = al->name; break; } + } - for (ent = md_tbl; ent->name != NULL; ent++) + for (ent = md_tbl; ent->name != NULL; ent++) { if(XSTRCMP(name, ent->name) == 0) { return (WOLFSSL_EVP_MD *)ent->name; } + } return NULL; } @@ -10017,7 +10207,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_md4(void) { WOLFSSL_ENTER("EVP_md4"); - return wolfSSL_EVP_get_digestbyname("MD4"); + return wolfSSL_EVP_get_digestbyname(WC_SN_md4); } #endif /* !NO_MD4 */ @@ -10028,7 +10218,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void) { WOLFSSL_ENTER("EVP_md5"); - return wolfSSL_EVP_get_digestbyname("MD5"); + return wolfSSL_EVP_get_digestbyname(WC_SN_md5); } #endif /* !NO_MD5 */ @@ -10040,8 +10230,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) */ const WOLFSSL_EVP_MD* wolfSSL_EVP_blake2b512(void) { - WOLFSSL_ENTER("EVP_blake2b512"); - return wolfSSL_EVP_get_digestbyname("BLAKE2b512"); + WOLFSSL_ENTER("wolfSSL_EVP_blake2b512"); + return wolfSSL_EVP_get_digestbyname(WC_SN_blake2b512); } #endif @@ -10080,7 +10270,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void) { WOLFSSL_ENTER("EVP_sha1"); - return wolfSSL_EVP_get_digestbyname("SHA1"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha1); } #endif /* NO_SHA */ @@ -10089,7 +10279,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha224(void) { WOLFSSL_ENTER("EVP_sha224"); - return wolfSSL_EVP_get_digestbyname("SHA224"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha224); } #endif /* WOLFSSL_SHA224 */ @@ -10098,7 +10288,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void) { WOLFSSL_ENTER("EVP_sha256"); - return wolfSSL_EVP_get_digestbyname("SHA256"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha256); } #ifdef WOLFSSL_SHA384 @@ -10106,7 +10296,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void) { WOLFSSL_ENTER("EVP_sha384"); - return wolfSSL_EVP_get_digestbyname("SHA384"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha384); } #endif /* WOLFSSL_SHA384 */ @@ -10116,7 +10306,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void) { WOLFSSL_ENTER("EVP_sha512"); - return wolfSSL_EVP_get_digestbyname("SHA512"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha512); } #ifndef WOLFSSL_NOSHA512_224 @@ -10124,7 +10314,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512_224(void) { WOLFSSL_ENTER("EVP_sha512_224"); - return wolfSSL_EVP_get_digestbyname("SHA512_224"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha512_224); } #endif /* !WOLFSSL_NOSHA512_224 */ @@ -10133,7 +10323,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512_256(void) { WOLFSSL_ENTER("EVP_sha512_256"); - return wolfSSL_EVP_get_digestbyname("SHA512_256"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha512_256); } #endif /* !WOLFSSL_NOSHA512_224 */ @@ -10145,7 +10335,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_224(void) { WOLFSSL_ENTER("EVP_sha3_224"); - return wolfSSL_EVP_get_digestbyname("SHA3_224"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha3_224); } #endif /* WOLFSSL_NOSHA3_224 */ @@ -10154,7 +10344,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_256(void) { WOLFSSL_ENTER("EVP_sha3_256"); - return wolfSSL_EVP_get_digestbyname("SHA3_256"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha3_256); } #endif /* WOLFSSL_NOSHA3_256 */ @@ -10162,7 +10352,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_384(void) { WOLFSSL_ENTER("EVP_sha3_384"); - return wolfSSL_EVP_get_digestbyname("SHA3_384"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha3_384); } #endif /* WOLFSSL_NOSHA3_384 */ @@ -10170,7 +10360,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_512(void) { WOLFSSL_ENTER("EVP_sha3_512"); - return wolfSSL_EVP_get_digestbyname("SHA3_512"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha3_512); } #endif /* WOLFSSL_NOSHA3_512 */ @@ -10196,7 +10386,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sm3(void) { WOLFSSL_ENTER("EVP_sm3"); - return wolfSSL_EVP_get_digestbyname("SM3"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sm3); } #endif /* WOLFSSL_SM3 */ @@ -10482,17 +10672,21 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) /* Not an error since an unused struct could be free'd or * reset. */ break; - case WC_HASH_TYPE_MD2: - case WC_HASH_TYPE_MD4: - case WC_HASH_TYPE_MD5_SHA: - case WC_HASH_TYPE_BLAKE2B: - case WC_HASH_TYPE_BLAKE2S: #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128) case WC_HASH_TYPE_SHAKE128: + wc_Shake128_Free(&ctx->hash.digest.shake); + break; #endif #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE256) case WC_HASH_TYPE_SHAKE256: + wc_Shake256_Free(&ctx->hash.digest.shake); + break; #endif + case WC_HASH_TYPE_MD2: + case WC_HASH_TYPE_MD4: + case WC_HASH_TYPE_MD5_SHA: + case WC_HASH_TYPE_BLAKE2B: + case WC_HASH_TYPE_BLAKE2S: default: ret = WOLFSSL_FAILURE; break; @@ -10526,76 +10720,92 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) XMEMSET(&ctx->hash.digest, 0, sizeof(WOLFSSL_Hasher)); } else #ifndef NO_SHA - if ((XSTRCMP(md, "SHA") == 0) || (XSTRCMP(md, "SHA1") == 0)) { + if ((XSTRCMP(md, "SHA") == 0) || (XSTRCMP(md, WC_SN_sha1) == 0)) { ret = wolfSSL_SHA_Init(&(ctx->hash.digest.sha)); } else #endif #ifndef NO_SHA256 - if (XSTRCMP(md, "SHA256") == 0) { + if (XSTRCMP(md, WC_SN_sha256) == 0) { ret = wolfSSL_SHA256_Init(&(ctx->hash.digest.sha256)); } else #endif #ifdef WOLFSSL_SHA224 - if (XSTRCMP(md, "SHA224") == 0) { + if (XSTRCMP(md, WC_SN_sha224) == 0) { ret = wolfSSL_SHA224_Init(&(ctx->hash.digest.sha224)); } else #endif #ifdef WOLFSSL_SHA384 - if (XSTRCMP(md, "SHA384") == 0) { + if (XSTRCMP(md, WC_SN_sha384) == 0) { ret = wolfSSL_SHA384_Init(&(ctx->hash.digest.sha384)); } else #endif #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \ defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224) - if (XSTRCMP(md, "SHA512_224") == 0) { + if (XSTRCMP(md, WC_SN_sha512_224) == 0) { ret = wolfSSL_SHA512_224_Init(&(ctx->hash.digest.sha512)); } else #endif #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \ defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256) - if (XSTRCMP(md, "SHA512_256") == 0) { + if (XSTRCMP(md, WC_SN_sha512_256) == 0) { ret = wolfSSL_SHA512_256_Init(&(ctx->hash.digest.sha512)); } else #endif #ifdef WOLFSSL_SHA512 - if (XSTRCMP(md, "SHA512") == 0) { + if (XSTRCMP(md, WC_SN_sha512) == 0) { ret = wolfSSL_SHA512_Init(&(ctx->hash.digest.sha512)); } else #endif #ifndef NO_MD4 - if (XSTRCMP(md, "MD4") == 0) { + if (XSTRCMP(md, WC_SN_md4) == 0) { wolfSSL_MD4_Init(&(ctx->hash.digest.md4)); } else #endif #ifndef NO_MD5 - if (XSTRCMP(md, "MD5") == 0) { + if (XSTRCMP(md, WC_SN_md5) == 0) { ret = wolfSSL_MD5_Init(&(ctx->hash.digest.md5)); } else #endif #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 - if (XSTRCMP(md, "SHA3_224") == 0) { + if (XSTRCMP(md, WC_SN_sha3_224) == 0) { ret = wolfSSL_SHA3_224_Init(&(ctx->hash.digest.sha3_224)); } else #endif #ifndef WOLFSSL_NOSHA3_256 - if (XSTRCMP(md, "SHA3_256") == 0) { + if (XSTRCMP(md, WC_SN_sha3_256) == 0) { ret = wolfSSL_SHA3_256_Init(&(ctx->hash.digest.sha3_256)); } else #endif #ifndef WOLFSSL_NOSHA3_384 - if (XSTRCMP(md, "SHA3_384") == 0) { + if (XSTRCMP(md, WC_SN_sha3_384) == 0) { ret = wolfSSL_SHA3_384_Init(&(ctx->hash.digest.sha3_384)); } else #endif #ifndef WOLFSSL_NOSHA3_512 - if (XSTRCMP(md, "SHA3_512") == 0) { + if (XSTRCMP(md, WC_SN_sha3_512) == 0) { ret = wolfSSL_SHA3_512_Init(&(ctx->hash.digest.sha3_512)); } else #endif + #ifdef WOLFSSL_SHAKE128 + if (XSTRCMP(md, WC_SN_shake128) == 0) { + if (wc_InitShake128(&(ctx->hash.digest.shake), NULL, + INVALID_DEVID) != 0) { + ret = WOLFSSL_FAILURE; + } + } else + #endif + #ifdef WOLFSSL_SHAKE256 + if (XSTRCMP(md, WC_SN_shake256) == 0) { + if (wc_InitShake256(&(ctx->hash.digest.shake), NULL, + INVALID_DEVID) != 0) { + ret = WOLFSSL_FAILURE; + } + } else + #endif #endif #ifdef WOLFSSL_SM3 - if (XSTRCMP(md, "SM3") == 0) { + if (XSTRCMP(md, WC_SN_sm3) == 0) { ret = wc_InitSm3(&ctx->hash.digest.sm3, NULL, INVALID_DEVID); if (ret == 0) { ret = WOLFSSL_SUCCESS; @@ -10723,17 +10933,28 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) } break; #endif - case WC_HASH_TYPE_NONE: - case WC_HASH_TYPE_MD2: - case WC_HASH_TYPE_MD5_SHA: - case WC_HASH_TYPE_BLAKE2B: - case WC_HASH_TYPE_BLAKE2S: #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128) case WC_HASH_TYPE_SHAKE128: + if (wc_Shake128_Update(&ctx->hash.digest.shake, + (const byte*)data, (word32)sz) == 0) { + + ret = WOLFSSL_SUCCESS; + } + break; #endif #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE256) case WC_HASH_TYPE_SHAKE256: + if (wc_Shake256_Update(&ctx->hash.digest.shake, + (const byte*)data, (word32)sz) == 0) { + ret = WOLFSSL_SUCCESS; + } + break; #endif + case WC_HASH_TYPE_NONE: + case WC_HASH_TYPE_MD2: + case WC_HASH_TYPE_MD5_SHA: + case WC_HASH_TYPE_BLAKE2B: + case WC_HASH_TYPE_BLAKE2S: default: return WOLFSSL_FAILURE; } @@ -10742,14 +10963,11 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) } /* WOLFSSL_SUCCESS on ok */ - int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md, - unsigned int* s) + static int wolfSSL_EVP_DigestFinal_Common(WOLFSSL_EVP_MD_CTX* ctx, + unsigned char* md, unsigned int* s, enum wc_HashType macType) { int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE); - enum wc_HashType macType; - WOLFSSL_ENTER("EVP_DigestFinal"); - macType = EvpMd2MacType(wolfSSL_EVP_MD_CTX_md(ctx)); switch (macType) { case WC_HASH_TYPE_MD4: #ifndef NO_MD4 @@ -10847,23 +11065,84 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) } if (s) *s = WC_SM3_DIGEST_SIZE; break; + #endif + #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128) + case WC_HASH_TYPE_SHAKE128: + if (wc_Shake128_Final(&ctx->hash.digest.shake, md, *s) == 0) { + ret = WOLFSSL_SUCCESS; + } + break; + #endif + #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE256) + case WC_HASH_TYPE_SHAKE256: + if (wc_Shake256_Final(&ctx->hash.digest.shake, md, *s) == 0) { + ret = WOLFSSL_SUCCESS; + } + break; #endif case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD5_SHA: case WC_HASH_TYPE_BLAKE2B: case WC_HASH_TYPE_BLAKE2S: + default: + return WOLFSSL_FAILURE; + } + + return ret; + } + + int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md, + unsigned int* s) + { + enum wc_HashType macType; + + WOLFSSL_ENTER("wolfSSL_EVP_DigestFinal"); + macType = EvpMd2MacType(wolfSSL_EVP_MD_CTX_md(ctx)); + switch (macType) { + case WC_HASH_TYPE_MD4: + case WC_HASH_TYPE_MD5: + case WC_HASH_TYPE_SHA: + case WC_HASH_TYPE_SHA224: + case WC_HASH_TYPE_SHA256: + case WC_HASH_TYPE_SHA384: + case WC_HASH_TYPE_SHA512: + #ifndef WOLFSSL_NOSHA512_224 + case WC_HASH_TYPE_SHA512_224: + #endif /* !WOLFSSL_NOSHA512_224 */ + #ifndef WOLFSSL_NOSHA512_256 + case WC_HASH_TYPE_SHA512_256: + #endif /* !WOLFSSL_NOSHA512_256 */ + case WC_HASH_TYPE_SHA3_224: + case WC_HASH_TYPE_SHA3_256: + case WC_HASH_TYPE_SHA3_384: + case WC_HASH_TYPE_SHA3_512: + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + #endif + case WC_HASH_TYPE_NONE: + case WC_HASH_TYPE_MD2: + case WC_HASH_TYPE_MD5_SHA: + case WC_HASH_TYPE_BLAKE2B: + case WC_HASH_TYPE_BLAKE2S: + break; + #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128) case WC_HASH_TYPE_SHAKE128: + *s = 16; /* if mixing up XOF with plain digest 128 bit is + * default for SHAKE128 */ + break; #endif #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE256) case WC_HASH_TYPE_SHAKE256: + *s = 32; /* if mixing up XOF with plain digest 256 bit is + * default for SHAKE256 */ + break; #endif default: return WOLFSSL_FAILURE; } - - return ret; + return wolfSSL_EVP_DigestFinal_Common(ctx, md, s, macType); } /* WOLFSSL_SUCCESS on ok */ @@ -10874,6 +11153,46 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) return wolfSSL_EVP_DigestFinal(ctx, md, s); } + + /* XOF stands for extendable-output functions. This is used for algos such + * as SHAKE256. + * + * returns 1 (WOLFSSL_SUCCESS) on success and 0 (WOLFSSL_FAILURE) on fail */ + int wolfSSL_EVP_DigestFinalXOF(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *md, + size_t sz) + { + unsigned int len; + enum wc_HashType macType; + + WOLFSSL_ENTER("wolfSSL_EVP_DigestFinalXOF"); + len = (unsigned int)sz; + + macType = EvpMd2MacType(wolfSSL_EVP_MD_CTX_md(ctx)); + return wolfSSL_EVP_DigestFinal_Common(ctx, md, &len, macType); + } + + + unsigned long wolfSSL_EVP_MD_flags(const WOLFSSL_EVP_MD *md) + { + enum wc_HashType macType; + + macType = EvpMd2MacType(md); + switch ((int)macType) { + case WC_HASH_TYPE_BLAKE2B: + case WC_HASH_TYPE_BLAKE2S: + #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128) + case WC_HASH_TYPE_SHAKE128: + #endif + #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE256) + case WC_HASH_TYPE_SHAKE256: + #endif + return WOLFSSL_EVP_MD_FLAG_XOF; + default: + return 0; + } + } + + void wolfSSL_EVP_cleanup(void) { /* nothing to do here */ @@ -10884,6 +11203,10 @@ const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id) WOLFSSL_MSG("wolfSSL_get_digestbynid"); switch(id) { +#ifndef NO_MD4 + case WC_NID_md4: + return wolfSSL_EVP_md4(); +#endif #ifndef NO_MD5 case WC_NID_md5: return wolfSSL_EVP_md5(); @@ -10928,64 +11251,64 @@ int wolfSSL_EVP_MD_block_size(const WOLFSSL_EVP_MD* type) } #ifndef NO_SHA - if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, "SHA1") == 0)) { + if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, WC_SN_sha1) == 0)) { return WC_SHA_BLOCK_SIZE; } else #endif #ifndef NO_SHA256 - if (XSTRCMP(type, "SHA256") == 0) { + if (XSTRCMP(type, WC_SN_sha256) == 0) { return WC_SHA256_BLOCK_SIZE; } else #endif #ifndef NO_MD4 - if (XSTRCMP(type, "MD4") == 0) { + if (XSTRCMP(type, WC_SN_md4) == 0) { return WC_MD4_BLOCK_SIZE; } else #endif #ifndef NO_MD5 - if (XSTRCMP(type, "MD5") == 0) { + if (XSTRCMP(type, WC_SN_md5) == 0) { return WC_MD5_BLOCK_SIZE; } else #endif #ifdef WOLFSSL_SHA224 - if (XSTRCMP(type, "SHA224") == 0) { + if (XSTRCMP(type, WC_SN_sha224) == 0) { return WC_SHA224_BLOCK_SIZE; } else #endif #ifdef WOLFSSL_SHA384 - if (XSTRCMP(type, "SHA384") == 0) { + if (XSTRCMP(type, WC_SN_sha384) == 0) { return WC_SHA384_BLOCK_SIZE; } else #endif #ifdef WOLFSSL_SHA512 - if (XSTRCMP(type, "SHA512") == 0) { + if (XSTRCMP(type, WC_SN_sha512) == 0) { return WC_SHA512_BLOCK_SIZE; } else #endif #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 - if (XSTRCMP(type, "SHA3_224") == 0) { + if (XSTRCMP(type, WC_SN_sha3_224) == 0) { return WC_SHA3_224_BLOCK_SIZE; } else #endif #ifndef WOLFSSL_NOSHA3_256 - if (XSTRCMP(type, "SHA3_256") == 0) { + if (XSTRCMP(type, WC_SN_sha3_256) == 0) { return WC_SHA3_256_BLOCK_SIZE; } else #endif #ifndef WOLFSSL_NOSHA3_384 - if (XSTRCMP(type, "SHA3_384") == 0) { + if (XSTRCMP(type, WC_SN_sha3_384) == 0) { return WC_SHA3_384_BLOCK_SIZE; } else #endif #ifndef WOLFSSL_NOSHA3_512 - if (XSTRCMP(type, "SHA3_512") == 0) { + if (XSTRCMP(type, WC_SN_sha3_512) == 0) { return WC_SHA3_512_BLOCK_SIZE; - } + } else #endif #endif /* WOLFSSL_SHA3 */ #ifdef WOLFSSL_SM3 - if (XSTRCMP(type, "SM3") == 0) { + if (XSTRCMP(type, WC_SN_sm3) == 0) { return WC_SM3_BLOCK_SIZE; } else #endif @@ -11003,74 +11326,74 @@ int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* type) } #ifndef NO_SHA - if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, "SHA1") == 0)) { + if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, WC_SN_sha1) == 0)) { return WC_SHA_DIGEST_SIZE; } else #endif #ifndef NO_SHA256 - if (XSTRCMP(type, "SHA256") == 0) { + if (XSTRCMP(type, WC_SN_sha256) == 0) { return WC_SHA256_DIGEST_SIZE; } else #endif #ifndef NO_MD4 - if (XSTRCMP(type, "MD4") == 0) { + if (XSTRCMP(type, WC_SN_md4) == 0) { return WC_MD4_DIGEST_SIZE; } else #endif #ifndef NO_MD5 - if (XSTRCMP(type, "MD5") == 0) { + if (XSTRCMP(type, WC_SN_md5) == 0) { return WC_MD5_DIGEST_SIZE; } else #endif #ifdef WOLFSSL_SHA224 - if (XSTRCMP(type, "SHA224") == 0) { + if (XSTRCMP(type, WC_SN_sha224) == 0) { return WC_SHA224_DIGEST_SIZE; } else #endif #ifdef WOLFSSL_SHA384 - if (XSTRCMP(type, "SHA384") == 0) { + if (XSTRCMP(type, WC_SN_sha384) == 0) { return WC_SHA384_DIGEST_SIZE; } else #endif #ifdef WOLFSSL_SHA512 - if (XSTRCMP(type, "SHA512") == 0) { + if (XSTRCMP(type, WC_SN_sha512) == 0) { return WC_SHA512_DIGEST_SIZE; } else #ifndef WOLFSSL_NOSHA512_224 - if (XSTRCMP(type, "SHA512_224") == 0) { + if (XSTRCMP(type, WC_SN_sha512_224) == 0) { return WC_SHA512_224_DIGEST_SIZE; } else #endif #ifndef WOLFSSL_NOSHA512_256 - if (XSTRCMP(type, "SHA512_256") == 0) { + if (XSTRCMP(type, WC_SN_sha512_256) == 0) { return WC_SHA512_256_DIGEST_SIZE; } else #endif #endif #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 - if (XSTRCMP(type, "SHA3_224") == 0) { + if (XSTRCMP(type, WC_SN_sha3_224) == 0) { return WC_SHA3_224_DIGEST_SIZE; } else #endif #ifndef WOLFSSL_NOSHA3_256 - if (XSTRCMP(type, "SHA3_256") == 0) { + if (XSTRCMP(type, WC_SN_sha3_256) == 0) { return WC_SHA3_256_DIGEST_SIZE; } else #endif #ifndef WOLFSSL_NOSHA3_384 - if (XSTRCMP(type, "SHA3_384") == 0) { + if (XSTRCMP(type, WC_SN_sha3_384) == 0) { return WC_SHA3_384_DIGEST_SIZE; } else #endif #ifndef WOLFSSL_NOSHA3_512 - if (XSTRCMP(type, "SHA3_512") == 0) { + if (XSTRCMP(type, WC_SN_sha3_512) == 0) { return WC_SHA3_512_DIGEST_SIZE; } else #endif #endif /* WOLFSSL_SHA3 */ #ifdef WOLFSSL_SM3 - if (XSTRCMP(type, "SM3") == 0) { + if (XSTRCMP(type, WC_SN_sm3) == 0) { return WC_SM3_DIGEST_SIZE; } #endif @@ -12182,7 +12505,7 @@ int wolfSSL_EVP_PKEY_print_public(WOLFSSL_BIO* out, case WC_EVP_PKEY_RSA: #if !defined(NO_RSA) - keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8; + keybits = wolfSSL_EVP_PKEY_bits((WOLFSSL_EVP_PKEY*)pkey); res = PrintPubKeyRSA( out, (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */ @@ -12198,7 +12521,7 @@ int wolfSSL_EVP_PKEY_print_public(WOLFSSL_BIO* out, case WC_EVP_PKEY_EC: #if defined(HAVE_ECC) - keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8; + keybits = wolfSSL_EVP_PKEY_bits((WOLFSSL_EVP_PKEY*)pkey); res = PrintPubKeyEC( out, (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */ @@ -12214,7 +12537,7 @@ int wolfSSL_EVP_PKEY_print_public(WOLFSSL_BIO* out, case WC_EVP_PKEY_DSA: #if !defined(NO_DSA) - keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8; + keybits = wolfSSL_EVP_PKEY_bits((WOLFSSL_EVP_PKEY*)pkey); res = PrintPubKeyDSA( out, (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */ @@ -12230,7 +12553,7 @@ int wolfSSL_EVP_PKEY_print_public(WOLFSSL_BIO* out, case WC_EVP_PKEY_DH: #if defined(WOLFSSL_DH_EXTRA) - keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8; + keybits = wolfSSL_EVP_PKEY_bits((WOLFSSL_EVP_PKEY*)pkey); res = PrintPubKeyDH( out, (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */ @@ -12263,64 +12586,64 @@ int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp, } #ifndef NO_SHA - if ((XSTRCMP("SHA", evp) == 0) || (XSTRCMP("SHA1", evp) == 0)) { + if ((XSTRCMP("SHA", evp) == 0) || (XSTRCMP(WC_SN_sha1, evp) == 0)) { hash = WC_HASH_TYPE_SHA; } else #endif #ifdef WOLFSSL_SHA224 - if (XSTRCMP("SHA224", evp) == 0) { + if (XSTRCMP(WC_SN_sha224, evp) == 0) { hash = WC_HASH_TYPE_SHA224; } else #endif #ifndef NO_SHA256 - if (XSTRCMP("SHA256", evp) == 0) { + if (XSTRCMP(WC_SN_sha256, evp) == 0) { hash = WC_HASH_TYPE_SHA256; } else #endif #ifdef WOLFSSL_SHA384 - if (XSTRCMP("SHA384", evp) == 0) { + if (XSTRCMP(WC_SN_sha384, evp) == 0) { hash = WC_HASH_TYPE_SHA384; } else #endif #ifdef WOLFSSL_SHA512 - if (XSTRCMP("SHA512", evp) == 0) { + if (XSTRCMP(WC_SN_sha512, evp) == 0) { hash = WC_HASH_TYPE_SHA512; } else #ifndef WOLFSSL_NOSHA512_224 - if (XSTRCMP("SHA512_224", evp) == 0) { + if (XSTRCMP(WC_SN_sha512_224, evp) == 0) { hash = WC_HASH_TYPE_SHA512_224; } else #endif #ifndef WOLFSSL_NOSHA512_256 - if (XSTRCMP("SHA512_256", evp) == 0) { + if (XSTRCMP(WC_SN_sha512_256, evp) == 0) { hash = WC_HASH_TYPE_SHA512_256; } else #endif #endif #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 - if (XSTRCMP("SHA3_224", evp) == 0) { + if (XSTRCMP(WC_SN_sha3_224, evp) == 0) { hash = WC_HASH_TYPE_SHA3_224; } else #endif #ifndef WOLFSSL_NOSHA3_256 - if (XSTRCMP("SHA3_256", evp) == 0) { + if (XSTRCMP(WC_SN_sha3_256, evp) == 0) { hash = WC_HASH_TYPE_SHA3_256; } else #endif #ifndef WOLFSSL_NOSHA3_384 - if (XSTRCMP("SHA3_384", evp) == 0) { + if (XSTRCMP(WC_SN_sha3_384, evp) == 0) { hash = WC_HASH_TYPE_SHA3_384; } else #endif #ifndef WOLFSSL_NOSHA3_512 - if (XSTRCMP("SHA3_512", evp) == 0) { + if (XSTRCMP(WC_SN_sha3_512, evp) == 0) { hash = WC_HASH_TYPE_SHA3_512; } else #endif #endif /* WOLFSSL_SHA3 */ #ifdef WOLFSSL_SM3 - if (XSTRCMP("SM3", evp) == 0) { + if (XSTRCMP(WC_SN_sm3, evp) == 0) { hash = WC_HASH_TYPE_SM3; } else #endif @@ -12330,12 +12653,12 @@ int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp, } else #endif #ifndef NO_MD4 - if (XSTRCMP("MD4", evp) == 0) { + if (XSTRCMP(WC_SN_md4, evp) == 0) { hash = WC_HASH_TYPE_MD4; } else #endif #ifndef NO_MD5 - if (XSTRCMP("MD5", evp) == 0) { + if (XSTRCMP(WC_SN_md5, evp) == 0) { hash = WC_HASH_TYPE_MD5; } else #endif diff --git a/src/wolfcrypt/src/ext_lms.c b/src/wolfcrypt/src/ext_lms.c index 70dfa5b..00a3e55 100644 --- a/src/wolfcrypt/src/ext_lms.c +++ b/src/wolfcrypt/src/ext_lms.c @@ -1,6 +1,6 @@ /* ext_lms.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,13 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include -#include -#include +#include #if defined(WOLFSSL_HAVE_LMS) && defined(HAVE_LIBLMS) @@ -1049,4 +1043,12 @@ int wc_LmsKey_Verify(LmsKey * key, const byte * sig, word32 sigSz, return 0; } +const byte * wc_LmsKey_GetKidFromPrivRaw(const byte * priv, word32 privSz) +{ + if ((priv == NULL) || (privSz < 16)) { + return NULL; + } + return priv - 16; +} + #endif /* WOLFSSL_HAVE_LMS && HAVE_LIBLMS */ diff --git a/src/wolfcrypt/src/ext_mlkem.c b/src/wolfcrypt/src/ext_mlkem.c new file mode 100644 index 0000000..3a9ccee --- /dev/null +++ b/src/wolfcrypt/src/ext_mlkem.c @@ -0,0 +1,762 @@ +/* ext_mlkem.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 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include + +#if defined(WOLFSSL_HAVE_MLKEM) && !defined(WOLFSSL_WC_MLKEM) +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#if defined (HAVE_LIBOQS) + +#include + +static const char* OQS_ID2name(int id) { + switch (id) { + #ifndef WOLFSSL_NO_ML_KEM + case WC_ML_KEM_512: return OQS_KEM_alg_ml_kem_512; + case WC_ML_KEM_768: return OQS_KEM_alg_ml_kem_768; + case WC_ML_KEM_1024: return OQS_KEM_alg_ml_kem_1024; + #endif + #ifdef WOLFSSL_MLKEM_KYBER + case KYBER_LEVEL1: return OQS_KEM_alg_kyber_512; + case KYBER_LEVEL3: return OQS_KEM_alg_kyber_768; + case KYBER_LEVEL5: return OQS_KEM_alg_kyber_1024; + #endif + default: break; + } + return NULL; +} + +int ext_mlkem_enabled(int id) +{ + const char * name = OQS_ID2name(id); + return OQS_KEM_alg_is_enabled(name); +} +#endif + +/******************************************************************************/ +/* Initializer and cleanup functions. */ + +/** + * Initialize the Kyber key. + * + * @param [out] key Kyber key object to initialize. + * @param [in] type Type of key: KYBER512, KYBER768, KYBER1024. + * @param [in] heap Dynamic memory hint. + * @param [in] devId Device Id. + * @return 0 on success. + * @return BAD_FUNC_ARG when key is NULL or type is unrecognized. + * @return NOT_COMPILED_IN when key type is not supported. + */ +int wc_MlKemKey_Init(MlKemKey* key, int type, void* heap, int devId) +{ + int ret = 0; + + /* Validate key. */ + if (key == NULL) { + ret = BAD_FUNC_ARG; + } + if (ret == 0) { + /* Validate type. */ + switch (type) { +#ifndef WOLFSSL_NO_ML_KEM + case WC_ML_KEM_512: + #ifdef HAVE_LIBOQS + case WC_ML_KEM_768: + case WC_ML_KEM_1024: + #endif /* HAVE_LIBOQS */ +#endif +#ifdef WOLFSSL_MLKEM_KYBER + case KYBER_LEVEL1: + #ifdef HAVE_LIBOQS + case KYBER_LEVEL3: + case KYBER_LEVEL5: + #endif /* HAVE_LIBOQS */ +#endif + break; + default: + /* No other values supported. */ + ret = BAD_FUNC_ARG; + break; + } + } + if (ret == 0) { + /* Zero out all data. */ + XMEMSET(key, 0, sizeof(*key)); + + /* Keep type for parameters. */ + key->type = type; + +#ifdef WOLF_CRYPTO_CB + key->devCtx = NULL; + key->devId = devId; +#endif + } + + (void)heap; + (void)devId; + + return ret; +} + +/** + * Free the Kyber key object. + * + * @param [in, out] key Kyber key object to dispose of. + */ +int wc_MlKemKey_Free(MlKemKey* key) +{ + if (key != NULL) { + /* Ensure all private data is zeroed. */ + ForceZero(key, sizeof(*key)); + } + + return 0; +} + +/******************************************************************************/ +/* Data size getters. */ + +/** + * Get the size in bytes of encoded private key for the key. + * + * @param [in] key Kyber key object. + * @param [out] len Length of encoded private key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or len is NULL. + * @return NOT_COMPILED_IN when key type is not supported. + */ +int wc_MlKemKey_PrivateKeySize(MlKemKey* key, word32* len) +{ + int ret = 0; + + /* Validate parameters. */ + if ((key == NULL) || (len == NULL)) { + ret = BAD_FUNC_ARG; + } + +#ifdef HAVE_LIBOQS + /* NOTE: SHAKE and AES variants have the same length private key. */ + if (ret == 0) { + switch (key->type) { + #ifndef WOLFSSL_NO_ML_KEM + case WC_ML_KEM_512: + *len = OQS_KEM_ml_kem_512_length_secret_key; + break; + case WC_ML_KEM_768: + *len = OQS_KEM_ml_kem_768_length_secret_key; + break; + case WC_ML_KEM_1024: + *len = OQS_KEM_ml_kem_1024_length_secret_key; + break; + #endif + #ifdef WOLFSSL_MLKEM_KYBER + case KYBER_LEVEL1: + *len = OQS_KEM_kyber_512_length_secret_key; + break; + case KYBER_LEVEL3: + *len = OQS_KEM_kyber_768_length_secret_key; + break; + case KYBER_LEVEL5: + *len = OQS_KEM_kyber_1024_length_secret_key; + break; + #endif + default: + /* No other values supported. */ + ret = BAD_FUNC_ARG; + break; + } + } +#endif /* HAVE_LIBOQS */ + + return ret; +} + +/** + * Get the size in bytes of encoded public key for the key. + * + * @param [in] key Kyber key object. + * @param [out] len Length of encoded public key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or len is NULL. + * @return NOT_COMPILED_IN when key type is not supported. + */ +int wc_MlKemKey_PublicKeySize(MlKemKey* key, word32* len) +{ + int ret = 0; + + /* Validate parameters. */ + if ((key == NULL) || (len == NULL)) { + ret = BAD_FUNC_ARG; + } + +#ifdef HAVE_LIBOQS + /* NOTE: SHAKE and AES variants have the same length public key. */ + if (ret == 0) { + switch (key->type) { + #ifndef WOLFSSL_NO_ML_KEM + case WC_ML_KEM_512: + *len = OQS_KEM_ml_kem_512_length_public_key; + break; + case WC_ML_KEM_768: + *len = OQS_KEM_ml_kem_768_length_public_key; + break; + case WC_ML_KEM_1024: + *len = OQS_KEM_ml_kem_1024_length_public_key; + break; + #endif + #ifdef WOLFSSL_MLKEM_KYBER + case KYBER_LEVEL1: + *len = OQS_KEM_kyber_512_length_public_key; + break; + case KYBER_LEVEL3: + *len = OQS_KEM_kyber_768_length_public_key; + break; + case KYBER_LEVEL5: + *len = OQS_KEM_kyber_1024_length_public_key; + break; + #endif + default: + /* No other values supported. */ + ret = BAD_FUNC_ARG; + break; + } + } +#endif /* HAVE_LIBOQS */ + + return ret; +} + +/** + * Get the size in bytes of cipher text for key. + * + * @param [in] key Kyber key object. + * @param [out] len Length of cipher text in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or len is NULL. + * @return NOT_COMPILED_IN when key type is not supported. + */ +int wc_MlKemKey_CipherTextSize(MlKemKey* key, word32* len) +{ + int ret = 0; + + /* Validate parameters. */ + if ((key == NULL) || (len == NULL)) { + ret = BAD_FUNC_ARG; + } + +#ifdef HAVE_LIBOQS + /* NOTE: SHAKE and AES variants have the same length ciphertext. */ + if (ret == 0) { + switch (key->type) { + #ifndef WOLFSSL_NO_ML_KEM + case WC_ML_KEM_512: + *len = OQS_KEM_ml_kem_512_length_ciphertext; + break; + case WC_ML_KEM_768: + *len = OQS_KEM_ml_kem_768_length_ciphertext; + break; + case WC_ML_KEM_1024: + *len = OQS_KEM_ml_kem_1024_length_ciphertext; + break; + #endif + #ifdef WOLFSSL_MLKEM_KYBER + case KYBER_LEVEL1: + *len = OQS_KEM_kyber_512_length_ciphertext; + break; + case KYBER_LEVEL3: + *len = OQS_KEM_kyber_768_length_ciphertext; + break; + case KYBER_LEVEL5: + *len = OQS_KEM_kyber_1024_length_ciphertext; + break; + #endif + default: + /* No other values supported. */ + ret = BAD_FUNC_ARG; + break; + } + } +#endif /* HAVE_LIBOQS */ + + return ret; +} + +/** + * Size of a shared secret in bytes. Always KYBER_SS_SZ. + * + * @param [in] key Kyber key object. Not used. + * @param [out] Size of the shared secret created with a Kyber key. + * @return 0 on success. + * @return 0 to indicate success. + */ +int wc_MlKemKey_SharedSecretSize(MlKemKey* key, word32* len) +{ + (void)key; + /* Validate parameters. */ + if (len == NULL) { + return BAD_FUNC_ARG; + } + + *len = KYBER_SS_SZ; + + return 0; +} + +/******************************************************************************/ +/* Cryptographic operations. */ + +/** + * Make a Kyber key object using a random number generator. + * + * NOTE: rng is ignored. OQS doesn't use our RNG. + * + * @param [in, out] key Kyber key ovject. + * @param [in] rng Random number generator. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or rng is NULL. + * @return MEMORY_E when dynamic memory allocation failed. + */ +int wc_MlKemKey_MakeKey(MlKemKey* key, WC_RNG* rng) +{ + int ret = 0; +#ifdef HAVE_LIBOQS + const char* algName = NULL; + OQS_KEM *kem = NULL; +#endif + + /* Validate parameter. */ + if (key == NULL) { + return BAD_FUNC_ARG; + } + +#ifdef WOLF_CRYPTO_CB + #ifndef WOLF_CRYPTO_CB_FIND + if (key->devId != INVALID_DEVID) + #endif + { + ret = wc_CryptoCb_MakePqcKemKey(rng, WC_PQC_KEM_TYPE_KYBER, + key->type, key); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when unavailable */ + ret = 0; + } +#endif + +#ifdef HAVE_LIBOQS + if (ret == 0) { + algName = OQS_ID2name(key->type); + if (algName == NULL) { + ret = BAD_FUNC_ARG; + } + } + + if (ret == 0) { + kem = OQS_KEM_new(algName); + if (kem == NULL) { + ret = BAD_FUNC_ARG; + } + } + if (ret == 0) { + ret = wolfSSL_liboqsRngMutexLock(rng); + } + if (ret == 0) { + if (OQS_KEM_keypair(kem, key->pub, key->priv) != + OQS_SUCCESS) { + ret = BAD_FUNC_ARG; + } + } + wolfSSL_liboqsRngMutexUnlock(); + OQS_KEM_free(kem); +#endif /* HAVE_LIBOQS */ + + if (ret != 0) { + ForceZero(key, sizeof(*key)); + } + + return ret; +} + +/** + * Make a Kyber key object using random data. + * + * @param [in, out] key Kyber key ovject. + * @param [in] rng Random number generator. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or rand is NULL. + * @return BUFFER_E when length is not KYBER_MAKEKEY_RAND_SZ. + * @return NOT_COMPILED_IN when key type is not supported. + * @return MEMORY_E when dynamic memory allocation failed. + */ +int wc_MlKemKey_MakeKeyWithRandom(MlKemKey* key, const unsigned char* rand, + int len) +{ + (void)rand; + (void)len; + /* OQS doesn't support external randomness. */ + return wc_MlKemKey_MakeKey(key, NULL); +} + +/** + * Encapsulate with random number generator and derive secret. + * + * @param [in] key Kyber key object. + * @param [out] ct Cipher text. + * @param [out] ss Shared secret generated. + * @param [in] rng Random number generator. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, ct, ss or RNG is NULL. + * @return NOT_COMPILED_IN when key type is not supported. + * @return MEMORY_E when dynamic memory allocation failed. + */ +int wc_MlKemKey_Encapsulate(MlKemKey* key, unsigned char* ct, unsigned char* ss, + WC_RNG* rng) +{ + int ret = 0; +#ifdef WOLF_CRYPTO_CB + word32 ctlen = 0; +#endif +#ifdef HAVE_LIBOQS + const char * algName = NULL; + OQS_KEM *kem = NULL; +#endif + + (void)rng; + + /* Validate parameters. */ + if ((key == NULL) || (ct == NULL) || (ss == NULL)) { + ret = BAD_FUNC_ARG; + } + +#ifdef WOLF_CRYPTO_CB + if (ret == 0) { + ret = wc_MlKemKey_CipherTextSize(key, &ctlen); + } + if ((ret == 0) + #ifndef WOLF_CRYPTO_CB_FIND + && (key->devId != INVALID_DEVID) + #endif + ) { + ret = wc_CryptoCb_PqcEncapsulate(ct, ctlen, ss, KYBER_SS_SZ, rng, + WC_PQC_KEM_TYPE_KYBER, key); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when unavailable */ + ret = 0; + } +#endif + +#ifdef HAVE_LIBOQS + if (ret == 0) { + algName = OQS_ID2name(key->type); + if (algName == NULL) { + ret = BAD_FUNC_ARG; + } + } + if (ret == 0) { + kem = OQS_KEM_new(algName); + if (kem == NULL) { + ret = BAD_FUNC_ARG; + } + } + if (ret == 0) { + ret = wolfSSL_liboqsRngMutexLock(rng); + } + if (ret == 0) { + if (OQS_KEM_encaps(kem, ct, ss, key->pub) != OQS_SUCCESS) { + ret = BAD_FUNC_ARG; + } + } + wolfSSL_liboqsRngMutexUnlock(); + OQS_KEM_free(kem); +#endif /* HAVE_LIBOQS */ + + return ret; +} + +/** + * Encapsulate with random data and derive secret. + * + * @param [out] ct Cipher text. + * @param [out] ss Shared secret generated. + * @param [in] rand Random data. + * @param [in] len Random data. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, ct, ss or RNG is NULL. + * @return BUFFER_E when len is not KYBER_ENC_RAND_SZ. + * @return NOT_COMPILED_IN when key type is not supported. + * @return MEMORY_E when dynamic memory allocation failed. + */ +int wc_MlKemKey_EncapsulateWithRandom(MlKemKey* key, unsigned char* ct, + unsigned char* ss, const unsigned char* rand, int len) +{ + (void)rand; + (void)len; + /* OQS doesn't support external randomness. */ + return wc_MlKemKey_Encapsulate(key, ct, ss, NULL); +} + +/** + * Decapsulate the cipher text to calculate the shared secret. + * + * Validates the cipher text by encapsulating and comparing with data passed in. + * + * @param [in] key Kyber key object. + * @param [out] ss Shared secret. + * @param [in] ct Cipher text. + * @param [in] len Length of cipher text. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, ss or cr are NULL. + * @return NOT_COMPILED_IN when key type is not supported. + * @return BUFFER_E when len is not the length of cipher text for the key type. + * @return MEMORY_E when dynamic memory allocation failed. + */ +int wc_MlKemKey_Decapsulate(MlKemKey* key, unsigned char* ss, + const unsigned char* ct, word32 len) +{ + int ret = 0; + word32 ctlen = 0; +#ifdef HAVE_LIBOQS + const char * algName = NULL; + OQS_KEM *kem = NULL; +#endif + + /* Validate parameters. */ + if ((key == NULL) || (ss == NULL) || (ct == NULL)) { + ret = BAD_FUNC_ARG; + } + if (ret == 0) { + ret = wc_MlKemKey_CipherTextSize(key, &ctlen); + } + if ((ret == 0) && (len != ctlen)) { + ret = BUFFER_E; + } + +#ifdef WOLF_CRYPTO_CB + if ((ret == 0) + #ifndef WOLF_CRYPTO_CB_FIND + && (key->devId != INVALID_DEVID) + #endif + ) { + ret = wc_CryptoCb_PqcDecapsulate(ct, ctlen, ss, KYBER_SS_SZ, + WC_PQC_KEM_TYPE_KYBER, key); + if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + return ret; + /* fall-through when unavailable */ + ret = 0; + } +#endif + +#ifdef HAVE_LIBOQS + if (ret == 0) { + algName = OQS_ID2name(key->type); + if (algName == NULL) { + ret = BAD_FUNC_ARG; + } + } + if (ret == 0) { + kem = OQS_KEM_new(algName); + if (kem == NULL) { + ret = BAD_FUNC_ARG; + } + } + if (ret == 0) { + if (OQS_KEM_decaps(kem, ss, ct, key->priv) != OQS_SUCCESS) { + ret = BAD_FUNC_ARG; + } + } + + OQS_KEM_free(kem); +#endif /* HAVE_LIBOQS */ + + return ret; + +} + +/******************************************************************************/ +/* Encoding and decoding functions. */ + +/** + * Decode the private key. + * + * We store the whole thing in the private key buffer. Note this means we cannot + * do the encapsulation operation with the private key. But generally speaking + * this is never done. + * + * @param [in, out] key Kyber key object. + * @param [in] in Buffer holding encoded key. + * @param [in] len Length of data in buffer. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or in is NULL. + * @return NOT_COMPILED_IN when key type is not supported. + * @return BUFFER_E when len is not the correct size. + */ +int wc_MlKemKey_DecodePrivateKey(MlKemKey* key, const unsigned char* in, + word32 len) +{ + int ret = 0; + word32 privLen = 0; + + /* Validate parameters. */ + if ((key == NULL) || (in == NULL)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + ret = wc_MlKemKey_PrivateKeySize(key, &privLen); + } + + /* Ensure the data is the correct length for the key type. */ + if ((ret == 0) && (len != privLen)) { + ret = BUFFER_E; + } + + if (ret == 0) { + XMEMCPY(key->priv, in, privLen); + } + + return ret; +} + +/** + * Decode public key. + * + * We store the whole thing in the public key buffer. + * + * @param [in, out] key Kyber key object. + * @param [in] in Buffer holding encoded key. + * @param [in] len Length of data in buffer. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or in is NULL. + * @return NOT_COMPILED_IN when key type is not supported. + * @return BUFFER_E when len is not the correct size. + */ +int wc_MlKemKey_DecodePublicKey(MlKemKey* key, const unsigned char* in, + word32 len) +{ + int ret = 0; + word32 pubLen = 0; + + /* Validate parameters. */ + if ((key == NULL) || (in == NULL)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + ret = wc_MlKemKey_PublicKeySize(key, &pubLen); + } + + /* Ensure the data is the correct length for the key type. */ + if ((ret == 0) && (len != pubLen)) { + ret = BUFFER_E; + } + + if (ret == 0) { + XMEMCPY(key->pub, in, pubLen); + } + + return ret; +} + +/** + * Encode the private key. + * + * We stored it as a blob so we can just copy it over. + * + * @param [in] key Kyber key object. + * @param [out] out Buffer to hold data. + * @param [in] len Size of buffer in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or out is NULL or private/public key not + * available. + * @return NOT_COMPILED_IN when key type is not supported. + */ +int wc_MlKemKey_EncodePrivateKey(MlKemKey* key, unsigned char* out, word32 len) +{ + int ret = 0; + unsigned int privLen = 0; + + if ((key == NULL) || (out == NULL)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + ret = wc_MlKemKey_PrivateKeySize(key, &privLen); + } + + /* Check buffer is big enough for encoding. */ + if ((ret == 0) && (len != privLen)) { + ret = BUFFER_E; + } + + if (ret == 0) { + XMEMCPY(out, key->priv, privLen); + } + + return ret; +} + +/** + * Encode the public key. + * + * We stored it as a blob so we can just copy it over. + * + * @param [in] key Kyber key object. + * @param [out] out Buffer to hold data. + * @param [in] len Size of buffer in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or out is NULL or public key not available. + * @return NOT_COMPILED_IN when key type is not supported. + */ +int wc_MlKemKey_EncodePublicKey(MlKemKey* key, unsigned char* out, word32 len) +{ + int ret = 0; + unsigned int pubLen = 0; + + if ((key == NULL) || (out == NULL)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + ret = wc_MlKemKey_PublicKeySize(key, &pubLen); + } + + /* Check buffer is big enough for encoding. */ + if ((ret == 0) && (len != pubLen)) { + ret = BUFFER_E; + } + + if (ret == 0) { + XMEMCPY(out, key->pub, pubLen); + } + + return ret; +} + +#endif /* WOLFSSL_HAVE_MLKEM && !WOLFSSL_WC_MLKEM */ diff --git a/src/wolfcrypt/src/ext_xmss.c b/src/wolfcrypt/src/ext_xmss.c index 938d513..48912a3 100644 --- a/src/wolfcrypt/src/ext_xmss.c +++ b/src/wolfcrypt/src/ext_xmss.c @@ -1,6 +1,6 @@ /* ext_xmss.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,13 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif +#include -#include -#include -#include #include #if defined(WOLFSSL_HAVE_XMSS) && defined(HAVE_LIBXMSS) diff --git a/src/wolfcrypt/src/falcon.c b/src/wolfcrypt/src/falcon.c index b1aabb1..6562a80 100644 --- a/src/wolfcrypt/src/falcon.c +++ b/src/wolfcrypt/src/falcon.c @@ -1,6 +1,6 @@ /* falcon.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,25 +19,19 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -/* Based on ed448.c and Reworked for Falcon by Anthony Hu. */ +#include -#ifdef HAVE_CONFIG_H - #include -#endif +/* Based on ed448.c and Reworked for Falcon by Anthony Hu. */ -/* in case user set HAVE_PQC there */ -#include +#if defined(HAVE_PQC) && defined(HAVE_FALCON) #include -#if defined(HAVE_PQC) && defined(HAVE_FALCON) - #ifdef HAVE_LIBOQS #include #endif #include -#include #ifdef NO_INLINE #include #else @@ -62,6 +56,10 @@ int wc_falcon_sign_msg(const byte* in, word32 inLen, falcon_key* key, WC_RNG* rng) { int ret = 0; +#ifdef HAVE_LIBOQS + OQS_SIG *oqssig = NULL; + size_t localOutLen = 0; +#endif /* sanity check on arguments */ if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL)) { @@ -73,8 +71,8 @@ int wc_falcon_sign_msg(const byte* in, word32 inLen, if (key->devId != INVALID_DEVID) #endif { - ret = wc_CryptoCb_PqcSign(in, inLen, out, outLen, rng, - WC_PQC_SIG_TYPE_FALCON, key); + ret = wc_CryptoCb_PqcSign(in, inLen, out, outLen, NULL, 0, + WC_HASH_TYPE_NONE, rng, WC_PQC_SIG_TYPE_FALCON, key); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) return ret; /* fall-through when unavailable */ @@ -83,9 +81,6 @@ int wc_falcon_sign_msg(const byte* in, word32 inLen, #endif #ifdef HAVE_LIBOQS - OQS_SIG *oqssig = NULL; - size_t localOutLen = 0; - if ((ret == 0) && (!key->prvKeySet)) { ret = BAD_FUNC_ARG; } @@ -161,6 +156,9 @@ int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg, word32 msgLen, int* res, falcon_key* key) { int ret = 0; +#ifdef HAVE_LIBOQS + OQS_SIG *oqssig = NULL; +#endif if (key == NULL || sig == NULL || msg == NULL || res == NULL) { return BAD_FUNC_ARG; @@ -171,8 +169,8 @@ int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg, if (key->devId != INVALID_DEVID) #endif { - ret = wc_CryptoCb_PqcVerify(sig, sigLen, msg, msgLen, res, - WC_PQC_SIG_TYPE_FALCON, key); + ret = wc_CryptoCb_PqcVerify(sig, sigLen, msg, msgLen, NULL, 0, + WC_HASH_TYPE_NONE, res, WC_PQC_SIG_TYPE_FALCON, key); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) return ret; /* fall-through when unavailable */ @@ -181,8 +179,6 @@ int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg, #endif #ifdef HAVE_LIBOQS - OQS_SIG *oqssig = NULL; - if ((ret == 0) && (!key->pubKeySet)) { ret = BAD_FUNC_ARG; } @@ -708,12 +704,12 @@ int wc_falcon_export_key(falcon_key* key, byte* priv, word32 *privSz, */ int wc_falcon_check_key(falcon_key* key) { + int ret = 0; + if (key == NULL) { return BAD_FUNC_ARG; } - int ret = 0; - /* The public key is also decoded and stored within the private key buffer * behind the private key. Hence, we can compare both stored public keys. */ if (key->level == 1) { diff --git a/src/wolfcrypt/src/fe_448.c b/src/wolfcrypt/src/fe_448.c index bbf31f6..8cf0245 100644 --- a/src/wolfcrypt/src/fe_448.c +++ b/src/wolfcrypt/src/fe_448.c @@ -1,6 +1,6 @@ /* fe_448.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -24,11 +24,7 @@ * Reworked for curve448 by Sean Parkinson. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if defined(HAVE_CURVE448) || defined(HAVE_ED448) @@ -1437,56 +1433,56 @@ void fe448_to_bytes(unsigned char* b, const sword32* a) b[ 0] = (byte)(in0 >> 0); b[ 1] = (byte)(in0 >> 8); b[ 2] = (byte)(in0 >> 16); - b[ 3] = (byte)(in0 >> 24) + (byte)((in1 >> 0) << 4); + b[ 3] = (byte)((byte)(in0 >> 24) + (byte)((in1 >> 0) << 4)); b[ 4] = (byte)(in1 >> 4); b[ 5] = (byte)(in1 >> 12); b[ 6] = (byte)(in1 >> 20); b[ 7] = (byte)(in2 >> 0); b[ 8] = (byte)(in2 >> 8); b[ 9] = (byte)(in2 >> 16); - b[10] = (byte)(in2 >> 24) + (byte)((in3 >> 0) << 4); + b[10] = (byte)((byte)(in2 >> 24) + (byte)((in3 >> 0) << 4)); b[11] = (byte)(in3 >> 4); b[12] = (byte)(in3 >> 12); b[13] = (byte)(in3 >> 20); b[14] = (byte)(in4 >> 0); b[15] = (byte)(in4 >> 8); b[16] = (byte)(in4 >> 16); - b[17] = (byte)(in4 >> 24) + (byte)((in5 >> 0) << 4); + b[17] = (byte)((byte)(in4 >> 24) + (byte)((in5 >> 0) << 4)); b[18] = (byte)(in5 >> 4); b[19] = (byte)(in5 >> 12); b[20] = (byte)(in5 >> 20); b[21] = (byte)(in6 >> 0); b[22] = (byte)(in6 >> 8); b[23] = (byte)(in6 >> 16); - b[24] = (byte)(in6 >> 24) + (byte)((in7 >> 0) << 4); + b[24] = (byte)((byte)(in6 >> 24) + (byte)((in7 >> 0) << 4)); b[25] = (byte)(in7 >> 4); b[26] = (byte)(in7 >> 12); b[27] = (byte)(in7 >> 20); b[28] = (byte)(in8 >> 0); b[29] = (byte)(in8 >> 8); b[30] = (byte)(in8 >> 16); - b[31] = (byte)(in8 >> 24) + (byte)((in9 >> 0) << 4); + b[31] = (byte)((byte)(in8 >> 24) + (byte)((in9 >> 0) << 4)); b[32] = (byte)(in9 >> 4); b[33] = (byte)(in9 >> 12); b[34] = (byte)(in9 >> 20); b[35] = (byte)(in10 >> 0); b[36] = (byte)(in10 >> 8); b[37] = (byte)(in10 >> 16); - b[38] = (byte)(in10 >> 24) + (byte)((in11 >> 0) << 4); + b[38] = (byte)((byte)(in10 >> 24) + (byte)((in11 >> 0) << 4)); b[39] = (byte)(in11 >> 4); b[40] = (byte)(in11 >> 12); b[41] = (byte)(in11 >> 20); b[42] = (byte)(in12 >> 0); b[43] = (byte)(in12 >> 8); b[44] = (byte)(in12 >> 16); - b[45] = (byte)(in12 >> 24) + (byte)((in13 >> 0) << 4); + b[45] = (byte)((byte)(in12 >> 24) + (byte)((in13 >> 0) << 4)); b[46] = (byte)(in13 >> 4); b[47] = (byte)(in13 >> 12); b[48] = (byte)(in13 >> 20); b[49] = (byte)(in14 >> 0); b[50] = (byte)(in14 >> 8); b[51] = (byte)(in14 >> 16); - b[52] = (byte)(in14 >> 24) + (byte)((in15 >> 0) << 4); + b[52] = (byte)((byte)(in14 >> 24) + (byte)((in15 >> 0) << 4)); b[53] = (byte)(in15 >> 4); b[54] = (byte)(in15 >> 12); b[55] = (byte)(in15 >> 20); diff --git a/src/wolfcrypt/src/fe_low_mem.c b/src/wolfcrypt/src/fe_low_mem.c index ad10a0e..febc123 100644 --- a/src/wolfcrypt/src/fe_low_mem.c +++ b/src/wolfcrypt/src/fe_low_mem.c @@ -1,6 +1,6 @@ /* fe_low_mem.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,15 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include /* Based from Daniel Beer's public domain work. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - #if defined(HAVE_CURVE25519) || defined(HAVE_ED25519) #if defined(CURVE25519_SMALL) || defined(ED25519_SMALL) /* use slower code that takes less memory */ diff --git a/src/wolfcrypt/src/fe_operations.c b/src/wolfcrypt/src/fe_operations.c index 2910151..135d703 100644 --- a/src/wolfcrypt/src/fe_operations.c +++ b/src/wolfcrypt/src/fe_operations.c @@ -1,6 +1,6 @@ /* fe_operations.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,15 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include /* Based On Daniel J Bernstein's curve25519 Public Domain ref10 work. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - #if defined(HAVE_CURVE25519) || defined(HAVE_ED25519) #if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL) /* run when not defined to use small memory math */ @@ -128,11 +123,9 @@ void fe_init(void) #if defined(HAVE_CURVE25519) && !defined(CURVE25519_SMALL) && \ !defined(FREESCALE_LTC_ECC) +#ifndef WOLFSSL_CURVE25519_BLINDING int curve25519(byte* q, const byte* n, const byte* p) { -#if 0 - unsigned char e[32]; -#endif fe x1 = {0}; fe x2 = {0}; fe z2 = {0}; @@ -143,17 +136,6 @@ int curve25519(byte* q, const byte* n, const byte* p) int pos = 0; unsigned int swap = 0; - /* Clamp already done during key generation and import */ -#if 0 - { - unsigned int i; - for (i = 0;i < 32;++i) e[i] = n[i]; - e[0] &= 248; - e[31] &= 127; - e[31] |= 64; - } -#endif - fe_frombytes(x1,p); fe_1(x2); fe_0(z2); @@ -163,11 +145,7 @@ int curve25519(byte* q, const byte* n, const byte* p) swap = 0; for (pos = 254;pos >= 0;--pos) { unsigned int b; -#if 0 - b = e[pos / 8] >> (pos & 7); -#else - b = n[pos / 8] >> (pos & 7); -#endif + b = (unsigned int)(n[pos / 8]) >> (pos & 7); b &= 1; swap ^= b; fe_cswap(x2,x3,(int)swap); @@ -203,6 +181,74 @@ int curve25519(byte* q, const byte* n, const byte* p) return 0; } +#else +int curve25519_blind(byte* q, const byte* n, const byte* mask, const byte* p, + const byte* rz) +{ + fe x1 = {0}; + fe x2 = {0}; + fe z2 = {0}; + fe x3 = {0}; + fe z3 = {0}; + fe tmp0 = {0}; + fe tmp1 = {0}; + int pos = 0; + unsigned int b; + + fe_frombytes(x1,p); + fe_1(x2); + fe_0(z2); + fe_copy(x3,x1); + fe_frombytes(z3, rz); + fe_mul(x3, x3, z3); + + /* mask_bits[252] */ + b = mask[31] >> 7; + b &= 1; + fe_cswap(x2,x3,(int)b); + fe_cswap(z2,z3,(int)b); + for (pos = 255;pos >= 1;--pos) { + b = n[pos / 8] >> (pos & 7); + b &= 1; + fe_cswap(x2,x3,(int)b); + fe_cswap(z2,z3,(int)b); + + /* montgomery */ + fe_sub(tmp0,x3,z3); + fe_sub(tmp1,x2,z2); + fe_add(x2,x2,z2); + fe_add(z2,x3,z3); + fe_mul(z3,tmp0,x2); + fe_mul(z2,z2,tmp1); + fe_sq(tmp0,tmp1); + fe_sq(tmp1,x2); + fe_add(x3,z3,z2); + fe_sub(z2,z3,z2); + fe_mul(x2,tmp1,tmp0); + fe_sub(tmp1,tmp1,tmp0); + fe_sq(z2,z2); + fe_mul121666(z3,tmp1); + fe_sq(x3,x3); + fe_add(tmp0,tmp0,z3); + fe_mul(z3,x1,z2); + fe_mul(z2,tmp1,tmp0); + + b = mask[(pos-1) / 8] >> ((pos-1) & 7); + b &= 1; + fe_cswap(x2,x3,(int)b); + fe_cswap(z2,z3,(int)b); + } + b = n[0] & 1; + fe_cswap(x2,x3,(int)b); + fe_cswap(z2,z3,(int)b); + + fe_invert(z2,z2); + fe_mul(x2,x2,z2); + fe_tobytes(q,x2); + + return 0; +} +#endif #endif /* HAVE_CURVE25519 && !CURVE25519_SMALL && !FREESCALE_LTC_ECC */ diff --git a/src/wolfcrypt/src/ge_448.c b/src/wolfcrypt/src/ge_448.c index 81f9c57..a09a92d 100644 --- a/src/wolfcrypt/src/ge_448.c +++ b/src/wolfcrypt/src/ge_448.c @@ -1,6 +1,6 @@ /* ge_448.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -24,17 +24,12 @@ * Reworked for ed448 by Sean Parkinson. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef HAVE_ED448 #include #include -#include #ifdef NO_INLINE #include #else @@ -369,7 +364,7 @@ int ge448_scalarmult_base(ge448_p2* h, const byte* a) return 0; } -/* Perform a scalar multplication of the base point and public point. +/* Perform a scalar multiplication of the base point and public point. * r = a * p + b * base * Uses a sliding window of 5 bits. * Not constant time. @@ -919,70 +914,70 @@ void sc448_muladd(byte* r, const byte* a, const byte* b, const byte* d) | (word64)((sword64) (d[55]) << 48); /* a * b + d */ - t[ 0] = (word128)dd[ 0] + (word128)((sword128)ad[ 0] * bd[ 0]); - t[ 1] = (word128)dd[ 1] + (word128)((sword128)ad[ 0] * bd[ 1] - + (sword128)ad[ 1] * bd[ 0]); - t[ 2] = (word128)dd[ 2] + (word128)((sword128)ad[ 0] * bd[ 2] - + (sword128)ad[ 1] * bd[ 1] - + (sword128)ad[ 2] * bd[ 0]); - t[ 3] = (word128)dd[ 3] + (word128)((sword128)ad[ 0] * bd[ 3] - + (sword128)ad[ 1] * bd[ 2] - + (sword128)ad[ 2] * bd[ 1] - + (sword128)ad[ 3] * bd[ 0]); - t[ 4] = (word128)dd[ 4] + (word128)((sword128)ad[ 0] * bd[ 4] - + (sword128)ad[ 1] * bd[ 3] - + (sword128)ad[ 2] * bd[ 2] - + (sword128)ad[ 3] * bd[ 1] - + (sword128)ad[ 4] * bd[ 0]); - t[ 5] = (word128)dd[ 5] + (word128)((sword128)ad[ 0] * bd[ 5] - + (sword128)ad[ 1] * bd[ 4] - + (sword128)ad[ 2] * bd[ 3] - + (sword128)ad[ 3] * bd[ 2] - + (sword128)ad[ 4] * bd[ 1] - + (sword128)ad[ 5] * bd[ 0]); - t[ 6] = (word128)dd[ 6] + (word128)((sword128)ad[ 0] * bd[ 6] - + (sword128)ad[ 1] * bd[ 5] - + (sword128)ad[ 2] * bd[ 4] - + (sword128)ad[ 3] * bd[ 3] - + (sword128)ad[ 4] * bd[ 2] - + (sword128)ad[ 5] * bd[ 1] - + (sword128)ad[ 6] * bd[ 0]); - t[ 7] = (word128)dd[ 7] + (word128)((sword128)ad[ 0] * bd[ 7] - + (sword128)ad[ 1] * bd[ 6] - + (sword128)ad[ 2] * bd[ 5] - + (sword128)ad[ 3] * bd[ 4] - + (sword128)ad[ 4] * bd[ 3] - + (sword128)ad[ 5] * bd[ 2] - + (sword128)ad[ 6] * bd[ 1] - + (sword128)ad[ 7] * bd[ 0]); - t[ 8] = (word128) ((sword128)ad[ 1] * bd[ 7] - + (sword128)ad[ 2] * bd[ 6] - + (sword128)ad[ 3] * bd[ 5] - + (sword128)ad[ 4] * bd[ 4] - + (sword128)ad[ 5] * bd[ 3] - + (sword128)ad[ 6] * bd[ 2] - + (sword128)ad[ 7] * bd[ 1]); - t[ 9] = (word128) ((sword128)ad[ 2] * bd[ 7] - + (sword128)ad[ 3] * bd[ 6] - + (sword128)ad[ 4] * bd[ 5] - + (sword128)ad[ 5] * bd[ 4] - + (sword128)ad[ 6] * bd[ 3] - + (sword128)ad[ 7] * bd[ 2]); - t[10] = (word128) ((sword128)ad[ 3] * bd[ 7] - + (sword128)ad[ 4] * bd[ 6] - + (sword128)ad[ 5] * bd[ 5] - + (sword128)ad[ 6] * bd[ 4] - + (sword128)ad[ 7] * bd[ 3]); - t[11] = (word128) ((sword128)ad[ 4] * bd[ 7] - + (sword128)ad[ 5] * bd[ 6] - + (sword128)ad[ 6] * bd[ 5] - + (sword128)ad[ 7] * bd[ 4]); - t[12] = (word128) ((sword128)ad[ 5] * bd[ 7] - + (sword128)ad[ 6] * bd[ 6] - + (sword128)ad[ 7] * bd[ 5]); - t[13] = (word128) ((sword128)ad[ 6] * bd[ 7] - + (sword128)ad[ 7] * bd[ 6]); - t[14] = (word128) (sword128)ad[ 7] * bd[ 7]; + t[ 0] = (word128)(dd[ 0] + (word128)((sword128)ad[ 0] * bd[ 0])); + t[ 1] = (word128)(dd[ 1] + (word128)((sword128)ad[ 0] * bd[ 1] + + (sword128)ad[ 1] * bd[ 0])); + t[ 2] = (word128)(dd[ 2] + (word128)((sword128)ad[ 0] * bd[ 2] + + (sword128)ad[ 1] * bd[ 1] + + (sword128)ad[ 2] * bd[ 0])); + t[ 3] = (word128)(dd[ 3] + (word128)((sword128)ad[ 0] * bd[ 3] + + (sword128)ad[ 1] * bd[ 2] + + (sword128)ad[ 2] * bd[ 1] + + (sword128)ad[ 3] * bd[ 0])); + t[ 4] = (word128)(dd[ 4] + (word128)((sword128)ad[ 0] * bd[ 4] + + (sword128)ad[ 1] * bd[ 3] + + (sword128)ad[ 2] * bd[ 2] + + (sword128)ad[ 3] * bd[ 1] + + (sword128)ad[ 4] * bd[ 0])); + t[ 5] = (word128)(dd[ 5] + (word128)((sword128)ad[ 0] * bd[ 5] + + (sword128)ad[ 1] * bd[ 4] + + (sword128)ad[ 2] * bd[ 3] + + (sword128)ad[ 3] * bd[ 2] + + (sword128)ad[ 4] * bd[ 1] + + (sword128)ad[ 5] * bd[ 0])); + t[ 6] = (word128)(dd[ 6] + (word128)((sword128)ad[ 0] * bd[ 6] + + (sword128)ad[ 1] * bd[ 5] + + (sword128)ad[ 2] * bd[ 4] + + (sword128)ad[ 3] * bd[ 3] + + (sword128)ad[ 4] * bd[ 2] + + (sword128)ad[ 5] * bd[ 1] + + (sword128)ad[ 6] * bd[ 0])); + t[ 7] = (word128)(dd[ 7] + (word128)((sword128)ad[ 0] * bd[ 7] + + (sword128)ad[ 1] * bd[ 6] + + (sword128)ad[ 2] * bd[ 5] + + (sword128)ad[ 3] * bd[ 4] + + (sword128)ad[ 4] * bd[ 3] + + (sword128)ad[ 5] * bd[ 2] + + (sword128)ad[ 6] * bd[ 1] + + (sword128)ad[ 7] * bd[ 0])); + t[ 8] = (word128)( (sword128)ad[ 1] * bd[ 7] + + (sword128)ad[ 2] * bd[ 6] + + (sword128)ad[ 3] * bd[ 5] + + (sword128)ad[ 4] * bd[ 4] + + (sword128)ad[ 5] * bd[ 3] + + (sword128)ad[ 6] * bd[ 2] + + (sword128)ad[ 7] * bd[ 1]); + t[ 9] = (word128)( (sword128)ad[ 2] * bd[ 7] + + (sword128)ad[ 3] * bd[ 6] + + (sword128)ad[ 4] * bd[ 5] + + (sword128)ad[ 5] * bd[ 4] + + (sword128)ad[ 6] * bd[ 3] + + (sword128)ad[ 7] * bd[ 2]); + t[10] = (word128)( (sword128)ad[ 3] * bd[ 7] + + (sword128)ad[ 4] * bd[ 6] + + (sword128)ad[ 5] * bd[ 5] + + (sword128)ad[ 6] * bd[ 4] + + (sword128)ad[ 7] * bd[ 3]); + t[11] = (word128)( (sword128)ad[ 4] * bd[ 7] + + (sword128)ad[ 5] * bd[ 6] + + (sword128)ad[ 6] * bd[ 5] + + (sword128)ad[ 7] * bd[ 4]); + t[12] = (word128)( (sword128)ad[ 5] * bd[ 7] + + (sword128)ad[ 6] * bd[ 6] + + (sword128)ad[ 7] * bd[ 5]); + t[13] = (word128)( (sword128)ad[ 6] * bd[ 7] + + (sword128)ad[ 7] * bd[ 6]); + t[14] = (word128)( (sword128)ad[ 7] * bd[ 7]); t[15] = 0; /* Mod curve order */ @@ -5143,136 +5138,169 @@ void sc448_reduce(byte* b) word32 o; /* Load from bytes */ - t[ 0] = (((sword32)((b[ 0] ) >> 0)) << 0) + t[ 0] = (word64)( + (((sword32)((b[ 0] ) >> 0)) << 0) | (((sword32)((b[ 1] ) >> 0)) << 8) | (((sword32)((b[ 2] ) >> 0)) << 16) - | ((((sword32)((b[ 3] & 0xf )) >> 0)) << 24); - t[ 1] = (((sword32)((b[ 3] ) >> 4)) << 0) + | ((((sword32)((b[ 3] & 0xf )) >> 0)) << 24)); + t[ 1] = (word64)( + (((sword32)((b[ 3] ) >> 4)) << 0) | (((sword32)((b[ 4] ) >> 0)) << 4) | (((sword32)((b[ 5] ) >> 0)) << 12) - | (((sword32)((b[ 6] ) >> 0)) << 20); - t[ 2] = (((sword32)((b[ 7] ) >> 0)) << 0) + | (((sword32)((b[ 6] ) >> 0)) << 20)); + t[ 2] = (word64)( + (((sword32)((b[ 7] ) >> 0)) << 0) | (((sword32)((b[ 8] ) >> 0)) << 8) | (((sword32)((b[ 9] ) >> 0)) << 16) - | ((((sword32)((b[10] & 0xf )) >> 0)) << 24); - t[ 3] = (((sword32)((b[10] ) >> 4)) << 0) + | ((((sword32)((b[10] & 0xf )) >> 0)) << 24)); + t[ 3] = (word64)( + (((sword32)((b[10] ) >> 4)) << 0) | (((sword32)((b[11] ) >> 0)) << 4) | (((sword32)((b[12] ) >> 0)) << 12) - | (((sword32)((b[13] ) >> 0)) << 20); - t[ 4] = (((sword32)((b[14] ) >> 0)) << 0) + | (((sword32)((b[13] ) >> 0)) << 20)); + t[ 4] = (word64)( + (((sword32)((b[14] ) >> 0)) << 0) | (((sword32)((b[15] ) >> 0)) << 8) | (((sword32)((b[16] ) >> 0)) << 16) - | ((((sword32)((b[17] & 0xf )) >> 0)) << 24); - t[ 5] = (((sword32)((b[17] ) >> 4)) << 0) + | ((((sword32)((b[17] & 0xf )) >> 0)) << 24)); + t[ 5] = (word64)( + (((sword32)((b[17] ) >> 4)) << 0) | (((sword32)((b[18] ) >> 0)) << 4) | (((sword32)((b[19] ) >> 0)) << 12) - | (((sword32)((b[20] ) >> 0)) << 20); - t[ 6] = (((sword32)((b[21] ) >> 0)) << 0) + | (((sword32)((b[20] ) >> 0)) << 20)); + t[ 6] = (word64)( + (((sword32)((b[21] ) >> 0)) << 0) | (((sword32)((b[22] ) >> 0)) << 8) | (((sword32)((b[23] ) >> 0)) << 16) - | ((((sword32)((b[24] & 0xf )) >> 0)) << 24); - t[ 7] = (((sword32)((b[24] ) >> 4)) << 0) + | ((((sword32)((b[24] & 0xf )) >> 0)) << 24)); + t[ 7] = (word64)( + (((sword32)((b[24] ) >> 4)) << 0) | (((sword32)((b[25] ) >> 0)) << 4) | (((sword32)((b[26] ) >> 0)) << 12) - | (((sword32)((b[27] ) >> 0)) << 20); - t[ 8] = (((sword32)((b[28] ) >> 0)) << 0) + | (((sword32)((b[27] ) >> 0)) << 20)); + t[ 8] = (word64)( + (((sword32)((b[28] ) >> 0)) << 0) | (((sword32)((b[29] ) >> 0)) << 8) | (((sword32)((b[30] ) >> 0)) << 16) - | ((((sword32)((b[31] & 0xf )) >> 0)) << 24); - t[ 9] = (((sword32)((b[31] ) >> 4)) << 0) + | ((((sword32)((b[31] & 0xf )) >> 0)) << 24)); + t[ 9] = (word64)( + (((sword32)((b[31] ) >> 4)) << 0) | (((sword32)((b[32] ) >> 0)) << 4) | (((sword32)((b[33] ) >> 0)) << 12) - | (((sword32)((b[34] ) >> 0)) << 20); - t[10] = (((sword32)((b[35] ) >> 0)) << 0) + | (((sword32)((b[34] ) >> 0)) << 20)); + t[10] = (word64)( + (((sword32)((b[35] ) >> 0)) << 0) | (((sword32)((b[36] ) >> 0)) << 8) | (((sword32)((b[37] ) >> 0)) << 16) - | ((((sword32)((b[38] & 0xf )) >> 0)) << 24); - t[11] = (((sword32)((b[38] ) >> 4)) << 0) + | ((((sword32)((b[38] & 0xf )) >> 0)) << 24)); + t[11] = (word64)( + (((sword32)((b[38] ) >> 4)) << 0) | (((sword32)((b[39] ) >> 0)) << 4) | (((sword32)((b[40] ) >> 0)) << 12) - | (((sword32)((b[41] ) >> 0)) << 20); - t[12] = (((sword32)((b[42] ) >> 0)) << 0) + | (((sword32)((b[41] ) >> 0)) << 20)); + t[12] = (word64)( + (((sword32)((b[42] ) >> 0)) << 0) | (((sword32)((b[43] ) >> 0)) << 8) | (((sword32)((b[44] ) >> 0)) << 16) - | ((((sword32)((b[45] & 0xf )) >> 0)) << 24); - t[13] = (((sword32)((b[45] ) >> 4)) << 0) + | ((((sword32)((b[45] & 0xf )) >> 0)) << 24)); + t[13] = (word64)( + (((sword32)((b[45] ) >> 4)) << 0) | (((sword32)((b[46] ) >> 0)) << 4) | (((sword32)((b[47] ) >> 0)) << 12) - | (((sword32)((b[48] ) >> 0)) << 20); - t[14] = (((sword32)((b[49] ) >> 0)) << 0) + | (((sword32)((b[48] ) >> 0)) << 20)); + t[14] = (word64)( + (((sword32)((b[49] ) >> 0)) << 0) | (((sword32)((b[50] ) >> 0)) << 8) | (((sword32)((b[51] ) >> 0)) << 16) - | ((((sword32)((b[52] & 0xf )) >> 0)) << 24); - t[15] = (((sword32)((b[52] ) >> 4)) << 0) + | ((((sword32)((b[52] & 0xf )) >> 0)) << 24)); + t[15] = (word64)( + (((sword32)((b[52] ) >> 4)) << 0) | (((sword32)((b[53] ) >> 0)) << 4) | (((sword32)((b[54] ) >> 0)) << 12) - | (((sword32)((b[55] ) >> 0)) << 20); - t[16] = (((sword32)((b[56] ) >> 0)) << 0) + | (((sword32)((b[55] ) >> 0)) << 20)); + t[16] = (word64)( + (((sword32)((b[56] ) >> 0)) << 0) | (((sword32)((b[57] ) >> 0)) << 8) | (((sword32)((b[58] ) >> 0)) << 16) - | ((((sword32)((b[59] & 0xf )) >> 0)) << 24); - t[17] = (((sword32)((b[59] ) >> 4)) << 0) + | ((((sword32)((b[59] & 0xf )) >> 0)) << 24)); + t[17] = (word64)( + (((sword32)((b[59] ) >> 4)) << 0) | (((sword32)((b[60] ) >> 0)) << 4) | (((sword32)((b[61] ) >> 0)) << 12) - | (((sword32)((b[62] ) >> 0)) << 20); - t[18] = (((sword32)((b[63] ) >> 0)) << 0) + | (((sword32)((b[62] ) >> 0)) << 20)); + t[18] = (word64)( + (((sword32)((b[63] ) >> 0)) << 0) | (((sword32)((b[64] ) >> 0)) << 8) | (((sword32)((b[65] ) >> 0)) << 16) - | ((((sword32)((b[66] & 0xf )) >> 0)) << 24); - t[19] = (((sword32)((b[66] ) >> 4)) << 0) + | ((((sword32)((b[66] & 0xf )) >> 0)) << 24)); + t[19] = (word64)( + (((sword32)((b[66] ) >> 4)) << 0) | (((sword32)((b[67] ) >> 0)) << 4) | (((sword32)((b[68] ) >> 0)) << 12) - | (((sword32)((b[69] ) >> 0)) << 20); - t[20] = (((sword32)((b[70] ) >> 0)) << 0) + | (((sword32)((b[69] ) >> 0)) << 20)); + t[20] = (word64)( + (((sword32)((b[70] ) >> 0)) << 0) | (((sword32)((b[71] ) >> 0)) << 8) | (((sword32)((b[72] ) >> 0)) << 16) - | ((((sword32)((b[73] & 0xf )) >> 0)) << 24); - t[21] = (((sword32)((b[73] ) >> 4)) << 0) + | ((((sword32)((b[73] & 0xf )) >> 0)) << 24)); + t[21] = (word64)( + (((sword32)((b[73] ) >> 4)) << 0) | (((sword32)((b[74] ) >> 0)) << 4) | (((sword32)((b[75] ) >> 0)) << 12) - | (((sword32)((b[76] ) >> 0)) << 20); - t[22] = (((sword32)((b[77] ) >> 0)) << 0) + | (((sword32)((b[76] ) >> 0)) << 20)); + t[22] = (word64)( + (((sword32)((b[77] ) >> 0)) << 0) | (((sword32)((b[78] ) >> 0)) << 8) | (((sword32)((b[79] ) >> 0)) << 16) - | ((((sword32)((b[80] & 0xf )) >> 0)) << 24); - t[23] = (((sword32)((b[80] ) >> 4)) << 0) + | ((((sword32)((b[80] & 0xf )) >> 0)) << 24)); + t[23] = (word64)( + (((sword32)((b[80] ) >> 4)) << 0) | (((sword32)((b[81] ) >> 0)) << 4) | (((sword32)((b[82] ) >> 0)) << 12) - | (((sword32)((b[83] ) >> 0)) << 20); - t[24] = (((sword32)((b[84] ) >> 0)) << 0) + | (((sword32)((b[83] ) >> 0)) << 20)); + t[24] = (word64)( + (((sword32)((b[84] ) >> 0)) << 0) | (((sword32)((b[85] ) >> 0)) << 8) | (((sword32)((b[86] ) >> 0)) << 16) - | ((((sword32)((b[87] & 0xf )) >> 0)) << 24); - t[25] = (((sword32)((b[87] ) >> 4)) << 0) + | ((((sword32)((b[87] & 0xf )) >> 0)) << 24)); + t[25] = (word64)( + (((sword32)((b[87] ) >> 4)) << 0) | (((sword32)((b[88] ) >> 0)) << 4) | (((sword32)((b[89] ) >> 0)) << 12) - | (((sword32)((b[90] ) >> 0)) << 20); - t[26] = (((sword32)((b[91] ) >> 0)) << 0) + | (((sword32)((b[90] ) >> 0)) << 20)); + t[26] = (word64)( + (((sword32)((b[91] ) >> 0)) << 0) | (((sword32)((b[92] ) >> 0)) << 8) | (((sword32)((b[93] ) >> 0)) << 16) - | ((((sword32)((b[94] & 0xf )) >> 0)) << 24); - t[27] = (((sword32)((b[94] ) >> 4)) << 0) + | ((((sword32)((b[94] & 0xf )) >> 0)) << 24)); + t[27] = (word64)( + (((sword32)((b[94] ) >> 4)) << 0) | (((sword32)((b[95] ) >> 0)) << 4) | (((sword32)((b[96] ) >> 0)) << 12) - | (((sword32)((b[97] ) >> 0)) << 20); - t[28] = (((sword32)((b[98] ) >> 0)) << 0) + | (((sword32)((b[97] ) >> 0)) << 20)); + t[28] = (word64)( + (((sword32)((b[98] ) >> 0)) << 0) | (((sword32)((b[99] ) >> 0)) << 8) | (((sword32)((b[100] ) >> 0)) << 16) - | ((((sword32)((b[101] & 0xf )) >> 0)) << 24); - t[29] = (((sword32)((b[101] ) >> 4)) << 0) + | ((((sword32)((b[101] & 0xf )) >> 0)) << 24)); + t[29] = (word64)( + (((sword32)((b[101] ) >> 4)) << 0) | (((sword32)((b[102] ) >> 0)) << 4) | (((sword32)((b[103] ) >> 0)) << 12) - | (((sword32)((b[104] ) >> 0)) << 20); - t[30] = (((sword32)((b[105] ) >> 0)) << 0) + | (((sword32)((b[104] ) >> 0)) << 20)); + t[30] = (word64)( + (((sword32)((b[105] ) >> 0)) << 0) | (((sword32)((b[106] ) >> 0)) << 8) | (((sword32)((b[107] ) >> 0)) << 16) - | ((((sword32)((b[108] & 0xf )) >> 0)) << 24); - t[31] = (((sword32)((b[108] ) >> 4)) << 0) + | ((((sword32)((b[108] & 0xf )) >> 0)) << 24)); + t[31] = (word64)( + (((sword32)((b[108] ) >> 4)) << 0) | (((sword32)((b[109] ) >> 0)) << 4) | (((sword32)((b[110] ) >> 0)) << 12) - | (((sword32)((b[111] ) >> 0)) << 20); - t[32] = (((sword32)((b[112] ) >> 0)) << 0) - | (((sword32)((b[113] ) >> 0)) << 8); + | (((sword32)((b[111] ) >> 0)) << 20)); + t[32] = (word64)( + (((sword32)((b[112] ) >> 0)) << 0) + | (((sword32)((b[113] ) >> 0)) << 8)); /* Mod curve order */ /* 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d */ @@ -5514,56 +5542,56 @@ void sc448_reduce(byte* b) b[ 0] = (byte)(d[0 ] >> 0); b[ 1] = (byte)(d[0 ] >> 8); b[ 2] = (byte)(d[0 ] >> 16); - b[ 3] = (byte)(d[0 ] >> 24) + (byte)((d[1 ] >> 0) << 4); + b[ 3] = (byte)((byte)(d[0 ] >> 24) + (byte)((d[1 ] >> 0) << 4)); b[ 4] = (byte)(d[1 ] >> 4); b[ 5] = (byte)(d[1 ] >> 12); b[ 6] = (byte)(d[1 ] >> 20); b[ 7] = (byte)(d[2 ] >> 0); b[ 8] = (byte)(d[2 ] >> 8); b[ 9] = (byte)(d[2 ] >> 16); - b[10] = (byte)(d[2 ] >> 24) + (byte)((d[3 ] >> 0) << 4); + b[10] = (byte)((byte)(d[2 ] >> 24) + (byte)((d[3 ] >> 0) << 4)); b[11] = (byte)(d[3 ] >> 4); b[12] = (byte)(d[3 ] >> 12); b[13] = (byte)(d[3 ] >> 20); b[14] = (byte)(d[4 ] >> 0); b[15] = (byte)(d[4 ] >> 8); b[16] = (byte)(d[4 ] >> 16); - b[17] = (byte)(d[4 ] >> 24) + (byte)((d[5 ] >> 0) << 4); + b[17] = (byte)((byte)(d[4 ] >> 24) + (byte)((d[5 ] >> 0) << 4)); b[18] = (byte)(d[5 ] >> 4); b[19] = (byte)(d[5 ] >> 12); b[20] = (byte)(d[5 ] >> 20); b[21] = (byte)(d[6 ] >> 0); b[22] = (byte)(d[6 ] >> 8); b[23] = (byte)(d[6 ] >> 16); - b[24] = (byte)(d[6 ] >> 24) + (byte)((d[7 ] >> 0) << 4); + b[24] = (byte)((byte)(d[6 ] >> 24) + (byte)((d[7 ] >> 0) << 4)); b[25] = (byte)(d[7 ] >> 4); b[26] = (byte)(d[7 ] >> 12); b[27] = (byte)(d[7 ] >> 20); b[28] = (byte)(d[8 ] >> 0); b[29] = (byte)(d[8 ] >> 8); b[30] = (byte)(d[8 ] >> 16); - b[31] = (byte)(d[8 ] >> 24) + (byte)((d[9 ] >> 0) << 4); + b[31] = (byte)((byte)(d[8 ] >> 24) + (byte)((d[9 ] >> 0) << 4)); b[32] = (byte)(d[9 ] >> 4); b[33] = (byte)(d[9 ] >> 12); b[34] = (byte)(d[9 ] >> 20); b[35] = (byte)(d[10] >> 0); b[36] = (byte)(d[10] >> 8); b[37] = (byte)(d[10] >> 16); - b[38] = (byte)(d[10] >> 24) + (byte)((d[11] >> 0) << 4); + b[38] = (byte)((byte)(d[10] >> 24) + (byte)((d[11] >> 0) << 4)); b[39] = (byte)(d[11] >> 4); b[40] = (byte)(d[11] >> 12); b[41] = (byte)(d[11] >> 20); b[42] = (byte)(d[12] >> 0); b[43] = (byte)(d[12] >> 8); b[44] = (byte)(d[12] >> 16); - b[45] = (byte)(d[12] >> 24) + (byte)((d[13] >> 0) << 4); + b[45] = (byte)((byte)(d[12] >> 24) + (byte)((d[13] >> 0) << 4)); b[46] = (byte)(d[13] >> 4); b[47] = (byte)(d[13] >> 12); b[48] = (byte)(d[13] >> 20); b[49] = (byte)(d[14] >> 0); b[50] = (byte)(d[14] >> 8); b[51] = (byte)(d[14] >> 16); - b[52] = (byte)(d[14] >> 24) + (byte)((d[15] >> 0) << 4); + b[52] = (byte)((byte)(d[14] >> 24) + (byte)((d[15] >> 0) << 4)); b[53] = (byte)(d[15] >> 4); b[54] = (byte)(d[15] >> 12); b[55] = (byte)(d[15] >> 20); @@ -5586,458 +5614,506 @@ void sc448_muladd(byte* r, const byte* a, const byte* b, const byte* d) sword32 u; /* Load from bytes */ - ad[ 0] = (((sword32)((a[ 0] ) >> 0)) << 0) + ad[ 0] = (word32)( + (((sword32)((a[ 0] ) >> 0)) << 0) | (((sword32)((a[ 1] ) >> 0)) << 8) | (((sword32)((a[ 2] ) >> 0)) << 16) - | ((((sword32)((a[ 3] & 0xf )) >> 0)) << 24); - ad[ 1] = (((sword32)((a[ 3] ) >> 4)) << 0) + | ((((sword32)((a[ 3] & 0xf )) >> 0)) << 24)); + ad[ 1] = (word32)( + (((sword32)((a[ 3] ) >> 4)) << 0) | (((sword32)((a[ 4] ) >> 0)) << 4) | (((sword32)((a[ 5] ) >> 0)) << 12) - | (((sword32)((a[ 6] ) >> 0)) << 20); - ad[ 2] = (((sword32)((a[ 7] ) >> 0)) << 0) + | (((sword32)((a[ 6] ) >> 0)) << 20)); + ad[ 2] = (word32)( + (((sword32)((a[ 7] ) >> 0)) << 0) | (((sword32)((a[ 8] ) >> 0)) << 8) | (((sword32)((a[ 9] ) >> 0)) << 16) - | ((((sword32)((a[10] & 0xf )) >> 0)) << 24); - ad[ 3] = (((sword32)((a[10] ) >> 4)) << 0) + | ((((sword32)((a[10] & 0xf )) >> 0)) << 24)); + ad[ 3] = (word32)( + (((sword32)((a[10] ) >> 4)) << 0) | (((sword32)((a[11] ) >> 0)) << 4) | (((sword32)((a[12] ) >> 0)) << 12) - | (((sword32)((a[13] ) >> 0)) << 20); - ad[ 4] = (((sword32)((a[14] ) >> 0)) << 0) + | (((sword32)((a[13] ) >> 0)) << 20)); + ad[ 4] = (word32)( + (((sword32)((a[14] ) >> 0)) << 0) | (((sword32)((a[15] ) >> 0)) << 8) | (((sword32)((a[16] ) >> 0)) << 16) - | ((((sword32)((a[17] & 0xf )) >> 0)) << 24); - ad[ 5] = (((sword32)((a[17] ) >> 4)) << 0) + | ((((sword32)((a[17] & 0xf )) >> 0)) << 24)); + ad[ 5] = (word32)( + (((sword32)((a[17] ) >> 4)) << 0) | (((sword32)((a[18] ) >> 0)) << 4) | (((sword32)((a[19] ) >> 0)) << 12) - | (((sword32)((a[20] ) >> 0)) << 20); - ad[ 6] = (((sword32)((a[21] ) >> 0)) << 0) + | (((sword32)((a[20] ) >> 0)) << 20)); + ad[ 6] = (word32)( + (((sword32)((a[21] ) >> 0)) << 0) | (((sword32)((a[22] ) >> 0)) << 8) | (((sword32)((a[23] ) >> 0)) << 16) - | ((((sword32)((a[24] & 0xf )) >> 0)) << 24); - ad[ 7] = (((sword32)((a[24] ) >> 4)) << 0) + | ((((sword32)((a[24] & 0xf )) >> 0)) << 24)); + ad[ 7] = (word32)( + (((sword32)((a[24] ) >> 4)) << 0) | (((sword32)((a[25] ) >> 0)) << 4) | (((sword32)((a[26] ) >> 0)) << 12) - | (((sword32)((a[27] ) >> 0)) << 20); - ad[ 8] = (((sword32)((a[28] ) >> 0)) << 0) + | (((sword32)((a[27] ) >> 0)) << 20)); + ad[ 8] = (word32)( + (((sword32)((a[28] ) >> 0)) << 0) | (((sword32)((a[29] ) >> 0)) << 8) | (((sword32)((a[30] ) >> 0)) << 16) - | ((((sword32)((a[31] & 0xf )) >> 0)) << 24); - ad[ 9] = (((sword32)((a[31] ) >> 4)) << 0) + | ((((sword32)((a[31] & 0xf )) >> 0)) << 24)); + ad[ 9] = (word32)( + (((sword32)((a[31] ) >> 4)) << 0) | (((sword32)((a[32] ) >> 0)) << 4) | (((sword32)((a[33] ) >> 0)) << 12) - | (((sword32)((a[34] ) >> 0)) << 20); - ad[10] = (((sword32)((a[35] ) >> 0)) << 0) + | (((sword32)((a[34] ) >> 0)) << 20)); + ad[10] = (word32)( + (((sword32)((a[35] ) >> 0)) << 0) | (((sword32)((a[36] ) >> 0)) << 8) | (((sword32)((a[37] ) >> 0)) << 16) - | ((((sword32)((a[38] & 0xf )) >> 0)) << 24); - ad[11] = (((sword32)((a[38] ) >> 4)) << 0) + | ((((sword32)((a[38] & 0xf )) >> 0)) << 24)); + ad[11] = (word32)( + (((sword32)((a[38] ) >> 4)) << 0) | (((sword32)((a[39] ) >> 0)) << 4) | (((sword32)((a[40] ) >> 0)) << 12) - | (((sword32)((a[41] ) >> 0)) << 20); - ad[12] = (((sword32)((a[42] ) >> 0)) << 0) + | (((sword32)((a[41] ) >> 0)) << 20)); + ad[12] = (word32)( + (((sword32)((a[42] ) >> 0)) << 0) | (((sword32)((a[43] ) >> 0)) << 8) | (((sword32)((a[44] ) >> 0)) << 16) - | ((((sword32)((a[45] & 0xf )) >> 0)) << 24); - ad[13] = (((sword32)((a[45] ) >> 4)) << 0) + | ((((sword32)((a[45] & 0xf )) >> 0)) << 24)); + ad[13] = (word32)( + (((sword32)((a[45] ) >> 4)) << 0) | (((sword32)((a[46] ) >> 0)) << 4) | (((sword32)((a[47] ) >> 0)) << 12) - | (((sword32)((a[48] ) >> 0)) << 20); - ad[14] = (((sword32)((a[49] ) >> 0)) << 0) + | (((sword32)((a[48] ) >> 0)) << 20)); + ad[14] = (word32)( + (((sword32)((a[49] ) >> 0)) << 0) | (((sword32)((a[50] ) >> 0)) << 8) | (((sword32)((a[51] ) >> 0)) << 16) - | ((((sword32)((a[52] & 0xf )) >> 0)) << 24); - ad[15] = (((sword32)((a[52] ) >> 4)) << 0) + | ((((sword32)((a[52] & 0xf )) >> 0)) << 24)); + ad[15] = (word32)( + (((sword32)((a[52] ) >> 4)) << 0) | (((sword32)((a[53] ) >> 0)) << 4) | (((sword32)((a[54] ) >> 0)) << 12) - | (((sword32)((a[55] ) >> 0)) << 20); + | (((sword32)((a[55] ) >> 0)) << 20)); /* Load from bytes */ - bd[ 0] = (((sword32)((b[ 0] ) >> 0)) << 0) + bd[ 0] = (word32)( + (((sword32)((b[ 0] ) >> 0)) << 0) | (((sword32)((b[ 1] ) >> 0)) << 8) | (((sword32)((b[ 2] ) >> 0)) << 16) - | ((((sword32)((b[ 3] & 0xf )) >> 0)) << 24); - bd[ 1] = (((sword32)((b[ 3] ) >> 4)) << 0) + | ((((sword32)((b[ 3] & 0xf )) >> 0)) << 24)); + bd[ 1] = (word32)( + (((sword32)((b[ 3] ) >> 4)) << 0) | (((sword32)((b[ 4] ) >> 0)) << 4) | (((sword32)((b[ 5] ) >> 0)) << 12) - | (((sword32)((b[ 6] ) >> 0)) << 20); - bd[ 2] = (((sword32)((b[ 7] ) >> 0)) << 0) + | (((sword32)((b[ 6] ) >> 0)) << 20)); + bd[ 2] = (word32)( + (((sword32)((b[ 7] ) >> 0)) << 0) | (((sword32)((b[ 8] ) >> 0)) << 8) | (((sword32)((b[ 9] ) >> 0)) << 16) - | ((((sword32)((b[10] & 0xf )) >> 0)) << 24); - bd[ 3] = (((sword32)((b[10] ) >> 4)) << 0) + | ((((sword32)((b[10] & 0xf )) >> 0)) << 24)); + bd[ 3] = (word32)( + (((sword32)((b[10] ) >> 4)) << 0) | (((sword32)((b[11] ) >> 0)) << 4) | (((sword32)((b[12] ) >> 0)) << 12) - | (((sword32)((b[13] ) >> 0)) << 20); - bd[ 4] = (((sword32)((b[14] ) >> 0)) << 0) + | (((sword32)((b[13] ) >> 0)) << 20)); + bd[ 4] = (word32)( + (((sword32)((b[14] ) >> 0)) << 0) | (((sword32)((b[15] ) >> 0)) << 8) | (((sword32)((b[16] ) >> 0)) << 16) - | ((((sword32)((b[17] & 0xf )) >> 0)) << 24); - bd[ 5] = (((sword32)((b[17] ) >> 4)) << 0) + | ((((sword32)((b[17] & 0xf )) >> 0)) << 24)); + bd[ 5] = (word32)( + (((sword32)((b[17] ) >> 4)) << 0) | (((sword32)((b[18] ) >> 0)) << 4) | (((sword32)((b[19] ) >> 0)) << 12) - | (((sword32)((b[20] ) >> 0)) << 20); - bd[ 6] = (((sword32)((b[21] ) >> 0)) << 0) + | (((sword32)((b[20] ) >> 0)) << 20)); + bd[ 6] = (word32)( + (((sword32)((b[21] ) >> 0)) << 0) | (((sword32)((b[22] ) >> 0)) << 8) | (((sword32)((b[23] ) >> 0)) << 16) - | ((((sword32)((b[24] & 0xf )) >> 0)) << 24); - bd[ 7] = (((sword32)((b[24] ) >> 4)) << 0) + | ((((sword32)((b[24] & 0xf )) >> 0)) << 24)); + bd[ 7] = (word32)( + (((sword32)((b[24] ) >> 4)) << 0) | (((sword32)((b[25] ) >> 0)) << 4) | (((sword32)((b[26] ) >> 0)) << 12) - | (((sword32)((b[27] ) >> 0)) << 20); - bd[ 8] = (((sword32)((b[28] ) >> 0)) << 0) + | (((sword32)((b[27] ) >> 0)) << 20)); + bd[ 8] = (word32)( + (((sword32)((b[28] ) >> 0)) << 0) | (((sword32)((b[29] ) >> 0)) << 8) | (((sword32)((b[30] ) >> 0)) << 16) - | ((((sword32)((b[31] & 0xf )) >> 0)) << 24); - bd[ 9] = (((sword32)((b[31] ) >> 4)) << 0) + | ((((sword32)((b[31] & 0xf )) >> 0)) << 24)); + bd[ 9] = (word32)( + (((sword32)((b[31] ) >> 4)) << 0) | (((sword32)((b[32] ) >> 0)) << 4) | (((sword32)((b[33] ) >> 0)) << 12) - | (((sword32)((b[34] ) >> 0)) << 20); - bd[10] = (((sword32)((b[35] ) >> 0)) << 0) + | (((sword32)((b[34] ) >> 0)) << 20)); + bd[10] = (word32)( + (((sword32)((b[35] ) >> 0)) << 0) | (((sword32)((b[36] ) >> 0)) << 8) | (((sword32)((b[37] ) >> 0)) << 16) - | ((((sword32)((b[38] & 0xf )) >> 0)) << 24); - bd[11] = (((sword32)((b[38] ) >> 4)) << 0) + | ((((sword32)((b[38] & 0xf )) >> 0)) << 24)); + bd[11] = (word32)( + (((sword32)((b[38] ) >> 4)) << 0) | (((sword32)((b[39] ) >> 0)) << 4) | (((sword32)((b[40] ) >> 0)) << 12) - | (((sword32)((b[41] ) >> 0)) << 20); - bd[12] = (((sword32)((b[42] ) >> 0)) << 0) + | (((sword32)((b[41] ) >> 0)) << 20)); + bd[12] = (word32)( + (((sword32)((b[42] ) >> 0)) << 0) | (((sword32)((b[43] ) >> 0)) << 8) | (((sword32)((b[44] ) >> 0)) << 16) - | ((((sword32)((b[45] & 0xf )) >> 0)) << 24); - bd[13] = (((sword32)((b[45] ) >> 4)) << 0) + | ((((sword32)((b[45] & 0xf )) >> 0)) << 24)); + bd[13] = (word32)( + (((sword32)((b[45] ) >> 4)) << 0) | (((sword32)((b[46] ) >> 0)) << 4) | (((sword32)((b[47] ) >> 0)) << 12) - | (((sword32)((b[48] ) >> 0)) << 20); - bd[14] = (((sword32)((b[49] ) >> 0)) << 0) + | (((sword32)((b[48] ) >> 0)) << 20)); + bd[14] = (word32)( + (((sword32)((b[49] ) >> 0)) << 0) | (((sword32)((b[50] ) >> 0)) << 8) | (((sword32)((b[51] ) >> 0)) << 16) - | ((((sword32)((b[52] & 0xf )) >> 0)) << 24); - bd[15] = (((sword32)((b[52] ) >> 4)) << 0) + | ((((sword32)((b[52] & 0xf )) >> 0)) << 24)); + bd[15] = (word32)( + (((sword32)((b[52] ) >> 4)) << 0) | (((sword32)((b[53] ) >> 0)) << 4) | (((sword32)((b[54] ) >> 0)) << 12) - | (((sword32)((b[55] ) >> 0)) << 20); + | (((sword32)((b[55] ) >> 0)) << 20)); /* Load from bytes */ - dd[ 0] = (((sword32)((d[ 0] ) >> 0)) << 0) + dd[ 0] = (word32)( + (((sword32)((d[ 0] ) >> 0)) << 0) | (((sword32)((d[ 1] ) >> 0)) << 8) | (((sword32)((d[ 2] ) >> 0)) << 16) - | ((((sword32)((d[ 3] & 0xf )) >> 0)) << 24); - dd[ 1] = (((sword32)((d[ 3] ) >> 4)) << 0) + | ((((sword32)((d[ 3] & 0xf )) >> 0)) << 24)); + dd[ 1] = (word32)( + (((sword32)((d[ 3] ) >> 4)) << 0) | (((sword32)((d[ 4] ) >> 0)) << 4) | (((sword32)((d[ 5] ) >> 0)) << 12) - | (((sword32)((d[ 6] ) >> 0)) << 20); - dd[ 2] = (((sword32)((d[ 7] ) >> 0)) << 0) + | (((sword32)((d[ 6] ) >> 0)) << 20)); + dd[ 2] = (word32)( + (((sword32)((d[ 7] ) >> 0)) << 0) | (((sword32)((d[ 8] ) >> 0)) << 8) | (((sword32)((d[ 9] ) >> 0)) << 16) - | ((((sword32)((d[10] & 0xf )) >> 0)) << 24); - dd[ 3] = (((sword32)((d[10] ) >> 4)) << 0) + | ((((sword32)((d[10] & 0xf )) >> 0)) << 24)); + dd[ 3] = (word32)( + (((sword32)((d[10] ) >> 4)) << 0) | (((sword32)((d[11] ) >> 0)) << 4) | (((sword32)((d[12] ) >> 0)) << 12) - | (((sword32)((d[13] ) >> 0)) << 20); - dd[ 4] = (((sword32)((d[14] ) >> 0)) << 0) + | (((sword32)((d[13] ) >> 0)) << 20)); + dd[ 4] = (word32)( + (((sword32)((d[14] ) >> 0)) << 0) | (((sword32)((d[15] ) >> 0)) << 8) | (((sword32)((d[16] ) >> 0)) << 16) - | ((((sword32)((d[17] & 0xf )) >> 0)) << 24); - dd[ 5] = (((sword32)((d[17] ) >> 4)) << 0) + | ((((sword32)((d[17] & 0xf )) >> 0)) << 24)); + dd[ 5] = (word32)( + (((sword32)((d[17] ) >> 4)) << 0) | (((sword32)((d[18] ) >> 0)) << 4) | (((sword32)((d[19] ) >> 0)) << 12) - | (((sword32)((d[20] ) >> 0)) << 20); - dd[ 6] = (((sword32)((d[21] ) >> 0)) << 0) + | (((sword32)((d[20] ) >> 0)) << 20)); + dd[ 6] = (word32)( + (((sword32)((d[21] ) >> 0)) << 0) | (((sword32)((d[22] ) >> 0)) << 8) | (((sword32)((d[23] ) >> 0)) << 16) - | ((((sword32)((d[24] & 0xf )) >> 0)) << 24); - dd[ 7] = (((sword32)((d[24] ) >> 4)) << 0) + | ((((sword32)((d[24] & 0xf )) >> 0)) << 24)); + dd[ 7] = (word32)( + (((sword32)((d[24] ) >> 4)) << 0) | (((sword32)((d[25] ) >> 0)) << 4) | (((sword32)((d[26] ) >> 0)) << 12) - | (((sword32)((d[27] ) >> 0)) << 20); - dd[ 8] = (((sword32)((d[28] ) >> 0)) << 0) + | (((sword32)((d[27] ) >> 0)) << 20)); + dd[ 8] = (word32)( + (((sword32)((d[28] ) >> 0)) << 0) | (((sword32)((d[29] ) >> 0)) << 8) | (((sword32)((d[30] ) >> 0)) << 16) - | ((((sword32)((d[31] & 0xf )) >> 0)) << 24); - dd[ 9] = (((sword32)((d[31] ) >> 4)) << 0) + | ((((sword32)((d[31] & 0xf )) >> 0)) << 24)); + dd[ 9] = (word32)( + (((sword32)((d[31] ) >> 4)) << 0) | (((sword32)((d[32] ) >> 0)) << 4) | (((sword32)((d[33] ) >> 0)) << 12) - | (((sword32)((d[34] ) >> 0)) << 20); - dd[10] = (((sword32)((d[35] ) >> 0)) << 0) + | (((sword32)((d[34] ) >> 0)) << 20)); + dd[10] = (word32)( + (((sword32)((d[35] ) >> 0)) << 0) | (((sword32)((d[36] ) >> 0)) << 8) | (((sword32)((d[37] ) >> 0)) << 16) - | ((((sword32)((d[38] & 0xf )) >> 0)) << 24); - dd[11] = (((sword32)((d[38] ) >> 4)) << 0) + | ((((sword32)((d[38] & 0xf )) >> 0)) << 24)); + dd[11] = (word32)( + (((sword32)((d[38] ) >> 4)) << 0) | (((sword32)((d[39] ) >> 0)) << 4) | (((sword32)((d[40] ) >> 0)) << 12) - | (((sword32)((d[41] ) >> 0)) << 20); - dd[12] = (((sword32)((d[42] ) >> 0)) << 0) + | (((sword32)((d[41] ) >> 0)) << 20)); + dd[12] = (word32)( + (((sword32)((d[42] ) >> 0)) << 0) | (((sword32)((d[43] ) >> 0)) << 8) | (((sword32)((d[44] ) >> 0)) << 16) - | ((((sword32)((d[45] & 0xf )) >> 0)) << 24); - dd[13] = (((sword32)((d[45] ) >> 4)) << 0) + | ((((sword32)((d[45] & 0xf )) >> 0)) << 24)); + dd[13] = (word32)( + (((sword32)((d[45] ) >> 4)) << 0) | (((sword32)((d[46] ) >> 0)) << 4) | (((sword32)((d[47] ) >> 0)) << 12) - | (((sword32)((d[48] ) >> 0)) << 20); - dd[14] = (((sword32)((d[49] ) >> 0)) << 0) + | (((sword32)((d[48] ) >> 0)) << 20)); + dd[14] = (word32)( + (((sword32)((d[49] ) >> 0)) << 0) | (((sword32)((d[50] ) >> 0)) << 8) | (((sword32)((d[51] ) >> 0)) << 16) - | ((((sword32)((d[52] & 0xf )) >> 0)) << 24); - dd[15] = (((sword32)((d[52] ) >> 4)) << 0) + | ((((sword32)((d[52] & 0xf )) >> 0)) << 24)); + dd[15] = (word32)( + (((sword32)((d[52] ) >> 4)) << 0) | (((sword32)((d[53] ) >> 0)) << 4) | (((sword32)((d[54] ) >> 0)) << 12) - | (((sword32)((d[55] ) >> 0)) << 20); + | (((sword32)((d[55] ) >> 0)) << 20)); /* a * b + d */ - t[ 0] = (word64)dd[ 0] + (sword64)ad[ 0] * bd[ 0]; - t[ 1] = (word64)dd[ 1] + (sword64)ad[ 0] * bd[ 1] - + (sword64)ad[ 1] * bd[ 0]; - t[ 2] = (word64)dd[ 2] + (sword64)ad[ 0] * bd[ 2] - + (sword64)ad[ 1] * bd[ 1] - + (sword64)ad[ 2] * bd[ 0]; - t[ 3] = (word64)dd[ 3] + (sword64)ad[ 0] * bd[ 3] - + (sword64)ad[ 1] * bd[ 2] - + (sword64)ad[ 2] * bd[ 1] - + (sword64)ad[ 3] * bd[ 0]; - t[ 4] = (word64)dd[ 4] + (sword64)ad[ 0] * bd[ 4] - + (sword64)ad[ 1] * bd[ 3] - + (sword64)ad[ 2] * bd[ 2] - + (sword64)ad[ 3] * bd[ 1] - + (sword64)ad[ 4] * bd[ 0]; - t[ 5] = (word64)dd[ 5] + (sword64)ad[ 0] * bd[ 5] - + (sword64)ad[ 1] * bd[ 4] - + (sword64)ad[ 2] * bd[ 3] - + (sword64)ad[ 3] * bd[ 2] - + (sword64)ad[ 4] * bd[ 1] - + (sword64)ad[ 5] * bd[ 0]; - t[ 6] = (word64)dd[ 6] + (sword64)ad[ 0] * bd[ 6] - + (sword64)ad[ 1] * bd[ 5] - + (sword64)ad[ 2] * bd[ 4] - + (sword64)ad[ 3] * bd[ 3] - + (sword64)ad[ 4] * bd[ 2] - + (sword64)ad[ 5] * bd[ 1] - + (sword64)ad[ 6] * bd[ 0]; - t[ 7] = (word64)dd[ 7] + (sword64)ad[ 0] * bd[ 7] - + (sword64)ad[ 1] * bd[ 6] - + (sword64)ad[ 2] * bd[ 5] - + (sword64)ad[ 3] * bd[ 4] - + (sword64)ad[ 4] * bd[ 3] - + (sword64)ad[ 5] * bd[ 2] - + (sword64)ad[ 6] * bd[ 1] - + (sword64)ad[ 7] * bd[ 0]; - t[ 8] = (word64)dd[ 8] + (sword64)ad[ 0] * bd[ 8] - + (sword64)ad[ 1] * bd[ 7] - + (sword64)ad[ 2] * bd[ 6] - + (sword64)ad[ 3] * bd[ 5] - + (sword64)ad[ 4] * bd[ 4] - + (sword64)ad[ 5] * bd[ 3] - + (sword64)ad[ 6] * bd[ 2] - + (sword64)ad[ 7] * bd[ 1] - + (sword64)ad[ 8] * bd[ 0]; - t[ 9] = (word64)dd[ 9] + (sword64)ad[ 0] * bd[ 9] - + (sword64)ad[ 1] * bd[ 8] - + (sword64)ad[ 2] * bd[ 7] - + (sword64)ad[ 3] * bd[ 6] - + (sword64)ad[ 4] * bd[ 5] - + (sword64)ad[ 5] * bd[ 4] - + (sword64)ad[ 6] * bd[ 3] - + (sword64)ad[ 7] * bd[ 2] - + (sword64)ad[ 8] * bd[ 1] - + (sword64)ad[ 9] * bd[ 0]; - t[10] = (word64)dd[10] + (sword64)ad[ 0] * bd[10] - + (sword64)ad[ 1] * bd[ 9] - + (sword64)ad[ 2] * bd[ 8] - + (sword64)ad[ 3] * bd[ 7] - + (sword64)ad[ 4] * bd[ 6] - + (sword64)ad[ 5] * bd[ 5] - + (sword64)ad[ 6] * bd[ 4] - + (sword64)ad[ 7] * bd[ 3] - + (sword64)ad[ 8] * bd[ 2] - + (sword64)ad[ 9] * bd[ 1] - + (sword64)ad[10] * bd[ 0]; - t[11] = (word64)dd[11] + (sword64)ad[ 0] * bd[11] - + (sword64)ad[ 1] * bd[10] - + (sword64)ad[ 2] * bd[ 9] - + (sword64)ad[ 3] * bd[ 8] - + (sword64)ad[ 4] * bd[ 7] - + (sword64)ad[ 5] * bd[ 6] - + (sword64)ad[ 6] * bd[ 5] - + (sword64)ad[ 7] * bd[ 4] - + (sword64)ad[ 8] * bd[ 3] - + (sword64)ad[ 9] * bd[ 2] - + (sword64)ad[10] * bd[ 1] - + (sword64)ad[11] * bd[ 0]; - t[12] = (word64)dd[12] + (sword64)ad[ 0] * bd[12] - + (sword64)ad[ 1] * bd[11] - + (sword64)ad[ 2] * bd[10] - + (sword64)ad[ 3] * bd[ 9] - + (sword64)ad[ 4] * bd[ 8] - + (sword64)ad[ 5] * bd[ 7] - + (sword64)ad[ 6] * bd[ 6] - + (sword64)ad[ 7] * bd[ 5] - + (sword64)ad[ 8] * bd[ 4] - + (sword64)ad[ 9] * bd[ 3] - + (sword64)ad[10] * bd[ 2] - + (sword64)ad[11] * bd[ 1] - + (sword64)ad[12] * bd[ 0]; - t[13] = (word64)dd[13] + (sword64)ad[ 0] * bd[13] - + (sword64)ad[ 1] * bd[12] - + (sword64)ad[ 2] * bd[11] - + (sword64)ad[ 3] * bd[10] - + (sword64)ad[ 4] * bd[ 9] - + (sword64)ad[ 5] * bd[ 8] - + (sword64)ad[ 6] * bd[ 7] - + (sword64)ad[ 7] * bd[ 6] - + (sword64)ad[ 8] * bd[ 5] - + (sword64)ad[ 9] * bd[ 4] - + (sword64)ad[10] * bd[ 3] - + (sword64)ad[11] * bd[ 2] - + (sword64)ad[12] * bd[ 1] - + (sword64)ad[13] * bd[ 0]; - t[14] = (word64)dd[14] + (sword64)ad[ 0] * bd[14] - + (sword64)ad[ 1] * bd[13] - + (sword64)ad[ 2] * bd[12] - + (sword64)ad[ 3] * bd[11] - + (sword64)ad[ 4] * bd[10] - + (sword64)ad[ 5] * bd[ 9] - + (sword64)ad[ 6] * bd[ 8] - + (sword64)ad[ 7] * bd[ 7] - + (sword64)ad[ 8] * bd[ 6] - + (sword64)ad[ 9] * bd[ 5] - + (sword64)ad[10] * bd[ 4] - + (sword64)ad[11] * bd[ 3] - + (sword64)ad[12] * bd[ 2] - + (sword64)ad[13] * bd[ 1] - + (sword64)ad[14] * bd[ 0]; - t[15] = (word64)dd[15] + (sword64)ad[ 0] * bd[15] - + (sword64)ad[ 1] * bd[14] - + (sword64)ad[ 2] * bd[13] - + (sword64)ad[ 3] * bd[12] - + (sword64)ad[ 4] * bd[11] - + (sword64)ad[ 5] * bd[10] - + (sword64)ad[ 6] * bd[ 9] - + (sword64)ad[ 7] * bd[ 8] - + (sword64)ad[ 8] * bd[ 7] - + (sword64)ad[ 9] * bd[ 6] - + (sword64)ad[10] * bd[ 5] - + (sword64)ad[11] * bd[ 4] - + (sword64)ad[12] * bd[ 3] - + (sword64)ad[13] * bd[ 2] - + (sword64)ad[14] * bd[ 1] - + (sword64)ad[15] * bd[ 0]; - t[16] = (word64) (sword64)ad[ 1] * bd[15] - + (sword64)ad[ 2] * bd[14] - + (sword64)ad[ 3] * bd[13] - + (sword64)ad[ 4] * bd[12] - + (sword64)ad[ 5] * bd[11] - + (sword64)ad[ 6] * bd[10] - + (sword64)ad[ 7] * bd[ 9] - + (sword64)ad[ 8] * bd[ 8] - + (sword64)ad[ 9] * bd[ 7] - + (sword64)ad[10] * bd[ 6] - + (sword64)ad[11] * bd[ 5] - + (sword64)ad[12] * bd[ 4] - + (sword64)ad[13] * bd[ 3] - + (sword64)ad[14] * bd[ 2] - + (sword64)ad[15] * bd[ 1]; - t[17] = (word64) (sword64)ad[ 2] * bd[15] - + (sword64)ad[ 3] * bd[14] - + (sword64)ad[ 4] * bd[13] - + (sword64)ad[ 5] * bd[12] - + (sword64)ad[ 6] * bd[11] - + (sword64)ad[ 7] * bd[10] - + (sword64)ad[ 8] * bd[ 9] - + (sword64)ad[ 9] * bd[ 8] - + (sword64)ad[10] * bd[ 7] - + (sword64)ad[11] * bd[ 6] - + (sword64)ad[12] * bd[ 5] - + (sword64)ad[13] * bd[ 4] - + (sword64)ad[14] * bd[ 3] - + (sword64)ad[15] * bd[ 2]; - t[18] = (word64) (sword64)ad[ 3] * bd[15] - + (sword64)ad[ 4] * bd[14] - + (sword64)ad[ 5] * bd[13] - + (sword64)ad[ 6] * bd[12] - + (sword64)ad[ 7] * bd[11] - + (sword64)ad[ 8] * bd[10] - + (sword64)ad[ 9] * bd[ 9] - + (sword64)ad[10] * bd[ 8] - + (sword64)ad[11] * bd[ 7] - + (sword64)ad[12] * bd[ 6] - + (sword64)ad[13] * bd[ 5] - + (sword64)ad[14] * bd[ 4] - + (sword64)ad[15] * bd[ 3]; - t[19] = (word64) (sword64)ad[ 4] * bd[15] - + (sword64)ad[ 5] * bd[14] - + (sword64)ad[ 6] * bd[13] - + (sword64)ad[ 7] * bd[12] - + (sword64)ad[ 8] * bd[11] - + (sword64)ad[ 9] * bd[10] - + (sword64)ad[10] * bd[ 9] - + (sword64)ad[11] * bd[ 8] - + (sword64)ad[12] * bd[ 7] - + (sword64)ad[13] * bd[ 6] - + (sword64)ad[14] * bd[ 5] - + (sword64)ad[15] * bd[ 4]; - t[20] = (word64) (sword64)ad[ 5] * bd[15] - + (sword64)ad[ 6] * bd[14] - + (sword64)ad[ 7] * bd[13] - + (sword64)ad[ 8] * bd[12] - + (sword64)ad[ 9] * bd[11] - + (sword64)ad[10] * bd[10] - + (sword64)ad[11] * bd[ 9] - + (sword64)ad[12] * bd[ 8] - + (sword64)ad[13] * bd[ 7] - + (sword64)ad[14] * bd[ 6] - + (sword64)ad[15] * bd[ 5]; - t[21] = (word64) (sword64)ad[ 6] * bd[15] - + (sword64)ad[ 7] * bd[14] - + (sword64)ad[ 8] * bd[13] - + (sword64)ad[ 9] * bd[12] - + (sword64)ad[10] * bd[11] - + (sword64)ad[11] * bd[10] - + (sword64)ad[12] * bd[ 9] - + (sword64)ad[13] * bd[ 8] - + (sword64)ad[14] * bd[ 7] - + (sword64)ad[15] * bd[ 6]; - t[22] = (word64) (sword64)ad[ 7] * bd[15] - + (sword64)ad[ 8] * bd[14] - + (sword64)ad[ 9] * bd[13] - + (sword64)ad[10] * bd[12] - + (sword64)ad[11] * bd[11] - + (sword64)ad[12] * bd[10] - + (sword64)ad[13] * bd[ 9] - + (sword64)ad[14] * bd[ 8] - + (sword64)ad[15] * bd[ 7]; - t[23] = (word64) (sword64)ad[ 8] * bd[15] - + (sword64)ad[ 9] * bd[14] - + (sword64)ad[10] * bd[13] - + (sword64)ad[11] * bd[12] - + (sword64)ad[12] * bd[11] - + (sword64)ad[13] * bd[10] - + (sword64)ad[14] * bd[ 9] - + (sword64)ad[15] * bd[ 8]; - t[24] = (word64) (sword64)ad[ 9] * bd[15] - + (sword64)ad[10] * bd[14] - + (sword64)ad[11] * bd[13] - + (sword64)ad[12] * bd[12] - + (sword64)ad[13] * bd[11] - + (sword64)ad[14] * bd[10] - + (sword64)ad[15] * bd[ 9]; - t[25] = (word64) (sword64)ad[10] * bd[15] - + (sword64)ad[11] * bd[14] - + (sword64)ad[12] * bd[13] - + (sword64)ad[13] * bd[12] - + (sword64)ad[14] * bd[11] - + (sword64)ad[15] * bd[10]; - t[26] = (word64) (sword64)ad[11] * bd[15] - + (sword64)ad[12] * bd[14] - + (sword64)ad[13] * bd[13] - + (sword64)ad[14] * bd[12] - + (sword64)ad[15] * bd[11]; - t[27] = (word64) (sword64)ad[12] * bd[15] - + (sword64)ad[13] * bd[14] - + (sword64)ad[14] * bd[13] - + (sword64)ad[15] * bd[12]; - t[28] = (word64) (sword64)ad[13] * bd[15] - + (sword64)ad[14] * bd[14] - + (sword64)ad[15] * bd[13]; - t[29] = (word64) (sword64)ad[14] * bd[15] - + (sword64)ad[15] * bd[14]; - t[30] = (word64) (sword64)ad[15] * bd[15]; + t[ 0] = (word64)(dd[ 0] + (word64)((sword64)ad[ 0] * bd[ 0])); + t[ 1] = (word64)(dd[ 1] + (word64)((sword64)ad[ 0] * bd[ 1] + + (sword64)ad[ 1] * bd[ 0])); + t[ 2] = (word64)(dd[ 2] + (word64)((sword64)ad[ 0] * bd[ 2] + + (sword64)ad[ 1] * bd[ 1] + + (sword64)ad[ 2] * bd[ 0])); + t[ 3] = (word64)(dd[ 3] + (word64)((sword64)ad[ 0] * bd[ 3] + + (sword64)ad[ 1] * bd[ 2] + + (sword64)ad[ 2] * bd[ 1] + + (sword64)ad[ 3] * bd[ 0])); + t[ 4] = (word64)(dd[ 4] + (word64)((sword64)ad[ 0] * bd[ 4] + + (sword64)ad[ 1] * bd[ 3] + + (sword64)ad[ 2] * bd[ 2] + + (sword64)ad[ 3] * bd[ 1] + + (sword64)ad[ 4] * bd[ 0])); + t[ 5] = (word64)(dd[ 5] + (word64)((sword64)ad[ 0] * bd[ 5] + + (sword64)ad[ 1] * bd[ 4] + + (sword64)ad[ 2] * bd[ 3] + + (sword64)ad[ 3] * bd[ 2] + + (sword64)ad[ 4] * bd[ 1] + + (sword64)ad[ 5] * bd[ 0])); + t[ 6] = (word64)(dd[ 6] + (word64)((sword64)ad[ 0] * bd[ 6] + + (sword64)ad[ 1] * bd[ 5] + + (sword64)ad[ 2] * bd[ 4] + + (sword64)ad[ 3] * bd[ 3] + + (sword64)ad[ 4] * bd[ 2] + + (sword64)ad[ 5] * bd[ 1] + + (sword64)ad[ 6] * bd[ 0])); + t[ 7] = (word64)(dd[ 7] + (word64)((sword64)ad[ 0] * bd[ 7] + + (sword64)ad[ 1] * bd[ 6] + + (sword64)ad[ 2] * bd[ 5] + + (sword64)ad[ 3] * bd[ 4] + + (sword64)ad[ 4] * bd[ 3] + + (sword64)ad[ 5] * bd[ 2] + + (sword64)ad[ 6] * bd[ 1] + + (sword64)ad[ 7] * bd[ 0])); + t[ 8] = (word64)(dd[ 8] + (word64)((sword64)ad[ 0] * bd[ 8] + + (sword64)ad[ 1] * bd[ 7] + + (sword64)ad[ 2] * bd[ 6] + + (sword64)ad[ 3] * bd[ 5] + + (sword64)ad[ 4] * bd[ 4] + + (sword64)ad[ 5] * bd[ 3] + + (sword64)ad[ 6] * bd[ 2] + + (sword64)ad[ 7] * bd[ 1] + + (sword64)ad[ 8] * bd[ 0])); + t[ 9] = (word64)(dd[ 9] + (word64)((sword64)ad[ 0] * bd[ 9] + + (sword64)ad[ 1] * bd[ 8] + + (sword64)ad[ 2] * bd[ 7] + + (sword64)ad[ 3] * bd[ 6] + + (sword64)ad[ 4] * bd[ 5] + + (sword64)ad[ 5] * bd[ 4] + + (sword64)ad[ 6] * bd[ 3] + + (sword64)ad[ 7] * bd[ 2] + + (sword64)ad[ 8] * bd[ 1] + + (sword64)ad[ 9] * bd[ 0])); + t[10] = (word64)(dd[10] + (word64)((sword64)ad[ 0] * bd[10] + + (sword64)ad[ 1] * bd[ 9] + + (sword64)ad[ 2] * bd[ 8] + + (sword64)ad[ 3] * bd[ 7] + + (sword64)ad[ 4] * bd[ 6] + + (sword64)ad[ 5] * bd[ 5] + + (sword64)ad[ 6] * bd[ 4] + + (sword64)ad[ 7] * bd[ 3] + + (sword64)ad[ 8] * bd[ 2] + + (sword64)ad[ 9] * bd[ 1] + + (sword64)ad[10] * bd[ 0])); + t[11] = (word64)(dd[11] + (word64)((sword64)ad[ 0] * bd[11] + + (sword64)ad[ 1] * bd[10] + + (sword64)ad[ 2] * bd[ 9] + + (sword64)ad[ 3] * bd[ 8] + + (sword64)ad[ 4] * bd[ 7] + + (sword64)ad[ 5] * bd[ 6] + + (sword64)ad[ 6] * bd[ 5] + + (sword64)ad[ 7] * bd[ 4] + + (sword64)ad[ 8] * bd[ 3] + + (sword64)ad[ 9] * bd[ 2] + + (sword64)ad[10] * bd[ 1] + + (sword64)ad[11] * bd[ 0])); + t[12] = (word64)(dd[12] + (word64)((sword64)ad[ 0] * bd[12] + + (sword64)ad[ 1] * bd[11] + + (sword64)ad[ 2] * bd[10] + + (sword64)ad[ 3] * bd[ 9] + + (sword64)ad[ 4] * bd[ 8] + + (sword64)ad[ 5] * bd[ 7] + + (sword64)ad[ 6] * bd[ 6] + + (sword64)ad[ 7] * bd[ 5] + + (sword64)ad[ 8] * bd[ 4] + + (sword64)ad[ 9] * bd[ 3] + + (sword64)ad[10] * bd[ 2] + + (sword64)ad[11] * bd[ 1] + + (sword64)ad[12] * bd[ 0])); + t[13] = (word64)(dd[13] + (word64)((sword64)ad[ 0] * bd[13] + + (sword64)ad[ 1] * bd[12] + + (sword64)ad[ 2] * bd[11] + + (sword64)ad[ 3] * bd[10] + + (sword64)ad[ 4] * bd[ 9] + + (sword64)ad[ 5] * bd[ 8] + + (sword64)ad[ 6] * bd[ 7] + + (sword64)ad[ 7] * bd[ 6] + + (sword64)ad[ 8] * bd[ 5] + + (sword64)ad[ 9] * bd[ 4] + + (sword64)ad[10] * bd[ 3] + + (sword64)ad[11] * bd[ 2] + + (sword64)ad[12] * bd[ 1] + + (sword64)ad[13] * bd[ 0])); + t[14] = (word64)(dd[14] + (word64)((sword64)ad[ 0] * bd[14] + + (sword64)ad[ 1] * bd[13] + + (sword64)ad[ 2] * bd[12] + + (sword64)ad[ 3] * bd[11] + + (sword64)ad[ 4] * bd[10] + + (sword64)ad[ 5] * bd[ 9] + + (sword64)ad[ 6] * bd[ 8] + + (sword64)ad[ 7] * bd[ 7] + + (sword64)ad[ 8] * bd[ 6] + + (sword64)ad[ 9] * bd[ 5] + + (sword64)ad[10] * bd[ 4] + + (sword64)ad[11] * bd[ 3] + + (sword64)ad[12] * bd[ 2] + + (sword64)ad[13] * bd[ 1] + + (sword64)ad[14] * bd[ 0])); + t[15] = (word64)(dd[15] + (word64)((sword64)ad[ 0] * bd[15] + + (sword64)ad[ 1] * bd[14] + + (sword64)ad[ 2] * bd[13] + + (sword64)ad[ 3] * bd[12] + + (sword64)ad[ 4] * bd[11] + + (sword64)ad[ 5] * bd[10] + + (sword64)ad[ 6] * bd[ 9] + + (sword64)ad[ 7] * bd[ 8] + + (sword64)ad[ 8] * bd[ 7] + + (sword64)ad[ 9] * bd[ 6] + + (sword64)ad[10] * bd[ 5] + + (sword64)ad[11] * bd[ 4] + + (sword64)ad[12] * bd[ 3] + + (sword64)ad[13] * bd[ 2] + + (sword64)ad[14] * bd[ 1] + + (sword64)ad[15] * bd[ 0])); + t[16] = (word64)( (sword64)ad[ 1] * bd[15] + + (sword64)ad[ 2] * bd[14] + + (sword64)ad[ 3] * bd[13] + + (sword64)ad[ 4] * bd[12] + + (sword64)ad[ 5] * bd[11] + + (sword64)ad[ 6] * bd[10] + + (sword64)ad[ 7] * bd[ 9] + + (sword64)ad[ 8] * bd[ 8] + + (sword64)ad[ 9] * bd[ 7] + + (sword64)ad[10] * bd[ 6] + + (sword64)ad[11] * bd[ 5] + + (sword64)ad[12] * bd[ 4] + + (sword64)ad[13] * bd[ 3] + + (sword64)ad[14] * bd[ 2] + + (sword64)ad[15] * bd[ 1]); + t[17] = (word64)( (sword64)ad[ 2] * bd[15] + + (sword64)ad[ 3] * bd[14] + + (sword64)ad[ 4] * bd[13] + + (sword64)ad[ 5] * bd[12] + + (sword64)ad[ 6] * bd[11] + + (sword64)ad[ 7] * bd[10] + + (sword64)ad[ 8] * bd[ 9] + + (sword64)ad[ 9] * bd[ 8] + + (sword64)ad[10] * bd[ 7] + + (sword64)ad[11] * bd[ 6] + + (sword64)ad[12] * bd[ 5] + + (sword64)ad[13] * bd[ 4] + + (sword64)ad[14] * bd[ 3] + + (sword64)ad[15] * bd[ 2]); + t[18] = (word64)( (sword64)ad[ 3] * bd[15] + + (sword64)ad[ 4] * bd[14] + + (sword64)ad[ 5] * bd[13] + + (sword64)ad[ 6] * bd[12] + + (sword64)ad[ 7] * bd[11] + + (sword64)ad[ 8] * bd[10] + + (sword64)ad[ 9] * bd[ 9] + + (sword64)ad[10] * bd[ 8] + + (sword64)ad[11] * bd[ 7] + + (sword64)ad[12] * bd[ 6] + + (sword64)ad[13] * bd[ 5] + + (sword64)ad[14] * bd[ 4] + + (sword64)ad[15] * bd[ 3]); + t[19] = (word64)( (sword64)ad[ 4] * bd[15] + + (sword64)ad[ 5] * bd[14] + + (sword64)ad[ 6] * bd[13] + + (sword64)ad[ 7] * bd[12] + + (sword64)ad[ 8] * bd[11] + + (sword64)ad[ 9] * bd[10] + + (sword64)ad[10] * bd[ 9] + + (sword64)ad[11] * bd[ 8] + + (sword64)ad[12] * bd[ 7] + + (sword64)ad[13] * bd[ 6] + + (sword64)ad[14] * bd[ 5] + + (sword64)ad[15] * bd[ 4]); + t[20] = (word64)( (sword64)ad[ 5] * bd[15] + + (sword64)ad[ 6] * bd[14] + + (sword64)ad[ 7] * bd[13] + + (sword64)ad[ 8] * bd[12] + + (sword64)ad[ 9] * bd[11] + + (sword64)ad[10] * bd[10] + + (sword64)ad[11] * bd[ 9] + + (sword64)ad[12] * bd[ 8] + + (sword64)ad[13] * bd[ 7] + + (sword64)ad[14] * bd[ 6] + + (sword64)ad[15] * bd[ 5]); + t[21] = (word64)( (sword64)ad[ 6] * bd[15] + + (sword64)ad[ 7] * bd[14] + + (sword64)ad[ 8] * bd[13] + + (sword64)ad[ 9] * bd[12] + + (sword64)ad[10] * bd[11] + + (sword64)ad[11] * bd[10] + + (sword64)ad[12] * bd[ 9] + + (sword64)ad[13] * bd[ 8] + + (sword64)ad[14] * bd[ 7] + + (sword64)ad[15] * bd[ 6]); + t[22] = (word64)( (sword64)ad[ 7] * bd[15] + + (sword64)ad[ 8] * bd[14] + + (sword64)ad[ 9] * bd[13] + + (sword64)ad[10] * bd[12] + + (sword64)ad[11] * bd[11] + + (sword64)ad[12] * bd[10] + + (sword64)ad[13] * bd[ 9] + + (sword64)ad[14] * bd[ 8] + + (sword64)ad[15] * bd[ 7]); + t[23] = (word64)( (sword64)ad[ 8] * bd[15] + + (sword64)ad[ 9] * bd[14] + + (sword64)ad[10] * bd[13] + + (sword64)ad[11] * bd[12] + + (sword64)ad[12] * bd[11] + + (sword64)ad[13] * bd[10] + + (sword64)ad[14] * bd[ 9] + + (sword64)ad[15] * bd[ 8]); + t[24] = (word64)( (sword64)ad[ 9] * bd[15] + + (sword64)ad[10] * bd[14] + + (sword64)ad[11] * bd[13] + + (sword64)ad[12] * bd[12] + + (sword64)ad[13] * bd[11] + + (sword64)ad[14] * bd[10] + + (sword64)ad[15] * bd[ 9]); + t[25] = (word64)( (sword64)ad[10] * bd[15] + + (sword64)ad[11] * bd[14] + + (sword64)ad[12] * bd[13] + + (sword64)ad[13] * bd[12] + + (sword64)ad[14] * bd[11] + + (sword64)ad[15] * bd[10]); + t[26] = (word64)( (sword64)ad[11] * bd[15] + + (sword64)ad[12] * bd[14] + + (sword64)ad[13] * bd[13] + + (sword64)ad[14] * bd[12] + + (sword64)ad[15] * bd[11]); + t[27] = (word64)( (sword64)ad[12] * bd[15] + + (sword64)ad[13] * bd[14] + + (sword64)ad[14] * bd[13] + + (sword64)ad[15] * bd[12]); + t[28] = (word64)( (sword64)ad[13] * bd[15] + + (sword64)ad[14] * bd[14] + + (sword64)ad[15] * bd[13]); + t[29] = (word64)( (sword64)ad[14] * bd[15] + + (sword64)ad[15] * bd[14]); + t[30] = (word64)( (sword64)ad[15] * bd[15]); t[31] = 0; /* Mod curve order */ @@ -6265,110 +6341,126 @@ void sc448_muladd(byte* r, const byte* a, const byte* b, const byte* d) o = rd[14] >> 28; rd[15] += o; rd[14] = rd[14] & 0xfffffff; /* Reduce to mod order. */ u = 0; - u += (sword32)(rd[0] - (sword32)0x0b5844f3L); u >>= 28; - u += (sword32)(rd[1] - (sword32)0x078c292aL); u >>= 28; - u += (sword32)(rd[2] - (sword32)0x058f5523L); u >>= 28; - u += (sword32)(rd[3] - (sword32)0x0c2728dcL); u >>= 28; - u += (sword32)(rd[4] - (sword32)0x0690216cL); u >>= 28; - u += (sword32)(rd[5] - (sword32)0x049aed63L); u >>= 28; - u += (sword32)(rd[6] - (sword32)0x09c44edbL); u >>= 28; - u += (sword32)(rd[7] - (sword32)0x07cca23eL); u >>= 28; - u += (sword32)(rd[8] - (sword32)0x0fffffffL); u >>= 28; - u += (sword32)(rd[9] - (sword32)0x0fffffffL); u >>= 28; - u += (sword32)(rd[10] - (sword32)0x0fffffffL); u >>= 28; - u += (sword32)(rd[11] - (sword32)0x0fffffffL); u >>= 28; - u += (sword32)(rd[12] - (sword32)0x0fffffffL); u >>= 28; - u += (sword32)(rd[13] - (sword32)0x0fffffffL); u >>= 28; - u += (sword32)(rd[14] - (sword32)0x0fffffffL); u >>= 28; - u += (sword32)(rd[15] - (sword32)0x03ffffffL); u >>= 28; + u += (sword32)rd[0] - (sword32)0x0b5844f3L; u >>= 28; + u += (sword32)rd[1] - (sword32)0x078c292aL; u >>= 28; + u += (sword32)rd[2] - (sword32)0x058f5523L; u >>= 28; + u += (sword32)rd[3] - (sword32)0x0c2728dcL; u >>= 28; + u += (sword32)rd[4] - (sword32)0x0690216cL; u >>= 28; + u += (sword32)rd[5] - (sword32)0x049aed63L; u >>= 28; + u += (sword32)rd[6] - (sword32)0x09c44edbL; u >>= 28; + u += (sword32)rd[7] - (sword32)0x07cca23eL; u >>= 28; + u += (sword32)rd[8] - (sword32)0x0fffffffL; u >>= 28; + u += (sword32)rd[9] - (sword32)0x0fffffffL; u >>= 28; + u += (sword32)rd[10] - (sword32)0x0fffffffL; u >>= 28; + u += (sword32)rd[11] - (sword32)0x0fffffffL; u >>= 28; + u += (sword32)rd[12] - (sword32)0x0fffffffL; u >>= 28; + u += (sword32)rd[13] - (sword32)0x0fffffffL; u >>= 28; + u += (sword32)rd[14] - (sword32)0x0fffffffL; u >>= 28; + u += (sword32)rd[15] - (sword32)0x03ffffffL; u >>= 28; o = (word32)0 - (u >= 0); u = 0; - u += (sword32)(rd[0] - ((word32)0x0b5844f3L & o)); rd[0] = u & 0xfffffff; + u += (sword32)rd[0] - (sword32)((word32)0x0b5844f3L & o); + rd[0] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[1] - ((word32)0x078c292aL & o)); rd[1] = u & 0xfffffff; + u += (sword32)rd[1] - (sword32)((word32)0x078c292aL & o); + rd[1] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[2] - ((word32)0x058f5523L & o)); rd[2] = u & 0xfffffff; + u += (sword32)rd[2] - (sword32)((word32)0x058f5523L & o); + rd[2] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[3] - ((word32)0x0c2728dcL & o)); rd[3] = u & 0xfffffff; + u += (sword32)rd[3] - (sword32)((word32)0x0c2728dcL & o); + rd[3] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[4] - ((word32)0x0690216cL & o)); rd[4] = u & 0xfffffff; + u += (sword32)rd[4] - (sword32)((word32)0x0690216cL & o); + rd[4] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[5] - ((word32)0x049aed63L & o)); rd[5] = u & 0xfffffff; + u += (sword32)rd[5] - (sword32)((word32)0x049aed63L & o); + rd[5] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[6] - ((word32)0x09c44edbL & o)); rd[6] = u & 0xfffffff; + u += (sword32)rd[6] - (sword32)((word32)0x09c44edbL & o); + rd[6] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[7] - ((word32)0x07cca23eL & o)); rd[7] = u & 0xfffffff; + u += (sword32)rd[7] - (sword32)((word32)0x07cca23eL & o); + rd[7] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[8] - ((word32)0x0fffffffL & o)); rd[8] = u & 0xfffffff; + u += (sword32)rd[8] - (sword32)((word32)0x0fffffffL & o); + rd[8] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[9] - ((word32)0x0fffffffL & o)); rd[9] = u & 0xfffffff; + u += (sword32)rd[9] - (sword32)((word32)0x0fffffffL & o); + rd[9] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[10] - ((word32)0x0fffffffL & o)); rd[10] = u & 0xfffffff; + u += (sword32)rd[10] - (sword32)((word32)0x0fffffffL & o); + rd[10] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[11] - ((word32)0x0fffffffL & o)); rd[11] = u & 0xfffffff; + u += (sword32)rd[11] - (sword32)((word32)0x0fffffffL & o); + rd[11] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[12] - ((word32)0x0fffffffL & o)); rd[12] = u & 0xfffffff; + u += (sword32)rd[12] - (sword32)((word32)0x0fffffffL & o); + rd[12] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[13] - ((word32)0x0fffffffL & o)); rd[13] = u & 0xfffffff; + u += (sword32)rd[13] - (sword32)((word32)0x0fffffffL & o); + rd[13] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[14] - ((word32)0x0fffffffL & o)); rd[14] = u & 0xfffffff; + u += (sword32)rd[14] - (sword32)((word32)0x0fffffffL & o); + rd[14] = u & 0xfffffff; u >>= 28; - u += (sword32)(rd[15] - ((word32)0x03ffffffL & o)); rd[15] = u & 0xfffffff; + u += (sword32)rd[15] - (sword32)((word32)0x03ffffffL & o); + rd[15] = u & 0xfffffff; /* Convert to bytes */ r[ 0] = (byte)(rd[0 ] >> 0); r[ 1] = (byte)(rd[0 ] >> 8); r[ 2] = (byte)(rd[0 ] >> 16); - r[ 3] = (byte)(rd[0 ] >> 24) + (byte)((rd[1 ] >> 0) << 4); + r[ 3] = (byte)((byte)(rd[0 ] >> 24) + (byte)((rd[1 ] >> 0) << 4)); r[ 4] = (byte)(rd[1 ] >> 4); r[ 5] = (byte)(rd[1 ] >> 12); r[ 6] = (byte)(rd[1 ] >> 20); r[ 7] = (byte)(rd[2 ] >> 0); r[ 8] = (byte)(rd[2 ] >> 8); r[ 9] = (byte)(rd[2 ] >> 16); - r[10] = (byte)(rd[2 ] >> 24) + (byte)((rd[3 ] >> 0) << 4); + r[10] = (byte)((byte)(rd[2 ] >> 24) + (byte)((rd[3 ] >> 0) << 4)); r[11] = (byte)(rd[3 ] >> 4); r[12] = (byte)(rd[3 ] >> 12); r[13] = (byte)(rd[3 ] >> 20); r[14] = (byte)(rd[4 ] >> 0); r[15] = (byte)(rd[4 ] >> 8); r[16] = (byte)(rd[4 ] >> 16); - r[17] = (byte)(rd[4 ] >> 24) + (byte)((rd[5 ] >> 0) << 4); + r[17] = (byte)((byte)(rd[4 ] >> 24) + (byte)((rd[5 ] >> 0) << 4)); r[18] = (byte)(rd[5 ] >> 4); r[19] = (byte)(rd[5 ] >> 12); r[20] = (byte)(rd[5 ] >> 20); r[21] = (byte)(rd[6 ] >> 0); r[22] = (byte)(rd[6 ] >> 8); r[23] = (byte)(rd[6 ] >> 16); - r[24] = (byte)(rd[6 ] >> 24) + (byte)((rd[7 ] >> 0) << 4); + r[24] = (byte)((byte)(rd[6 ] >> 24) + (byte)((rd[7 ] >> 0) << 4)); r[25] = (byte)(rd[7 ] >> 4); r[26] = (byte)(rd[7 ] >> 12); r[27] = (byte)(rd[7 ] >> 20); r[28] = (byte)(rd[8 ] >> 0); r[29] = (byte)(rd[8 ] >> 8); r[30] = (byte)(rd[8 ] >> 16); - r[31] = (byte)(rd[8 ] >> 24) + (byte)((rd[9 ] >> 0) << 4); + r[31] = (byte)((byte)(rd[8 ] >> 24) + (byte)((rd[9 ] >> 0) << 4)); r[32] = (byte)(rd[9 ] >> 4); r[33] = (byte)(rd[9 ] >> 12); r[34] = (byte)(rd[9 ] >> 20); r[35] = (byte)(rd[10] >> 0); r[36] = (byte)(rd[10] >> 8); r[37] = (byte)(rd[10] >> 16); - r[38] = (byte)(rd[10] >> 24) + (byte)((rd[11] >> 0) << 4); + r[38] = (byte)((byte)(rd[10] >> 24) + (byte)((rd[11] >> 0) << 4)); r[39] = (byte)(rd[11] >> 4); r[40] = (byte)(rd[11] >> 12); r[41] = (byte)(rd[11] >> 20); r[42] = (byte)(rd[12] >> 0); r[43] = (byte)(rd[12] >> 8); r[44] = (byte)(rd[12] >> 16); - r[45] = (byte)(rd[12] >> 24) + (byte)((rd[13] >> 0) << 4); + r[45] = (byte)((byte)(rd[12] >> 24) + (byte)((rd[13] >> 0) << 4)); r[46] = (byte)(rd[13] >> 4); r[47] = (byte)(rd[13] >> 12); r[48] = (byte)(rd[13] >> 20); r[49] = (byte)(rd[14] >> 0); r[50] = (byte)(rd[14] >> 8); r[51] = (byte)(rd[14] >> 16); - r[52] = (byte)(rd[14] >> 24) + (byte)((rd[15] >> 0) << 4); + r[52] = (byte)((byte)(rd[14] >> 24) + (byte)((rd[15] >> 0) << 4)); r[53] = (byte)(rd[15] >> 4); r[54] = (byte)(rd[15] >> 12); r[55] = (byte)(rd[15] >> 20); diff --git a/src/wolfcrypt/src/ge_low_mem.c b/src/wolfcrypt/src/ge_low_mem.c index cb505af..c0a952b 100644 --- a/src/wolfcrypt/src/ge_low_mem.c +++ b/src/wolfcrypt/src/ge_low_mem.c @@ -1,6 +1,6 @@ /* ge_low_mem.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,20 +19,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include /* Based from Daniel Beer's public domain work. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - #ifdef HAVE_ED25519 #ifdef ED25519_SMALL /* use slower code that takes less memory */ #include -#include #ifdef NO_INLINE #include #else diff --git a/src/wolfcrypt/src/ge_operations.c b/src/wolfcrypt/src/ge_operations.c index 4a50d46..bde5a06 100644 --- a/src/wolfcrypt/src/ge_operations.c +++ b/src/wolfcrypt/src/ge_operations.c @@ -1,6 +1,6 @@ /* ge_operations.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -22,19 +22,13 @@ /* Based On Daniel J Bernstein's ed25519 Public Domain ref10 work. */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef HAVE_ED25519 #ifndef ED25519_SMALL /* run when not defined to use small memory math */ #include #include -#include #ifdef NO_INLINE #include #else @@ -9392,7 +9386,7 @@ B is the Ed25519 base point (x,4/5) with x positive. int ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) { -#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) signed char *aslide = NULL; signed char *bslide = NULL; ge_cached *Ai = NULL; /* A,3A,5A,7A,9A,11A,13A,15A */ @@ -9413,7 +9407,7 @@ int ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, #endif int i; -#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) if (((aslide = (signed char *)XMALLOC(SLIDE_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER))== NULL) || ((bslide = (signed char *)XMALLOC(SLIDE_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER))== NULL) || ((Ai = (ge_cached *)XMALLOC(8 * sizeof(*Ai), NULL, DYNAMIC_TYPE_TMP_BUFFER))== NULL) || @@ -9475,7 +9469,7 @@ int ge_double_scalarmult_vartime(ge_p2 *r, const unsigned char *a, } #endif -#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) out: XFREE(aslide, NULL, DYNAMIC_TYPE_TMP_BUFFER); diff --git a/src/wolfcrypt/src/hash.c b/src/wolfcrypt/src/hash.c index 4850a84..c709fa3 100644 --- a/src/wolfcrypt/src/hash.c +++ b/src/wolfcrypt/src/hash.c @@ -1,6 +1,6 @@ /* hash.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,14 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include -#ifdef HAVE_CONFIG_H - #include -#endif - -#include -#include -#include #ifndef NO_ASN #include #endif diff --git a/src/wolfcrypt/src/hmac.c b/src/wolfcrypt/src/hmac.c index 65dbf66..912b26d 100644 --- a/src/wolfcrypt/src/hmac.c +++ b/src/wolfcrypt/src/hmac.c @@ -1,6 +1,6 @@ /* hmac.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -20,14 +20,7 @@ */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include -#include -#include -#include +#include #ifndef NO_HMAC @@ -155,76 +148,72 @@ int wc_HmacSizeByType(int type) return ret; } -int _InitHmac(Hmac* hmac, int type, void* heap) +static int HmacKeyInitHash(wc_HmacHash* hash, int type, void* heap, int devId) { int ret = 0; -#ifdef WOLF_CRYPTO_CB - int devId = hmac->devId; -#else - int devId = INVALID_DEVID; -#endif + switch (type) { #ifndef NO_MD5 case WC_MD5: - ret = wc_InitMd5_ex(&hmac->hash.md5, heap, devId); + ret = wc_InitMd5_ex(&hash->md5, heap, devId); break; #endif /* !NO_MD5 */ #ifndef NO_SHA case WC_SHA: - ret = wc_InitSha_ex(&hmac->hash.sha, heap, devId); + ret = wc_InitSha_ex(&hash->sha, heap, devId); break; #endif /* !NO_SHA */ #ifdef WOLFSSL_SHA224 case WC_SHA224: - ret = wc_InitSha224_ex(&hmac->hash.sha224, heap, devId); + ret = wc_InitSha224_ex(&hash->sha224, heap, devId); break; #endif /* WOLFSSL_SHA224 */ #ifndef NO_SHA256 case WC_SHA256: - ret = wc_InitSha256_ex(&hmac->hash.sha256, heap, devId); + ret = wc_InitSha256_ex(&hash->sha256, heap, devId); break; #endif /* !NO_SHA256 */ #ifdef WOLFSSL_SHA384 case WC_SHA384: - ret = wc_InitSha384_ex(&hmac->hash.sha384, heap, devId); + ret = wc_InitSha384_ex(&hash->sha384, heap, devId); break; #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA512 case WC_SHA512: - ret = wc_InitSha512_ex(&hmac->hash.sha512, heap, devId); + ret = wc_InitSha512_ex(&hash->sha512, heap, devId); break; #endif /* WOLFSSL_SHA512 */ #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 case WC_SHA3_224: - ret = wc_InitSha3_224(&hmac->hash.sha3, heap, devId); + ret = wc_InitSha3_224(&hash->sha3, heap, devId); break; #endif #ifndef WOLFSSL_NOSHA3_256 case WC_SHA3_256: - ret = wc_InitSha3_256(&hmac->hash.sha3, heap, devId); + ret = wc_InitSha3_256(&hash->sha3, heap, devId); break; #endif #ifndef WOLFSSL_NOSHA3_384 case WC_SHA3_384: - ret = wc_InitSha3_384(&hmac->hash.sha3, heap, devId); + ret = wc_InitSha3_384(&hash->sha3, heap, devId); break; #endif #ifndef WOLFSSL_NOSHA3_512 case WC_SHA3_512: - ret = wc_InitSha3_512(&hmac->hash.sha3, heap, devId); + ret = wc_InitSha3_512(&hash->sha3, heap, devId); break; #endif #endif #ifdef WOLFSSL_SM3 case WC_SM3: - ret = wc_InitSm3(&hmac->hash.sm3, heap, devId); + ret = wc_InitSm3(&hash->sm3, heap, devId); break; #endif @@ -233,6 +222,22 @@ int _InitHmac(Hmac* hmac, int type, void* heap) break; } + return ret; +} + +int _InitHmac(Hmac* hmac, int type, void* heap) +{ + int ret; +#ifdef WOLF_CRYPTO_CB + int devId = hmac->devId; +#else + int devId = INVALID_DEVID; +#endif + + ret = HmacKeyInitHash(&hmac->hash, type, heap, devId); + if (ret != 0) + return ret; + /* default to NULL heap hint or test value */ #ifdef WOLFSSL_HEAP_TEST hmac->heap = (void*)WOLFSSL_HEAP_TEST; @@ -243,6 +248,158 @@ int _InitHmac(Hmac* hmac, int type, void* heap) return ret; } +#ifdef WOLFSSL_HMAC_COPY_HASH +static int HmacKeyCopyHash(byte macType, wc_HmacHash* src, wc_HmacHash* dst) +{ + int ret = 0; + + switch (macType) { + #ifndef NO_MD5 + case WC_MD5: + ret = wc_Md5Copy(&src->md5, &dst->md5); + break; + #endif /* !NO_MD5 */ + + #ifndef NO_SHA + case WC_SHA: + ret = wc_ShaCopy(&src->sha, &dst->sha); + break; + #endif /* !NO_SHA */ + + #ifdef WOLFSSL_SHA224 + case WC_SHA224: + ret = wc_Sha224Copy(&src->sha224, &dst->sha224); + break; + #endif /* WOLFSSL_SHA224 */ + #ifndef NO_SHA256 + case WC_SHA256: + ret = wc_Sha256Copy(&src->sha256, &dst->sha256); + break; + #endif /* !NO_SHA256 */ + + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + ret = wc_Sha384Copy(&src->sha384, &dst->sha384); + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case WC_SHA512: + ret = wc_Sha512Copy(&src->sha512, &dst->sha512); + break; + #endif /* WOLFSSL_SHA512 */ + + #ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 + case WC_SHA3_224: + ret = wc_Sha3_224_Copy(&src->sha3, &dst->sha3); + break; + #endif + #ifndef WOLFSSL_NOSHA3_256 + case WC_SHA3_256: + ret = wc_Sha3_256_Copy(&src->sha3, &dst->sha3); + break; + #endif + #ifndef WOLFSSL_NOSHA3_384 + case WC_SHA3_384: + ret = wc_Sha3_384_Copy(&src->sha3, &dst->sha3); + break; + #endif + #ifndef WOLFSSL_NOSHA3_512 + case WC_SHA3_512: + ret = wc_Sha3_512_Copy(&src->sha3, &dst->sha3); + break; + #endif + #endif /* WOLFSSL_SHA3 */ + + #ifdef WOLFSSL_SM3 + case WC_SM3: + ret = wc_Sm3Copy(&src->sm3, &dst->sm3); + break; + #endif + + default: + break; + } + + return ret; +} +#endif + +static int HmacKeyHashUpdate(byte macType, wc_HmacHash* hash, byte* pad) +{ + int ret = 0; + + switch (macType) { + #ifndef NO_MD5 + case WC_MD5: + ret = wc_Md5Update(&hash->md5, pad, WC_MD5_BLOCK_SIZE); + break; + #endif /* !NO_MD5 */ + + #ifndef NO_SHA + case WC_SHA: + ret = wc_ShaUpdate(&hash->sha, pad, WC_SHA_BLOCK_SIZE); + break; + #endif /* !NO_SHA */ + + #ifdef WOLFSSL_SHA224 + case WC_SHA224: + ret = wc_Sha224Update(&hash->sha224, pad, WC_SHA224_BLOCK_SIZE); + break; + #endif /* WOLFSSL_SHA224 */ + #ifndef NO_SHA256 + case WC_SHA256: + ret = wc_Sha256Update(&hash->sha256, pad, WC_SHA256_BLOCK_SIZE); + break; + #endif /* !NO_SHA256 */ + + #ifdef WOLFSSL_SHA384 + case WC_SHA384: + ret = wc_Sha384Update(&hash->sha384, pad, WC_SHA384_BLOCK_SIZE); + break; + #endif /* WOLFSSL_SHA384 */ + #ifdef WOLFSSL_SHA512 + case WC_SHA512: + ret = wc_Sha512Update(&hash->sha512, pad, WC_SHA512_BLOCK_SIZE); + break; + #endif /* WOLFSSL_SHA512 */ + + #ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 + case WC_SHA3_224: + ret = wc_Sha3_224_Update(&hash->sha3, pad, WC_SHA3_224_BLOCK_SIZE); + break; + #endif + #ifndef WOLFSSL_NOSHA3_256 + case WC_SHA3_256: + ret = wc_Sha3_256_Update(&hash->sha3, pad, WC_SHA3_256_BLOCK_SIZE); + break; + #endif + #ifndef WOLFSSL_NOSHA3_384 + case WC_SHA3_384: + ret = wc_Sha3_384_Update(&hash->sha3, pad, WC_SHA3_384_BLOCK_SIZE); + break; + #endif + #ifndef WOLFSSL_NOSHA3_512 + case WC_SHA3_512: + ret = wc_Sha3_512_Update(&hash->sha3, pad, WC_SHA3_512_BLOCK_SIZE); + break; + #endif + #endif /* WOLFSSL_SHA3 */ + + #ifdef WOLFSSL_SM3 + case WC_SM3: + ret = wc_Sm3Update(&hash->sm3, pad, WC_SM3_BLOCK_SIZE); + break; + #endif + + default: + break; + } + + return ret; +} + int wc_HmacSetKey_ex(Hmac* hmac, int type, const byte* key, word32 length, int allowFlag) @@ -603,6 +760,29 @@ int wc_HmacSetKey_ex(Hmac* hmac, int type, const byte* key, word32 length, } } +#ifdef WOLFSSL_HMAC_COPY_HASH + if ( ret == 0) { + #ifdef WOLF_CRYPTO_CB + int devId = hmac->devId; + #else + int devId = INVALID_DEVID; + #endif + + ret = HmacKeyInitHash(&hmac->i_hash, hmac->macType, heap, devId); + if (ret != 0) + return ret; + ret = HmacKeyInitHash(&hmac->o_hash, hmac->macType, heap, devId); + if (ret != 0) + return ret; + ret = HmacKeyHashUpdate(hmac->macType, &hmac->i_hash, ip); + if (ret != 0) + return ret; + ret = HmacKeyHashUpdate(hmac->macType, &hmac->o_hash, op); + if (ret != 0) + return ret; + } +#endif + return ret; #endif /* WOLFSSL_MAXQ108X */ } @@ -618,96 +798,6 @@ int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) return wc_HmacSetKey_ex(hmac, type, key, length, allowFlag); } -static int HmacKeyInnerHash(Hmac* hmac) -{ - int ret = 0; - - switch (hmac->macType) { - #ifndef NO_MD5 - case WC_MD5: - ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->ipad, - WC_MD5_BLOCK_SIZE); - break; - #endif /* !NO_MD5 */ - - #ifndef NO_SHA - case WC_SHA: - ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->ipad, - WC_SHA_BLOCK_SIZE); - break; - #endif /* !NO_SHA */ - - #ifdef WOLFSSL_SHA224 - case WC_SHA224: - ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->ipad, - WC_SHA224_BLOCK_SIZE); - break; - #endif /* WOLFSSL_SHA224 */ - #ifndef NO_SHA256 - case WC_SHA256: - ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->ipad, - WC_SHA256_BLOCK_SIZE); - break; - #endif /* !NO_SHA256 */ - - #ifdef WOLFSSL_SHA384 - case WC_SHA384: - ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->ipad, - WC_SHA384_BLOCK_SIZE); - break; - #endif /* WOLFSSL_SHA384 */ - #ifdef WOLFSSL_SHA512 - case WC_SHA512: - ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->ipad, - WC_SHA512_BLOCK_SIZE); - break; - #endif /* WOLFSSL_SHA512 */ - - #ifdef WOLFSSL_SHA3 - #ifndef WOLFSSL_NOSHA3_224 - case WC_SHA3_224: - ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->ipad, - WC_SHA3_224_BLOCK_SIZE); - break; - #endif - #ifndef WOLFSSL_NOSHA3_256 - case WC_SHA3_256: - ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->ipad, - WC_SHA3_256_BLOCK_SIZE); - break; - #endif - #ifndef WOLFSSL_NOSHA3_384 - case WC_SHA3_384: - ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->ipad, - WC_SHA3_384_BLOCK_SIZE); - break; - #endif - #ifndef WOLFSSL_NOSHA3_512 - case WC_SHA3_512: - ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->ipad, - WC_SHA3_512_BLOCK_SIZE); - break; - #endif - #endif /* WOLFSSL_SHA3 */ - - #ifdef WOLFSSL_SM3 - case WC_SM3: - ret = wc_Sm3Update(&hmac->hash.sm3, (byte*)hmac->ipad, - WC_SM3_BLOCK_SIZE); - break; - #endif - - default: - break; - } - - if (ret == 0) - hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_SW; - - return ret; -} - - int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length) { int ret = 0; @@ -739,9 +829,14 @@ int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length) #endif /* WOLFSSL_ASYNC_CRYPT */ if (!hmac->innerHashKeyed) { - ret = HmacKeyInnerHash(hmac); +#ifndef WOLFSSL_HMAC_COPY_HASH + ret = HmacKeyHashUpdate(hmac->macType, &hmac->hash, (byte*)hmac->ipad); +#else + ret = HmacKeyCopyHash(hmac->macType, &hmac->i_hash, &hmac->hash); +#endif if (ret != 0) return ret; + hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_SW; } switch (hmac->macType) { @@ -851,9 +946,14 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) #endif /* WOLFSSL_ASYNC_CRYPT */ if (!hmac->innerHashKeyed) { - ret = HmacKeyInnerHash(hmac); +#ifndef WOLFSSL_HMAC_COPY_HASH + ret = HmacKeyHashUpdate(hmac->macType, &hmac->hash, (byte*)hmac->ipad); +#else + ret = HmacKeyCopyHash(hmac->macType, &hmac->i_hash, &hmac->hash); +#endif if (ret != 0) return ret; + hmac->innerHashKeyed = WC_HMAC_INNER_HASH_KEYED_SW; } switch (hmac->macType) { @@ -862,8 +962,12 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) ret = wc_Md5Final(&hmac->hash.md5, (byte*)hmac->innerHash); if (ret != 0) break; + #ifndef WOLFSSL_HMAC_COPY_HASH ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->opad, WC_MD5_BLOCK_SIZE); + #else + ret = HmacKeyCopyHash(WC_MD5, &hmac->o_hash, &hmac->hash); + #endif if (ret != 0) break; ret = wc_Md5Update(&hmac->hash.md5, (byte*)hmac->innerHash, @@ -879,8 +983,12 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) ret = wc_ShaFinal(&hmac->hash.sha, (byte*)hmac->innerHash); if (ret != 0) break; + #ifndef WOLFSSL_HMAC_COPY_HASH ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->opad, WC_SHA_BLOCK_SIZE); + #else + ret = HmacKeyCopyHash(WC_SHA, &hmac->o_hash, &hmac->hash); + #endif if (ret != 0) break; ret = wc_ShaUpdate(&hmac->hash.sha, (byte*)hmac->innerHash, @@ -896,8 +1004,12 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) ret = wc_Sha224Final(&hmac->hash.sha224, (byte*)hmac->innerHash); if (ret != 0) break; + #ifndef WOLFSSL_HMAC_COPY_HASH ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->opad, WC_SHA224_BLOCK_SIZE); + #else + ret = HmacKeyCopyHash(WC_SHA224, &hmac->o_hash, &hmac->hash); + #endif if (ret != 0) break; ret = wc_Sha224Update(&hmac->hash.sha224, (byte*)hmac->innerHash, @@ -914,8 +1026,12 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) ret = wc_Sha256Final(&hmac->hash.sha256, (byte*)hmac->innerHash); if (ret != 0) break; + #ifndef WOLFSSL_HMAC_COPY_HASH ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->opad, WC_SHA256_BLOCK_SIZE); + #else + ret = HmacKeyCopyHash(WC_SHA256, &hmac->o_hash, &hmac->hash); + #endif if (ret != 0) break; ret = wc_Sha256Update(&hmac->hash.sha256, (byte*)hmac->innerHash, @@ -931,8 +1047,12 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) ret = wc_Sha384Final(&hmac->hash.sha384, (byte*)hmac->innerHash); if (ret != 0) break; + #ifndef WOLFSSL_HMAC_COPY_HASH ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->opad, WC_SHA384_BLOCK_SIZE); + #else + ret = HmacKeyCopyHash(WC_SHA384, &hmac->o_hash, &hmac->hash); + #endif if (ret != 0) break; ret = wc_Sha384Update(&hmac->hash.sha384, (byte*)hmac->innerHash, @@ -947,8 +1067,12 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) ret = wc_Sha512Final(&hmac->hash.sha512, (byte*)hmac->innerHash); if (ret != 0) break; + #ifndef WOLFSSL_HMAC_COPY_HASH ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->opad, WC_SHA512_BLOCK_SIZE); + #else + ret = HmacKeyCopyHash(WC_SHA512, &hmac->o_hash, &hmac->hash); + #endif if (ret != 0) break; ret = wc_Sha512Update(&hmac->hash.sha512, (byte*)hmac->innerHash, @@ -965,8 +1089,12 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) ret = wc_Sha3_224_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); if (ret != 0) break; + #ifndef WOLFSSL_HMAC_COPY_HASH ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->opad, WC_SHA3_224_BLOCK_SIZE); + #else + ret = HmacKeyCopyHash(WC_SHA3_224, &hmac->o_hash, &hmac->hash); + #endif if (ret != 0) break; ret = wc_Sha3_224_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, @@ -981,8 +1109,12 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) ret = wc_Sha3_256_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); if (ret != 0) break; + #ifndef WOLFSSL_HMAC_COPY_HASH ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->opad, WC_SHA3_256_BLOCK_SIZE); + #else + ret = HmacKeyCopyHash(WC_SHA3_256, &hmac->o_hash, &hmac->hash); + #endif if (ret != 0) break; ret = wc_Sha3_256_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, @@ -997,8 +1129,12 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) ret = wc_Sha3_384_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); if (ret != 0) break; + #ifndef WOLFSSL_HMAC_COPY_HASH ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->opad, WC_SHA3_384_BLOCK_SIZE); + #else + ret = HmacKeyCopyHash(WC_SHA3_384, &hmac->o_hash, &hmac->hash); + #endif if (ret != 0) break; ret = wc_Sha3_384_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, @@ -1013,8 +1149,12 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) ret = wc_Sha3_512_Final(&hmac->hash.sha3, (byte*)hmac->innerHash); if (ret != 0) break; + #ifndef WOLFSSL_HMAC_COPY_HASH ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->opad, WC_SHA3_512_BLOCK_SIZE); + #else + ret = HmacKeyCopyHash(WC_SHA3_512, &hmac->o_hash, &hmac->hash); + #endif if (ret != 0) break; ret = wc_Sha3_512_Update(&hmac->hash.sha3, (byte*)hmac->innerHash, @@ -1031,8 +1171,12 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) ret = wc_Sm3Final(&hmac->hash.sm3, (byte*)hmac->innerHash); if (ret != 0) break; + #ifndef WOLFSSL_HMAC_COPY_HASH ret = wc_Sm3Update(&hmac->hash.sm3, (byte*)hmac->opad, WC_SM3_BLOCK_SIZE); + #else + ret = HmacKeyCopyHash(WC_SM3, &hmac->o_hash, &hmac->hash); + #endif if (ret != 0) break; ret = wc_Sm3Update(&hmac->hash.sm3, (byte*)hmac->innerHash, @@ -1163,34 +1307,58 @@ void wc_HmacFree(Hmac* hmac) #ifndef NO_MD5 case WC_MD5: wc_Md5Free(&hmac->hash.md5); + #ifdef WOLFSSL_HMAC_COPY_HASH + wc_Md5Free(&hmac->i_hash.md5); + wc_Md5Free(&hmac->o_hash.md5); + #endif break; #endif /* !NO_MD5 */ #ifndef NO_SHA case WC_SHA: wc_ShaFree(&hmac->hash.sha); + #ifdef WOLFSSL_HMAC_COPY_HASH + wc_ShaFree(&hmac->i_hash.sha); + wc_ShaFree(&hmac->o_hash.sha); + #endif break; #endif /* !NO_SHA */ #ifdef WOLFSSL_SHA224 case WC_SHA224: wc_Sha224Free(&hmac->hash.sha224); + #ifdef WOLFSSL_HMAC_COPY_HASH + wc_Sha224Free(&hmac->i_hash.sha224); + wc_Sha224Free(&hmac->o_hash.sha224); + #endif break; #endif /* WOLFSSL_SHA224 */ #ifndef NO_SHA256 case WC_SHA256: wc_Sha256Free(&hmac->hash.sha256); + #ifdef WOLFSSL_HMAC_COPY_HASH + wc_Sha256Free(&hmac->i_hash.sha256); + wc_Sha256Free(&hmac->o_hash.sha256); + #endif break; #endif /* !NO_SHA256 */ #ifdef WOLFSSL_SHA384 case WC_SHA384: wc_Sha384Free(&hmac->hash.sha384); + #ifdef WOLFSSL_HMAC_COPY_HASH + wc_Sha384Free(&hmac->i_hash.sha384); + wc_Sha384Free(&hmac->o_hash.sha384); + #endif break; #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA512 case WC_SHA512: wc_Sha512Free(&hmac->hash.sha512); + #ifdef WOLFSSL_HMAC_COPY_HASH + wc_Sha512Free(&hmac->i_hash.sha512); + wc_Sha512Free(&hmac->o_hash.sha512); + #endif break; #endif /* WOLFSSL_SHA512 */ @@ -1198,21 +1366,37 @@ void wc_HmacFree(Hmac* hmac) #ifndef WOLFSSL_NOSHA3_224 case WC_SHA3_224: wc_Sha3_224_Free(&hmac->hash.sha3); + #ifdef WOLFSSL_HMAC_COPY_HASH + wc_Sha3_224_Free(&hmac->i_hash.sha3); + wc_Sha3_224_Free(&hmac->o_hash.sha3); + #endif break; #endif #ifndef WOLFSSL_NOSHA3_256 case WC_SHA3_256: wc_Sha3_256_Free(&hmac->hash.sha3); + #ifdef WOLFSSL_HMAC_COPY_HASH + wc_Sha3_256_Free(&hmac->i_hash.sha3); + wc_Sha3_256_Free(&hmac->o_hash.sha3); + #endif break; #endif #ifndef WOLFSSL_NOSHA3_384 case WC_SHA3_384: wc_Sha3_384_Free(&hmac->hash.sha3); + #ifdef WOLFSSL_HMAC_COPY_HASH + wc_Sha3_384_Free(&hmac->i_hash.sha3); + wc_Sha3_384_Free(&hmac->o_hash.sha3); + #endif break; #endif #ifndef WOLFSSL_NOSHA3_512 case WC_SHA3_512: wc_Sha3_512_Free(&hmac->hash.sha3); + #ifdef WOLFSSL_HMAC_COPY_HASH + wc_Sha3_512_Free(&hmac->i_hash.sha3); + wc_Sha3_512_Free(&hmac->o_hash.sha3); + #endif break; #endif #endif /* WOLFSSL_SHA3 */ @@ -1220,6 +1404,10 @@ void wc_HmacFree(Hmac* hmac) #ifdef WOLFSSL_SM3 case WC_SM3: wc_Sm3Free(&hmac->hash.sm3); + #ifdef WOLFSSL_HMAC_COPY_HASH + wc_Sm3Free(&hmac->i_hash.sm3); + wc_Sm3Free(&hmac->i_hash.sm3); + #endif break; #endif diff --git a/src/wolfcrypt/src/hpke.c b/src/wolfcrypt/src/hpke.c index 02e189b..8ce209f 100644 --- a/src/wolfcrypt/src/hpke.c +++ b/src/wolfcrypt/src/hpke.c @@ -1,6 +1,6 @@ /* hpke.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -23,16 +23,11 @@ * TODO: Add X448 and ChaCha20 */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if defined(HAVE_HPKE) && (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ defined(HAVE_AESGCM) -#include #include #include #include @@ -591,6 +586,10 @@ static int wc_HpkeContextComputeNonce(Hpke* hpke, HpkeBaseContext* context, int ret; byte seq_bytes[HPKE_Nn_MAX]; + if (hpke == NULL || context == NULL) { + return BAD_FUNC_ARG; + } + /* convert the sequence into a byte string with the same length as the * nonce */ ret = I2OSP(context->seq, (int)hpke->Nn, seq_bytes); @@ -875,49 +874,63 @@ static int wc_HpkeSetupBaseSender(Hpke* hpke, HpkeBaseContext* context, return ret; } +/* give SetupBaseSender a more intuitive and wolfCrypt friendly name */ +int wc_HpkeInitSealContext(Hpke* hpke, HpkeBaseContext* context, + void* ephemeralKey, void* receiverKey, byte* info, word32 infoSz) +{ + if (hpke == NULL || context == NULL || ephemeralKey == NULL || + receiverKey == NULL || (info == NULL && infoSz > 0)) { + return BAD_FUNC_ARG; + } + + /* zero out all fields */ + XMEMSET(context, 0, sizeof(HpkeBaseContext)); + + return wc_HpkeSetupBaseSender(hpke, context, ephemeralKey, receiverKey, + info, infoSz); +} + /* encrypt a message using an hpke base context, return 0 or error */ -static int wc_HpkeContextSealBase(Hpke* hpke, HpkeBaseContext* context, +int wc_HpkeContextSealBase(Hpke* hpke, HpkeBaseContext* context, byte* aad, word32 aadSz, byte* plaintext, word32 ptSz, byte* out) { int ret; byte nonce[HPKE_Nn_MAX]; #ifndef WOLFSSL_SMALL_STACK - Aes aes_key[1]; + Aes aes[1]; #else - Aes* aes_key; + Aes* aes; #endif - - if (hpke == NULL) { + if (hpke == NULL || context == NULL || (aad == NULL && aadSz > 0) || + plaintext == NULL || out == NULL) { return BAD_FUNC_ARG; } - #ifdef WOLFSSL_SMALL_STACK - aes_key = (Aes*)XMALLOC(sizeof(Aes), hpke->heap, DYNAMIC_TYPE_AES); - if (aes_key == NULL) { + aes = (Aes*)XMALLOC(sizeof(Aes), hpke->heap, DYNAMIC_TYPE_AES); + if (aes == NULL) { return MEMORY_E; } #endif - - ret = wc_AesInit(aes_key, hpke->heap, INVALID_DEVID); + ret = wc_AesInit(aes, hpke->heap, INVALID_DEVID); if (ret == 0) { + /* compute nonce */ ret = wc_HpkeContextComputeNonce(hpke, context, nonce); if (ret == 0) { - ret = wc_AesGcmSetKey(aes_key, context->key, hpke->Nk); + ret = wc_AesGcmSetKey(aes, context->key, hpke->Nk); } if (ret == 0) { - ret = wc_AesGcmEncrypt(aes_key, out, plaintext, ptSz, nonce, + ret = wc_AesGcmEncrypt(aes, out, plaintext, ptSz, nonce, hpke->Nn, out + ptSz, hpke->Nt, aad, aadSz); } + /* increment sequence for non one shot */ if (ret == 0) { context->seq++; } - wc_AesFree(aes_key); + wc_AesFree(aes); } - #ifdef WOLFSSL_SMALL_STACK - XFREE(aes_key, hpke->heap, DYNAMIC_TYPE_AES); + XFREE(aes, hpke->heap, DYNAMIC_TYPE_AES); #endif - return ret; } @@ -1021,8 +1034,10 @@ static int wc_HpkeDecap(Hpke* hpke, void* receiverKey, const byte* pubKey, #ifdef ECC_TIMING_RESISTANT rng = wc_rng_new(NULL, 0, hpke->heap); - if (rng == NULL) - return RNG_FAILURE_E; + if (rng == NULL) { + ret = RNG_FAILURE_E; + break; + } wc_ecc_set_rng((ecc_key*)receiverKey, rng); #endif @@ -1111,49 +1126,60 @@ static int wc_HpkeSetupBaseReceiver(Hpke* hpke, HpkeBaseContext* context, return ret; } +/* give SetupBaseReceiver a more intuitive and wolfCrypt friendly name */ +int wc_HpkeInitOpenContext(Hpke* hpke, HpkeBaseContext* context, + void* receiverKey, const byte* pubKey, word16 pubKeySz, byte* info, + word32 infoSz) +{ + if (hpke == NULL || context == NULL || receiverKey == NULL || pubKey == NULL + || (info == NULL && infoSz > 0)) { + return BAD_FUNC_ARG; + } + + return wc_HpkeSetupBaseReceiver(hpke, context, receiverKey, pubKey, + pubKeySz, info, infoSz); +} + /* decrypt a message using a setup hpke context, return 0 or error */ -static int wc_HpkeContextOpenBase(Hpke* hpke, HpkeBaseContext* context, - byte* aad, word32 aadSz, byte* ciphertext, word32 ctSz, byte* out) +int wc_HpkeContextOpenBase(Hpke* hpke, HpkeBaseContext* context, byte* aad, + word32 aadSz, byte* ciphertext, word32 ctSz, byte* out) { int ret; byte nonce[HPKE_Nn_MAX]; #ifndef WOLFSSL_SMALL_STACK - Aes aes_key[1]; + Aes aes[1]; #else - Aes* aes_key; + Aes* aes; #endif - if (hpke == NULL) { return BAD_FUNC_ARG; } - XMEMSET(nonce, 0, sizeof(nonce)); #ifdef WOLFSSL_SMALL_STACK - aes_key = (Aes*)XMALLOC(sizeof(Aes), hpke->heap, DYNAMIC_TYPE_AES); - if (aes_key == NULL) { + aes = (Aes*)XMALLOC(sizeof(Aes), hpke->heap, DYNAMIC_TYPE_AES); + if (aes == NULL) { return MEMORY_E; } #endif - + /* compute nonce */ ret = wc_HpkeContextComputeNonce(hpke, context, nonce); if (ret == 0) - ret = wc_AesInit(aes_key, hpke->heap, INVALID_DEVID); + ret = wc_AesInit(aes, hpke->heap, INVALID_DEVID); if (ret == 0) { - ret = wc_AesGcmSetKey(aes_key, context->key, hpke->Nk); + ret = wc_AesGcmSetKey(aes, context->key, hpke->Nk); if (ret == 0) { - ret = wc_AesGcmDecrypt(aes_key, out, ciphertext, ctSz, nonce, + ret = wc_AesGcmDecrypt(aes, out, ciphertext, ctSz, nonce, hpke->Nn, ciphertext + ctSz, hpke->Nt, aad, aadSz); } + /* increment sequence for non one shot */ if (ret == 0) { context->seq++; } - wc_AesFree(aes_key); + wc_AesFree(aes); } - #ifdef WOLFSSL_SMALL_STACK - XFREE(aes_key, hpke->heap, DYNAMIC_TYPE_AES); + XFREE(aes, hpke->heap, DYNAMIC_TYPE_AES); #endif - return ret; } diff --git a/src/wolfcrypt/src/integer.c b/src/wolfcrypt/src/integer.c index 3deeaeb..341d99d 100644 --- a/src/wolfcrypt/src/integer.c +++ b/src/wolfcrypt/src/integer.c @@ -1,6 +1,6 @@ /* integer.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,21 +19,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - +#include /* * Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca, * http://math.libtomcrypt.com */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -/* in case user set USE_FAST_MATH there */ -#include - #ifndef NO_BIG_INT #if !defined(USE_FAST_MATH) && defined(USE_INTEGER_HEAP_MATH) @@ -177,6 +169,9 @@ int mp_init (mp_int * a) /* clear one (frees) */ void mp_clear (mp_int * a) { +#ifdef HAVE_FIPS + mp_forcezero(a); +#else int i; if (a == NULL) @@ -202,6 +197,7 @@ void mp_clear (mp_int * a) a->alloc = a->used = 0; a->sign = MP_ZPOS; } +#endif } void mp_free (mp_int * a) @@ -409,11 +405,10 @@ int mp_copy (const mp_int * a, mp_int * b) /* grow as required */ int mp_grow (mp_int * a, int size) { - int i; mp_digit *tmp; /* if the alloc size is smaller alloc more ram */ - if (a->alloc < size || size == 0) { + if ((a->alloc < size) || (size == 0) || (a->alloc == 0)) { /* ensure there are always at least MP_PREC digits extra on top */ size += (MP_PREC * 2) - (size % MP_PREC); @@ -434,11 +429,12 @@ int mp_grow (mp_int * a, int size) a->dp = tmp; /* zero excess digits */ - i = a->alloc; + XMEMSET(&a->dp[a->alloc], 0, sizeof (mp_digit) * (size - a->alloc)); a->alloc = size; - for (; i < a->alloc; i++) { - a->dp[i] = 0; - } + } + else if (a->dp == NULL) { + /* opportunistic sanity check for null a->dp with nonzero a->alloc */ + return MP_VAL; } return MP_OKAY; } @@ -1758,6 +1754,13 @@ int s_mp_add (mp_int * a, mp_int * b, mp_int * c) /* destination */ tmpc = c->dp; + /* sanity-check dp pointers. */ + if ((min_ab > 0) && + ((tmpa == NULL) || (tmpb == NULL) || (tmpc == NULL))) + { + return MP_VAL; + } + /* zero the carry */ u = 0; for (i = 0; i < min_ab; i++) { @@ -1833,6 +1836,13 @@ int s_mp_sub (mp_int * a, mp_int * b, mp_int * c) tmpb = b->dp; tmpc = c->dp; + /* sanity-check dp pointers from a and b. */ + if ((min_b > 0) && + ((tmpa == NULL) || (tmpb == NULL))) + { + return MP_VAL; + } + /* set carry to zero */ u = 0; for (i = 0; i < min_b; i++) { @@ -3290,6 +3300,10 @@ int mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) q.used = a->used; q.sign = a->sign; w = 0; + + if (a->used == 0) + return MP_VAL; + for (ix = a->used - 1; ix >= 0; ix--) { w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); @@ -3332,8 +3346,6 @@ int mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) /* init an mp_init for a given size */ int mp_init_size (mp_int * a, int size) { - int x; - /* pad size so there are always extra digits */ size += (MP_PREC * 2) - (size % MP_PREC); @@ -3353,9 +3365,7 @@ int mp_init_size (mp_int * a, int size) #endif /* zero the digits */ - for (x = 0; x < size; x++) { - a->dp[x] = 0; - } + XMEMSET(a->dp, 0, sizeof (mp_digit) * size); return MP_OKAY; } @@ -4681,8 +4691,11 @@ static int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) } } - w = 0; + + if (a->used == 0) + return MP_VAL; + for (ix = a->used - 1; ix >= 0; ix--) { w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); diff --git a/src/wolfcrypt/src/kdf.c b/src/wolfcrypt/src/kdf.c index c45c635..0e092dd 100644 --- a/src/wolfcrypt/src/kdf.c +++ b/src/wolfcrypt/src/kdf.c @@ -1,6 +1,6 @@ /* kdf.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,15 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include -#include -#include -#include +#include #ifndef NO_KDF @@ -814,7 +806,7 @@ int wc_SSH_KDF(byte hashId, byte keyId, byte* key, word32 keySz, return BAD_FUNC_ARG; } - ret = wc_HmacSizeByType(enmhashId); + ret = wc_HmacSizeByType((int)enmhashId); if (ret <= 0) { return BAD_FUNC_ARG; } @@ -1051,11 +1043,7 @@ int wc_SRTP_KDF(const byte* key, word32 keySz, const byte* salt, word32 saltSz, ret = MEMORY_E; } } - if (aes != NULL) #endif - { - XMEMSET(aes, 0, sizeof(Aes)); - } /* Setup AES object. */ if (ret == 0) { @@ -1155,11 +1143,7 @@ int wc_SRTCP_KDF_ex(const byte* key, word32 keySz, const byte* salt, word32 salt ret = MEMORY_E; } } - if (aes != NULL) #endif - { - XMEMSET(aes, 0, sizeof(Aes)); - } /* Setup AES object. */ if (ret == 0) { @@ -1256,11 +1240,7 @@ int wc_SRTP_KDF_label(const byte* key, word32 keySz, const byte* salt, ret = MEMORY_E; } } - if (aes != NULL) #endif - { - XMEMSET(aes, 0, sizeof(Aes)); - } /* Setup AES object. */ if (ret == 0) { @@ -1339,11 +1319,7 @@ int wc_SRTCP_KDF_label(const byte* key, word32 keySz, const byte* salt, ret = MEMORY_E; } } - if (aes != NULL) #endif - { - XMEMSET(aes, 0, sizeof(Aes)); - } /* Setup AES object. */ if (ret == 0) { diff --git a/src/wolfcrypt/src/logging.c b/src/wolfcrypt/src/logging.c index d548cd6..29b9221 100644 --- a/src/wolfcrypt/src/logging.c +++ b/src/wolfcrypt/src/logging.c @@ -1,6 +1,6 @@ /* logging.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,15 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - -#include -#include #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) /* avoid adding WANT_READ and WANT_WRITE to error queue */ #include @@ -265,7 +258,6 @@ void WOLFSSL_TIME(int count) /* the requisite linux/kernel.h is included in wc_port.h, with incompatible warnings masked out. */ #elif defined(FUSION_RTOS) #include - #include #define fprintf FCL_FPRINTF #else #include /* for default printf stuff */ @@ -904,7 +896,7 @@ unsigned long wc_PeekErrorNodeLineData(const char **file, int *line, * Get the error value at the HEAD of the ERR queue or 0 if the queue * is empty. The HEAD entry is removed by this call. */ -unsigned long wc_GetErrorNodeErr(void) +int wc_GetErrorNodeErr(void) { int ret; @@ -923,7 +915,7 @@ unsigned long wc_GetErrorNodeErr(void) wc_ClearErrorNodes(); } } - return (unsigned long)ret; + return ret; } #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) @@ -1171,7 +1163,7 @@ int wc_AddErrorNode(int error, int line, char* buf, char* file) sz = WOLFSSL_MAX_ERROR_SZ - 1; } if (sz > 0) { - XMEMCPY(err->error, buf, sz); + XMEMCPY(err->error, buf, (size_t)sz); } sz = (int)XSTRLEN(file); @@ -1179,7 +1171,7 @@ int wc_AddErrorNode(int error, int line, char* buf, char* file) sz = WOLFSSL_MAX_ERROR_SZ - 1; } if (sz > 0) { - XMEMCPY(err->file, file, sz); + XMEMCPY(err->file, file, (size_t)sz); } err->value = error; @@ -1420,7 +1412,7 @@ unsigned long wc_PeekErrorNodeLineData(const char **file, int *line, } } -unsigned long wc_GetErrorNodeErr(void) +int wc_GetErrorNodeErr(void) { int ret; @@ -1428,7 +1420,7 @@ unsigned long wc_GetErrorNodeErr(void) if (ERRQ_LOCK() != 0) { WOLFSSL_MSG("Lock debug mutex failed"); - return (unsigned long)(0 - BAD_MUTEX_E); + return (0 - BAD_MUTEX_E); } ret = pullErrorNode(NULL, NULL, NULL); @@ -1595,10 +1587,10 @@ unsigned long wc_PeekErrorNodeLineData(const char **file, int *line, return (unsigned long)(0 - NOT_COMPILED_IN); } -unsigned long wc_GetErrorNodeErr(void) +int wc_GetErrorNodeErr(void) { WOLFSSL_ENTER("wc_GetErrorNodeErr"); - return (unsigned long)(0 - NOT_COMPILED_IN); + return (0 - NOT_COMPILED_IN); } #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) diff --git a/src/wolfcrypt/src/md2.c b/src/wolfcrypt/src/md2.c index 07ad963..89cec62 100644 --- a/src/wolfcrypt/src/md2.c +++ b/src/wolfcrypt/src/md2.c @@ -1,6 +1,6 @@ /* md2.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,18 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLFSSL_MD2 #include -#include #ifdef NO_INLINE #include @@ -42,6 +35,9 @@ void wc_InitMd2(wc_Md2* md2) { + if (md2 == NULL) + return; + XMEMSET(md2->X, 0, WC_MD2_X_SIZE); XMEMSET(md2->C, 0, WC_MD2_BLOCK_SIZE); XMEMSET(md2->buffer, 0, WC_MD2_BLOCK_SIZE); @@ -73,6 +69,9 @@ void wc_Md2Update(wc_Md2* md2, const byte* data, word32 len) 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 }; + if (md2 == NULL || (data == NULL && len != 0)) + return; + while (len) { word32 L = (WC_MD2_PAD_SIZE - md2->count) < len ? (WC_MD2_PAD_SIZE - md2->count) : len; @@ -117,9 +116,13 @@ void wc_Md2Update(wc_Md2* md2, const byte* data, word32 len) void wc_Md2Final(wc_Md2* md2, byte* hash) { byte padding[WC_MD2_BLOCK_SIZE]; - word32 padLen = WC_MD2_PAD_SIZE - md2->count; + word32 padLen; word32 i; + if (md2 == NULL || hash == NULL) + return; + + padLen = WC_MD2_PAD_SIZE - md2->count; for (i = 0; i < padLen; i++) padding[i] = (byte)padLen; diff --git a/src/wolfcrypt/src/md4.c b/src/wolfcrypt/src/md4.c index 592a0a3..53d206e 100644 --- a/src/wolfcrypt/src/md4.c +++ b/src/wolfcrypt/src/md4.c @@ -1,6 +1,6 @@ /* md4.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifndef NO_MD4 @@ -39,6 +34,9 @@ void wc_InitMd4(wc_Md4* md4) { + if (md4 == NULL) + return; + md4->digest[0] = 0x67452301L; md4->digest[1] = 0xefcdab89L; md4->digest[2] = 0x98badcfeL; @@ -141,8 +139,12 @@ static WC_INLINE void AddLength(wc_Md4* md4, word32 len) void wc_Md4Update(wc_Md4* md4, const byte* data, word32 len) { /* do block size increments */ - byte* local = (byte*)md4->buffer; + byte* local; + + if (md4 == NULL || (data == NULL && len != 0)) + return; + local = (byte*)md4->buffer; while (len) { word32 add = min(len, WC_MD4_BLOCK_SIZE - md4->buffLen); XMEMCPY(&local[md4->buffLen], data, add); @@ -165,8 +167,12 @@ void wc_Md4Update(wc_Md4* md4, const byte* data, word32 len) void wc_Md4Final(wc_Md4* md4, byte* hash) { - byte* local = (byte*)md4->buffer; + byte* local; + + if (md4 == NULL || hash == NULL) + return; + local = (byte*)md4->buffer; AddLength(md4, md4->buffLen); /* before adding pads */ local[md4->buffLen++] = 0x80; /* add 1 */ diff --git a/src/wolfcrypt/src/md5.c b/src/wolfcrypt/src/md5.c index 557de7c..84f1117 100644 --- a/src/wolfcrypt/src/md5.c +++ b/src/wolfcrypt/src/md5.c @@ -1,6 +1,6 @@ /* md5.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,13 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include +#include #if !defined(NO_MD5) @@ -35,8 +29,6 @@ #else #include -#include -#include #include #ifdef NO_INLINE diff --git a/src/wolfcrypt/src/memory.c b/src/wolfcrypt/src/memory.c index 4fd648a..928dd7b 100644 --- a/src/wolfcrypt/src/memory.c +++ b/src/wolfcrypt/src/memory.c @@ -1,6 +1,6 @@ /* memory.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,20 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +/* inhibit "#undef current" in linuxkm_wc_port.h, included from wc_port.h, + * because needed in linuxkm_memory.c, included below. + */ +#define WOLFSSL_LINUXKM_NEED_LINUX_CURRENT -#ifdef HAVE_CONFIG_H - #include -#endif - -#ifdef WOLFSSL_LINUXKM - /* inhibit "#undef current" in linuxkm_wc_port.h, included from wc_port.h, - * because needed in linuxkm_memory.c, included below. - */ - #define WOLFSSL_NEED_LINUX_CURRENT -#endif - -#include -#include +#include /* Possible memory options: @@ -81,8 +73,6 @@ void *z_realloc(void *ptr, size_t size) #ifdef USE_WOLFSSL_MEMORY #include -#include -#include #if defined(WOLFSSL_DEBUG_MEMORY) && defined(WOLFSSL_DEBUG_MEMORY_PRINT) #include @@ -1764,7 +1754,7 @@ WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void) { } (void)lrand48_r(&wc_svr_fuzzing_state, &result); if (result & 1) - return IO_FAILED_E; + return WC_NO_ERR_TRACE(IO_FAILED_E); else return 0; } @@ -1804,7 +1794,7 @@ WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void) { balance_bit = !balance_bit; - return ((prn & 1) ^ balance_bit) ? IO_FAILED_E : 0; + return ((prn & 1) ^ balance_bit) ? WC_NO_ERR_TRACE(IO_FAILED_E) : 0; } #endif /* !HAVE_THREAD_LS */ diff --git a/src/wolfcrypt/src/misc.c b/src/wolfcrypt/src/misc.c index c37e2dc..98b83c7 100644 --- a/src/wolfcrypt/src/misc.c +++ b/src/wolfcrypt/src/misc.c @@ -1,6 +1,6 @@ /* misc.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -25,11 +25,15 @@ This module implements the arithmetic-shift right, left, byte swapping, XOR, masking and clearing memory logic. */ -#ifdef HAVE_CONFIG_H - #include -#endif -#include +#ifdef WOLFSSL_VIS_FOR_TESTS + #ifdef HAVE_CONFIG_H + #include + #endif + #include +#else + #include +#endif #ifndef WOLF_CRYPT_MISC_C #define WOLF_CRYPT_MISC_C @@ -189,6 +193,28 @@ WC_MISC_STATIC WC_INLINE void ByteReverseWords(word32* out, const word32* in, out[i] = ByteReverseWord32(in[i]); } #ifdef WOLFSSL_USE_ALIGN + else if (((size_t)in & 0x3) == 0) { + byte *out_bytes = (byte *)out; + word32 scratch; + + byteCount &= ~0x3U; + + for (i = 0; i < byteCount; i += (word32)sizeof(word32)) { + scratch = ByteReverseWord32(*in++); + XMEMCPY(out_bytes + i, &scratch, sizeof(scratch)); + } + } + else if (((size_t)out & 0x3) == 0) { + byte *in_bytes = (byte *)in; + word32 scratch; + + byteCount &= ~0x3U; + + for (i = 0; i < byteCount; i += (word32)sizeof(word32)) { + XMEMCPY(&scratch, in_bytes + i, sizeof(scratch)); + *out++ = ByteReverseWord32(scratch); + } + } else { byte *in_bytes = (byte *)in; byte *out_bytes = (byte *)out; @@ -335,22 +361,68 @@ WC_MISC_STATIC WC_INLINE void ByteReverseWords64(word64* out, const word64* in, { word32 count = byteCount/(word32)sizeof(word64), i; - for (i = 0; i < count; i++) - out[i] = ByteReverseWord64(in[i]); +#ifdef WOLFSSL_USE_ALIGN + if ((((size_t)in & 0x7) == 0) && + (((size_t)out & 0x7) == 0)) +#endif + { + for (i = 0; i < count; i++) + out[i] = ByteReverseWord64(in[i]); + } +#ifdef WOLFSSL_USE_ALIGN + else if (((size_t)in & 0x7) == 0) { + byte *out_bytes = (byte *)out; + word64 scratch; + + byteCount &= ~0x7U; + + for (i = 0; i < byteCount; i += (word32)sizeof(word64)) { + scratch = ByteReverseWord64(*in++); + XMEMCPY(out_bytes + i, &scratch, sizeof(scratch)); + } + } + else if (((size_t)out & 0x7) == 0) { + byte *in_bytes = (byte *)in; + word64 scratch; + + byteCount &= ~0x7U; + + for (i = 0; i < byteCount; i += (word32)sizeof(word64)) { + XMEMCPY(&scratch, in_bytes + i, sizeof(scratch)); + *out++ = ByteReverseWord64(scratch); + } + } + else { + byte *in_bytes = (byte *)in; + byte *out_bytes = (byte *)out; + word64 scratch; + + byteCount &= ~0x7U; + for (i = 0; i < byteCount; i += (word32)sizeof(word64)) { + XMEMCPY(&scratch, in_bytes + i, sizeof(scratch)); + scratch = ByteReverseWord64(scratch); + XMEMCPY(out_bytes + i, &scratch, sizeof(scratch)); + } + } +#endif } #endif /* WORD64_AVAILABLE && !WOLFSSL_NO_WORD64_OPS */ #ifndef WOLFSSL_NO_XOR_OPS + +/* Leave no doubt that WOLFSSL_WORD_SIZE is a power of 2. */ +wc_static_assert((WOLFSSL_WORD_SIZE & (WOLFSSL_WORD_SIZE - 1)) == 0); + /* This routine performs a bitwise XOR operation of <*r> and <*a> for number of wolfssl_words, placing the result in <*r>. */ WC_MISC_STATIC WC_INLINE void XorWordsOut(wolfssl_word** r, const wolfssl_word** a, const wolfssl_word** b, word32 n) { - word32 i; + const wolfssl_word *e = *a + n; - for (i = 0; i < n; i++) + while (*a < e) *((*r)++) = *((*a)++) ^ *((*b)++); } @@ -360,48 +432,68 @@ counts, placing the result in <*buf>. */ WC_MISC_STATIC WC_INLINE void xorbufout(void* out, const void* buf, const void* mask, word32 count) { - word32 i; - byte* o; - const byte* b; - const byte* m; - - o = (byte*)out; - b = (const byte*)buf; - m = (const byte*)mask; - - - if (((wc_ptr_t)o) % WOLFSSL_WORD_SIZE == - ((wc_ptr_t)b) % WOLFSSL_WORD_SIZE && - ((wc_ptr_t)b) % WOLFSSL_WORD_SIZE == - ((wc_ptr_t)m) % WOLFSSL_WORD_SIZE) { - /* type-punning helpers */ - union { - byte* bp; - wolfssl_word* wp; - } tpo; - union { - const byte* bp; - const wolfssl_word* wp; - } tpb, tpm; - /* Alignment checks out. Possible to XOR words. */ - /* Move alignment so that it lines up with a - * WOLFSSL_WORD_SIZE boundary */ - while (((wc_ptr_t)b) % WOLFSSL_WORD_SIZE != 0 && count > 0) { - *(o++) = (byte)(*(b++) ^ *(m++)); + byte* o = (byte*)out; + const byte* b = (const byte*)buf; + const byte* m = (const byte*)mask; + + /* type-punning helpers */ + union { + byte* bp; + wolfssl_word* wp; + } tpo; + union { + const byte* bp; + const wolfssl_word* wp; + } tpb, tpm; + + if (((((wc_ptr_t)o) & (WOLFSSL_WORD_SIZE - 1)) == 0) && + ((((wc_ptr_t)b) & (WOLFSSL_WORD_SIZE - 1)) == 0) && + ((((wc_ptr_t)m) & (WOLFSSL_WORD_SIZE - 1)) == 0)) + { + /* All buffers are already aligned. Possible to XOR by words without + * fixup. + */ + + tpo.bp = o; + tpb.bp = b; + tpm.bp = m; + XorWordsOut(&tpo.wp, &tpb.wp, &tpm.wp, count >> WOLFSSL_WORD_SIZE_LOG2); + o = tpo.bp; + b = tpb.bp; + m = tpm.bp; + count &= (WOLFSSL_WORD_SIZE - 1); + } + else if ((((wc_ptr_t)o) & (WOLFSSL_WORD_SIZE - 1)) == + (((wc_ptr_t)b) & (WOLFSSL_WORD_SIZE - 1)) && + (((wc_ptr_t)b) & (WOLFSSL_WORD_SIZE - 1)) == + (((wc_ptr_t)m) & (WOLFSSL_WORD_SIZE - 1))) + { + /* Alignment can be fixed up to allow XOR by words. */ + + /* Perform bytewise xor until pointers are aligned to + * WOLFSSL_WORD_SIZE. + */ + while ((((wc_ptr_t)b & (WOLFSSL_WORD_SIZE - 1)) != 0) && (count > 0)) + { + *o++ = (byte)(*b++ ^ *m++); count--; } + tpo.bp = o; tpb.bp = b; tpm.bp = m; - XorWordsOut( &tpo.wp, &tpb.wp, &tpm.wp, count / WOLFSSL_WORD_SIZE); + XorWordsOut(&tpo.wp, &tpb.wp, &tpm.wp, count >> WOLFSSL_WORD_SIZE_LOG2); o = tpo.bp; b = tpb.bp; m = tpm.bp; - count %= WOLFSSL_WORD_SIZE; + count &= (WOLFSSL_WORD_SIZE - 1); + } + + while (count > 0) { + *o++ = (byte)(*b++ ^ *m++); + count--; } - for (i = 0; i < count; i++) - o[i] = (byte)(b[i] ^ m[i]); } /* This routine performs a bitwise XOR operation of <*r> and <*a> for number @@ -409,9 +501,9 @@ of wolfssl_words, placing the result in <*r>. */ WC_MISC_STATIC WC_INLINE void XorWords(wolfssl_word** r, const wolfssl_word** a, word32 n) { - word32 i; + const wolfssl_word *e = *a + n; - for (i = 0; i < n; i++) + while (*a < e) *((*r)++) ^= *((*a)++); } @@ -420,47 +512,82 @@ counts, placing the result in <*buf>. */ WC_MISC_STATIC WC_INLINE void xorbuf(void* buf, const void* mask, word32 count) { - word32 i; - byte* b; - const byte* m; - - b = (byte*)buf; - m = (const byte*)mask; - - if (((wc_ptr_t)b) % WOLFSSL_WORD_SIZE == - ((wc_ptr_t)m) % WOLFSSL_WORD_SIZE) { - /* type-punning helpers */ - union { - byte* bp; - wolfssl_word* wp; - } tpb; - union { - const byte* bp; - const wolfssl_word* wp; - } tpm; - /* Alignment checks out. Possible to XOR words. */ - /* Move alignment so that it lines up with a - * WOLFSSL_WORD_SIZE boundary */ - while (((wc_ptr_t)buf) % WOLFSSL_WORD_SIZE != 0 && count > 0) { + byte* b = (byte*)buf; + const byte* m = (const byte*)mask; + + /* type-punning helpers */ + union { + byte* bp; + wolfssl_word* wp; + } tpb; + union { + const byte* bp; + const wolfssl_word* wp; + } tpm; + + if ((((wc_ptr_t)buf & (WOLFSSL_WORD_SIZE - 1)) == 0) && + (((wc_ptr_t)mask & (WOLFSSL_WORD_SIZE - 1)) == 0)) + { + /* Both buffers are already aligned. Possible to XOR by words without + * fixup. + */ + + tpb.bp = b; + tpm.bp = m; + /* Work around false positives from linuxkm CONFIG_FORTIFY_SOURCE. */ + #if defined(WOLFSSL_LINUXKM) && defined(CONFIG_FORTIFY_SOURCE) + PRAGMA_GCC_DIAG_PUSH; + PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") + #endif + XorWords(&tpb.wp, &tpm.wp, count >> WOLFSSL_WORD_SIZE_LOG2); + #if defined(WOLFSSL_LINUXKM) && defined(CONFIG_FORTIFY_SOURCE) + PRAGMA_GCC_DIAG_POP; + #endif + b = tpb.bp; + m = tpm.bp; + count &= (WOLFSSL_WORD_SIZE - 1); + } + else if (((wc_ptr_t)buf & (WOLFSSL_WORD_SIZE - 1)) == + ((wc_ptr_t)mask & (WOLFSSL_WORD_SIZE - 1))) + { + /* Alignment can be fixed up to allow XOR by words. */ + + /* Perform bytewise xor until pointers are aligned to + * WOLFSSL_WORD_SIZE. + */ + while ((((wc_ptr_t)b & (WOLFSSL_WORD_SIZE - 1)) != 0) && (count > 0)) + { *(b++) ^= *(m++); count--; } + tpb.bp = b; tpm.bp = m; - XorWords( &tpb.wp, &tpm.wp, count / WOLFSSL_WORD_SIZE); + /* Work around false positives from linuxkm CONFIG_FORTIFY_SOURCE. */ + #if defined(WOLFSSL_LINUXKM) && defined(CONFIG_FORTIFY_SOURCE) + PRAGMA_GCC_DIAG_PUSH; + PRAGMA_GCC("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") + #endif + XorWords(&tpb.wp, &tpm.wp, count >> WOLFSSL_WORD_SIZE_LOG2); + #if defined(WOLFSSL_LINUXKM) && defined(CONFIG_FORTIFY_SOURCE) + PRAGMA_GCC_DIAG_POP; + #endif b = tpb.bp; m = tpm.bp; - count %= WOLFSSL_WORD_SIZE; + count &= (WOLFSSL_WORD_SIZE - 1); } - for (i = 0; i < count; i++) - b[i] ^= m[i]; + while (count > 0) { + *b++ ^= *m++; + count--; + } } -#endif + +#endif /* !WOLFSSL_NO_XOR_OPS */ #ifndef WOLFSSL_NO_FORCE_ZERO /* This routine fills the first len bytes of the memory area pointed by mem - with zeros. It ensures compiler optimizations doesn't skip it */ + with zeros. It ensures compiler optimization doesn't skip it */ WC_MISC_STATIC WC_INLINE void ForceZero(void* mem, word32 len) { volatile byte* z = (volatile byte*)mem; @@ -506,6 +633,125 @@ WC_MISC_STATIC WC_INLINE int ConstantCompare(const byte* a, const byte* b, } #endif +#ifndef WOLFSSL_NO_CT_OPS +/* Constant time - mask set when a > b. */ +WC_MISC_STATIC WC_INLINE byte ctMaskGT(int a, int b) +{ + return (byte)((((word32)a - (word32)b - 1) >> 31) - 1); +} + +/* Constant time - mask set when a >= b. */ +WC_MISC_STATIC WC_INLINE byte ctMaskGTE(int a, int b) +{ + return (byte)((((word32)a - (word32)b) >> 31) - 1); +} + +/* Constant time - mask set when a >= b. */ +WC_MISC_STATIC WC_INLINE int ctMaskIntGTE(int a, int b) +{ + return (int)((((word32)a - (word32)b) >> 31) - 1); +} + +#ifdef WORD64_AVAILABLE +/* Constant time - mask set when a >= b. */ +WC_MISC_STATIC WC_INLINE word32 ctMaskWord32GTE(word32 a, word32 b) +{ + return (word32)((((word64)a - (word64)b) >> 63) - 1); +} +#endif + +/* Constant time - mask set when a < b. */ +WC_MISC_STATIC WC_INLINE byte ctMaskLT(int a, int b) +{ + return (byte)((((word32)b - (word32)a - 1) >> 31) - 1); +} + +/* Constant time - mask set when a <= b. */ +WC_MISC_STATIC WC_INLINE byte ctMaskLTE(int a, int b) +{ + return (byte)((((word32)b - (word32)a) >> 31) - 1); +} + +/* Constant time - mask set when a == b. */ +WC_MISC_STATIC WC_INLINE byte ctMaskEq(int a, int b) +{ + return (byte)((byte)(~ctMaskGT(a, b)) & (byte)(~ctMaskLT(a, b))); +} + +/* Constant time - sets 16 bit integer mask when a > b */ +WC_MISC_STATIC WC_INLINE word16 ctMask16GT(int a, int b) +{ + return (word16)((((word32)a - (word32)b - 1) >> 31) - 1); +} + +/* Constant time - sets 16 bit integer mask when a >= b */ +WC_MISC_STATIC WC_INLINE word16 ctMask16GTE(int a, int b) +{ + return (word16)((((word32)a - (word32)b) >> 31) - 1); +} + +/* Constant time - sets 16 bit integer mask when a < b. */ +WC_MISC_STATIC WC_INLINE word16 ctMask16LT(int a, int b) +{ + return (word16)((((word32)b - (word32)a - 1) >> 31) - 1); +} + +/* Constant time - sets 16 bit integer mask when a <= b. */ +WC_MISC_STATIC WC_INLINE word16 ctMask16LTE(int a, int b) +{ + return (word16)((((word32)b - (word32)a) >> 31) - 1); +} + +/* Constant time - sets 16 bit integer mask when a == b. */ +WC_MISC_STATIC WC_INLINE word16 ctMask16Eq(int a, int b) +{ + return (word16)((word16)(~ctMask16GT(a, b)) & (word16)(~ctMask16LT(a, b))); +} + +/* Constant time - mask set when a != b. */ +WC_MISC_STATIC WC_INLINE byte ctMaskNotEq(int a, int b) +{ + return (byte)((byte)ctMaskGT(a, b) | (byte)ctMaskLT(a, b)); +} + +/* Constant time - select a when mask is set and b otherwise. */ +WC_MISC_STATIC WC_INLINE byte ctMaskSel(byte m, byte a, byte b) +{ + return (byte)((b & ((byte)~(word32)m)) | (a & m)); +} + +/* Constant time - select integer a when mask is set and integer b otherwise. */ +WC_MISC_STATIC WC_INLINE int ctMaskSelInt(byte m, int a, int b) +{ + return (b & (~(signed int)(signed char)m)) | + (a & ( (signed int)(signed char)m)); +} + +/* Constant time - select word32 a when mask is set and word32 b otherwise. */ +WC_MISC_STATIC WC_INLINE word32 ctMaskSelWord32(byte m, word32 a, word32 b) +{ + return (((word32)b & (word32)(~(signed int)(signed char)m)) | + ((word32)a & (word32)( (signed int)(signed char)m))); +} + +/* Constant time - bit set when a <= b. */ +WC_MISC_STATIC WC_INLINE byte ctSetLTE(int a, int b) +{ + return (byte)(((word32)a - (word32)b - 1) >> 31); +} + +/* Constant time - conditionally copy size bytes from src to dst if mask is set + */ +WC_MISC_STATIC WC_INLINE void ctMaskCopy(byte mask, byte* dst, byte* src, + word16 size) +{ + int i; + for (i = 0; i < size; ++i) { + dst[i] ^= (dst[i] ^ src[i]) & mask; + } +} + +#endif /* !WOLFSSL_NO_CT_OPS */ #ifndef WOLFSSL_HAVE_MIN #define WOLFSSL_HAVE_MIN @@ -515,7 +761,12 @@ WC_MISC_STATIC WC_INLINE int ConstantCompare(const byte* a, const byte* b, /* returns the smaller of a and b */ WC_MISC_STATIC WC_INLINE word32 min(word32 a, word32 b) { +#if !defined(WOLFSSL_NO_CT_OPS) && defined(WORD64_AVAILABLE) + word32 gte_mask = (word32)ctMaskWord32GTE(a, b); + return (a & ~gte_mask) | (b & gte_mask); +#else /* WOLFSSL_NO_CT_OPS */ return a > b ? b : a; +#endif /* WOLFSSL_NO_CT_OPS */ } #endif /* !WOLFSSL_HAVE_MIN */ @@ -526,7 +777,12 @@ WC_MISC_STATIC WC_INLINE int ConstantCompare(const byte* a, const byte* b, #endif WC_MISC_STATIC WC_INLINE word32 max(word32 a, word32 b) { +#if !defined(WOLFSSL_NO_CT_OPS) && defined(WORD64_AVAILABLE) + word32 gte_mask = (word32)ctMaskWord32GTE(a, b); + return (a & gte_mask) | (b & ~gte_mask); +#else /* WOLFSSL_NO_CT_OPS */ return a > b ? a : b; +#endif /* WOLFSSL_NO_CT_OPS */ } #endif /* !WOLFSSL_HAVE_MAX */ @@ -631,8 +887,10 @@ WC_MISC_STATIC WC_INLINE signed char HexCharToByte(char ch) WC_MISC_STATIC WC_INLINE char ByteToHex(byte in) { - static const char kHexChar[] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + static ALIGN64 const char kHexChar[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; return (char)(kHexChar[in & 0xF]); } @@ -648,6 +906,11 @@ WC_MISC_STATIC WC_INLINE int ByteToHexStr(byte in, char* out) WC_MISC_STATIC WC_INLINE int CharIsWhiteSpace(char ch) { +#ifndef WOLFSSL_NO_CT_OPS + return (ctMaskEq(ch, ' ') | + ctMaskEq(ch, '\t') | + ctMaskEq(ch, '\n')) & 1; +#else /* WOLFSSL_NO_CT_OPS */ switch (ch) { case ' ': case '\t': @@ -656,120 +919,9 @@ WC_MISC_STATIC WC_INLINE int CharIsWhiteSpace(char ch) default: return 0; } +#endif /* WOLFSSL_NO_CT_OPS */ } -#ifndef WOLFSSL_NO_CT_OPS -/* Constant time - mask set when a > b. */ -WC_MISC_STATIC WC_INLINE byte ctMaskGT(int a, int b) -{ - return (byte)((((word32)a - (word32)b - 1) >> 31) - 1); -} - -/* Constant time - mask set when a >= b. */ -WC_MISC_STATIC WC_INLINE byte ctMaskGTE(int a, int b) -{ - return (byte)((((word32)a - (word32)b) >> 31) - 1); -} - -/* Constant time - mask set when a >= b. */ -WC_MISC_STATIC WC_INLINE int ctMaskIntGTE(int a, int b) -{ - return (int)((((word32)a - (word32)b) >> 31) - 1); -} - -/* Constant time - mask set when a < b. */ -WC_MISC_STATIC WC_INLINE byte ctMaskLT(int a, int b) -{ - return (byte)((((word32)b - (word32)a - 1) >> 31) - 1); -} - -/* Constant time - mask set when a <= b. */ -WC_MISC_STATIC WC_INLINE byte ctMaskLTE(int a, int b) -{ - return (byte)((((word32)b - (word32)a) >> 31) - 1); -} - -/* Constant time - mask set when a == b. */ -WC_MISC_STATIC WC_INLINE byte ctMaskEq(int a, int b) -{ - return (byte)((byte)(~ctMaskGT(a, b)) & (byte)(~ctMaskLT(a, b))); -} - -/* Constant time - sets 16 bit integer mask when a > b */ -WC_MISC_STATIC WC_INLINE word16 ctMask16GT(int a, int b) -{ - return (word16)((((word32)a - (word32)b - 1) >> 31) - 1); -} - -/* Constant time - sets 16 bit integer mask when a >= b */ -WC_MISC_STATIC WC_INLINE word16 ctMask16GTE(int a, int b) -{ - return (word16)((((word32)a - (word32)b) >> 31) - 1); -} - -/* Constant time - sets 16 bit integer mask when a < b. */ -WC_MISC_STATIC WC_INLINE word16 ctMask16LT(int a, int b) -{ - return (word16)((((word32)b - (word32)a - 1) >> 31) - 1); -} - -/* Constant time - sets 16 bit integer mask when a <= b. */ -WC_MISC_STATIC WC_INLINE word16 ctMask16LTE(int a, int b) -{ - return (word16)((((word32)b - (word32)a) >> 31) - 1); -} - -/* Constant time - sets 16 bit integer mask when a == b. */ -WC_MISC_STATIC WC_INLINE word16 ctMask16Eq(int a, int b) -{ - return (word16)((word16)(~ctMask16GT(a, b)) & (word16)(~ctMask16LT(a, b))); -} - -/* Constant time - mask set when a != b. */ -WC_MISC_STATIC WC_INLINE byte ctMaskNotEq(int a, int b) -{ - return (byte)((byte)ctMaskGT(a, b) | (byte)ctMaskLT(a, b)); -} - -/* Constant time - select a when mask is set and b otherwise. */ -WC_MISC_STATIC WC_INLINE byte ctMaskSel(byte m, byte a, byte b) -{ - return (byte)((b & ((byte)~(word32)m)) | (a & m)); -} - -/* Constant time - select integer a when mask is set and integer b otherwise. */ -WC_MISC_STATIC WC_INLINE int ctMaskSelInt(byte m, int a, int b) -{ - return (b & (~(signed int)(signed char)m)) | - (a & ( (signed int)(signed char)m)); -} - -/* Constant time - select word32 a when mask is set and word32 b otherwise. */ -WC_MISC_STATIC WC_INLINE word32 ctMaskSelWord32(byte m, word32 a, word32 b) -{ - return (((word32)b & (word32)(~(signed int)(signed char)m)) | - ((word32)a & (word32)( (signed int)(signed char)m))); -} - -/* Constant time - bit set when a <= b. */ -WC_MISC_STATIC WC_INLINE byte ctSetLTE(int a, int b) -{ - return (byte)(((word32)a - (word32)b - 1) >> 31); -} - -/* Constant time - conditionally copy size bytes from src to dst if mask is set - */ -WC_MISC_STATIC WC_INLINE void ctMaskCopy(byte mask, byte* dst, byte* src, - word16 size) -{ - int i; - for (i = 0; i < size; ++i) { - dst[i] ^= (dst[i] ^ src[i]) & mask; - } -} - -#endif - #if defined(WOLFSSL_W64_WRAPPER) #if defined(WORD64_AVAILABLE) && !defined(WOLFSSL_W64_WRAPPER_TEST) WC_MISC_STATIC WC_INLINE void w64Increment(w64wrapper *n) { diff --git a/src/wolfcrypt/src/pkcs12.c b/src/wolfcrypt/src/pkcs12.c index 07ff1ad..5f8b85a 100644 --- a/src/wolfcrypt/src/pkcs12.c +++ b/src/wolfcrypt/src/pkcs12.c @@ -1,6 +1,6 @@ /* pkcs12.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -21,11 +21,7 @@ /* PKCS#12 allows storage of key and certificates into containers */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if defined(HAVE_PKCS12) && \ !defined(NO_ASN) && !defined(NO_PWDBASED) && !defined(NO_HMAC) && \ @@ -33,9 +29,7 @@ #include #include -#include #include -#include #ifdef NO_INLINE #include #else @@ -289,6 +283,7 @@ static int GetSafeContent(WC_PKCS12* pkcs12, const byte* input, if (wc_BerToDer(input, safe->dataSz, NULL, &pkcs12->safeDersz) != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) { WOLFSSL_MSG("Not BER sequence"); + freeSafe(safe, pkcs12->heap); return ASN_PARSE_E; } @@ -1144,7 +1139,7 @@ static WARN_UNUSED_RESULT int freeDecCertList(WC_DerCertList** list, #ifdef ASN_BER_TO_DER /* append data to encrypted content cache in PKCS12 structure * return buffer on success, NULL on error */ -static byte* PKCS12_ConcatonateContent(WC_PKCS12* pkcs12,byte* mergedData, +static byte* PKCS12_ConcatenateContent(WC_PKCS12* pkcs12,byte* mergedData, word32* mergedSz, byte* in, word32 inSz) { byte* oldContent; @@ -1180,7 +1175,7 @@ static int PKCS12_CheckConstructedZero(byte* data, word32 dataSz, word32* idx) { word32 oid; int ret = 0; - int number, size; + int number, size = 0; byte tag = 0; if (GetSequence(data, idx, &size, dataSz) < 0) { @@ -1257,7 +1252,7 @@ static int PKCS12_CoalesceOctetStrings(WC_PKCS12* pkcs12, byte* data, ret = MEMORY_E; } } - mergedData = PKCS12_ConcatonateContent(pkcs12, mergedData, + mergedData = PKCS12_ConcatenateContent(pkcs12, mergedData, &mergedSz, &data[*idx], (word32)encryptedContentSz); if (mergedData == NULL) { ret = MEMORY_E; @@ -1269,17 +1264,19 @@ static int PKCS12_CoalesceOctetStrings(WC_PKCS12* pkcs12, byte* data, *idx += (word32)encryptedContentSz; } - *idx = saveIdx; - - *idx += SetLength(mergedSz, &data[*idx]); + if (ret == 0) { + *idx = saveIdx; - if (mergedSz > 0) { - /* Copy over concatenated octet strings into data buffer */ - XMEMCPY(&data[*idx], mergedData, mergedSz); + *idx += SetLength(mergedSz, &data[*idx]); - XFREE(mergedData, pkcs12->heap, DYNAMIC_TYPE_PKCS); + if (mergedSz > 0) { + /* Copy over concatenated octet strings into data buffer */ + XMEMCPY(&data[*idx], mergedData, mergedSz); + } } + XFREE(mergedData, pkcs12->heap, DYNAMIC_TYPE_PKCS); + return ret; } #endif @@ -1300,6 +1297,27 @@ static int PKCS12_CoalesceOctetStrings(WC_PKCS12* pkcs12, byte* data, int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, byte** pkey, word32* pkeySz, byte** cert, word32* certSz, WC_DerCertList** ca) +{ + return wc_PKCS12_parse_ex(pkcs12, psw, pkey, pkeySz, cert, certSz, ca, 0); +} + +/* return 0 on success and negative on failure. + * By side effect returns private key, cert, and optionally ca. + * Parses and decodes the parts of PKCS12 + * + * NOTE: can parse with USER RSA enabled but may return cert that is not the + * pair for the key when using RSA key pairs. + * + * pkcs12 : non-null WC_PKCS12 struct + * psw : password to use for PKCS12 decode + * pkey : Private key returned + * cert : x509 cert returned + * ca : optional ca returned + * keepKeyHeader : 0 removes PKCS8 header, other than 0 keeps PKCS8 header + */ +int wc_PKCS12_parse_ex(WC_PKCS12* pkcs12, const char* psw, + byte** pkey, word32* pkeySz, byte** cert, word32* certSz, + WC_DerCertList** ca, int keepKeyHeader) { ContentInfo* ci = NULL; WC_DerCertList* certList = NULL; @@ -1495,7 +1513,13 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, ERROR_OUT(MEMORY_E, exit_pk12par); } XMEMCPY(*pkey, data + idx, (size_t)size); - *pkeySz = (word32)ToTraditional_ex(*pkey, (word32)size, &algId); + if (keepKeyHeader) { + *pkeySz = (word32)size; + } + else { + *pkeySz = (word32)ToTraditional_ex(*pkey, + (word32)size, &algId); + } } #ifdef WOLFSSL_DEBUG_PKCS12 @@ -1534,10 +1558,19 @@ int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, XMEMCPY(k, data + idx, (size_t)size); /* overwrites input, be warned */ - if ((ret = ToTraditionalEnc(k, (word32)size, psw, pswSz, - &algId)) < 0) { - XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY); - goto exit_pk12par; + if (keepKeyHeader) { + if ((ret = wc_DecryptPKCS8Key(k, (word32)size, psw, + pswSz)) < 0) { + XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY); + goto exit_pk12par; + } + } + else { + if ((ret = ToTraditionalEnc(k, (word32)size, psw, + pswSz, &algId)) < 0) { + XFREE(k, pkcs12->heap, DYNAMIC_TYPE_PUBLIC_KEY); + goto exit_pk12par; + } } if (ret < size) { diff --git a/src/wolfcrypt/src/pkcs7.c b/src/wolfcrypt/src/pkcs7.c index a96f537..a8545ba 100644 --- a/src/wolfcrypt/src/pkcs7.c +++ b/src/wolfcrypt/src/pkcs7.c @@ -1,6 +1,6 @@ /* pkcs7.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,18 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef HAVE_PKCS7 #include -#include -#include #include #ifndef NO_RSA #include @@ -88,8 +81,8 @@ struct PKCS7State { byte* content; byte* buffer; /* main internal read buffer */ - wc_HashAlg hashAlg; - int hashType; + wc_HashAlg hashAlg; + enum wc_HashType hashType; int cntIdfCnt; /* count of in-definite length in content info */ /* stack variables to store for when returning */ @@ -297,7 +290,9 @@ static int wc_PKCS7_AddDataToStream(wc_PKCS7* pkcs7, byte* in, word32 inSz, } /* check if internal buffer size needs to be increased */ - if (len + pkcs7->stream->length > pkcs7->stream->bufferSz) { + if ((len + pkcs7->stream->length > pkcs7->stream->bufferSz) || + (pkcs7->stream->buffer == NULL)) + { int ret = wc_PKCS7_GrowStream(pkcs7, expected); if (ret < 0) { return ret; @@ -376,15 +371,11 @@ static int wc_PKCS7_SetMaxStream(wc_PKCS7* pkcs7, byte* in, word32 defSz) return ret; } - #ifdef ASN_BER_TO_DER if (length == 0 && ret == 0) { idx = 0; - if ((ret = wc_BerToDer(pt, maxIdx, NULL, (word32*)&length)) - != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) { - return ret; - } + WOLFSSL_MSG("PKCS7 found indef SEQ with peek"); } - #endif /* ASN_BER_TO_DER */ + pkcs7->stream->maxLen = (word32)length + idx; if (pkcs7->stream->maxLen == 0) { @@ -1733,8 +1724,8 @@ static int FlattenAttributes(wc_PKCS7* pkcs7, byte* output, EncodedAttrib* ea, } /* create array of FlatAttrib struct pointers to hold DER attribs */ - derArr = (FlatAttrib**) XMALLOC((unsigned long)eaSz * sizeof(FlatAttrib*), pkcs7->heap, - DYNAMIC_TYPE_TMP_BUFFER); + derArr = (FlatAttrib**) XMALLOC((unsigned long)eaSz * sizeof(FlatAttrib*), + pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); if (derArr == NULL) { return MEMORY_E; } @@ -2073,6 +2064,8 @@ static int wc_PKCS7_BuildSignedAttributes(wc_PKCS7* pkcs7, ESD* esd, cannedAttribsCount = sizeof(cannedAttribs)/sizeof(PKCS7Attrib); + XMEMSET(&cannedAttribs[idx], 0, sizeof(cannedAttribs[idx])); + if ((pkcs7->defaultSignedAttribs & WOLFSSL_CONTENT_TYPE_ATTRIBUTE) || pkcs7->defaultSignedAttribs == 0) { cannedAttribs[idx].oid = contentTypeOid; @@ -2642,21 +2635,32 @@ static int wc_PKCS7_EncodeContentStream(wc_PKCS7* pkcs7, ESD* esd, void* aes, /* check and handle octet boundary */ sz = contentDataRead; if ((int)idx + sz > BER_OCTET_LENGTH) { - sz = BER_OCTET_LENGTH - (int)idx; - contentDataRead -= sz; + int amtWritten = 0; - XMEMCPY(contentData + idx, buf, (word32)sz); - ret = wc_PKCS7_EncodeContentStreamHelper(pkcs7, cipherType, - aes, encContentOut, contentData, BER_OCTET_LENGTH, out, - &outIdx, esd); - if (ret != 0) { - XFREE(encContentOut, heap, DYNAMIC_TYPE_PKCS7); - XFREE(contentData, heap, DYNAMIC_TYPE_PKCS7); - return ret; + /* loop over current buffer until it is empty */ + while (idx + (word32)sz > BER_OCTET_LENGTH) { + sz = BER_OCTET_LENGTH; + if (idx > 0) { /* account for previously stored data */ + sz = BER_OCTET_LENGTH - (int)idx; + } + contentDataRead -= sz; + + XMEMCPY(contentData + idx, buf, (word32)sz); + ret = wc_PKCS7_EncodeContentStreamHelper(pkcs7, cipherType, + aes, encContentOut, contentData, BER_OCTET_LENGTH, out, + &outIdx, esd); + if (ret != 0) { + XFREE(encContentOut, heap, DYNAMIC_TYPE_PKCS7); + XFREE(contentData, heap, DYNAMIC_TYPE_PKCS7); + return ret; + } + idx = 0; /* cleared out previously stored data */ + amtWritten += sz; + sz = contentDataRead; } /* copy over any remaining data */ - XMEMCPY(contentData, buf + sz, (word32)contentDataRead); + XMEMCPY(contentData, buf + amtWritten, (word32)contentDataRead); idx = (word32)contentDataRead; } else { @@ -2917,8 +2921,13 @@ static int PKCS7_EncodeSigned(wc_PKCS7* pkcs7, /* SignerIdentifier */ if (pkcs7->sidType == CMS_ISSUER_AND_SERIAL_NUMBER) { /* IssuerAndSerialNumber */ - esd->issuerSnSz = (word32)SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz, + ret = SetSerialNumber(pkcs7->issuerSn, pkcs7->issuerSnSz, esd->issuerSn, MAX_SN_SZ, MAX_SN_SZ); + if (ret < 0) { + idx = ret; + goto out; + } + esd->issuerSnSz = (word32)ret; signerInfoSz += esd->issuerSnSz; esd->issuerNameSz = SetSequence(pkcs7->issuerSz, esd->issuerName); signerInfoSz += esd->issuerNameSz + pkcs7->issuerSz; @@ -5267,35 +5276,52 @@ static int wc_PKCS7_HandleOctetStrings(wc_PKCS7* pkcs7, byte* in, word32 inSz, /* got partial octet string data */ /* accumulate partial octet string to buffer */ if (keepContent) { + #ifdef ASN_BER_TO_DER + if (pkcs7->streamOutCb) { + ret = wc_HashUpdate(&pkcs7->stream->hashAlg, + pkcs7->stream->hashType, + msg + *idx, pkcs7->stream->expected); + if (ret != 0) + break; + pkcs7->streamOutCb(pkcs7, msg + *idx, + pkcs7->stream->expected, pkcs7->streamCtx); + } + else + #endif /* ASN_BER_TO_DER */ + { + /* store current content buffer temporarily */ + tempBuf = pkcs7->stream->content; + pkcs7->stream->content = NULL; - /* store current content buffer temporarily */ - tempBuf = pkcs7->stream->content; - pkcs7->stream->content = NULL; - - /* grow content buffer */ - contBufSz = pkcs7->stream->accumContSz; - pkcs7->stream->accumContSz += pkcs7->stream->expected; + /* grow content buffer */ + contBufSz = pkcs7->stream->accumContSz; + pkcs7->stream->accumContSz += pkcs7->stream->expected; - pkcs7->stream->content = - (byte*)XMALLOC(pkcs7->stream->accumContSz, - pkcs7->heap, DYNAMIC_TYPE_PKCS7); + pkcs7->stream->content = + (byte*)XMALLOC(pkcs7->stream->accumContSz, + pkcs7->heap, DYNAMIC_TYPE_PKCS7); - if (pkcs7->stream->content == NULL) { - WOLFSSL_MSG("failed to grow content buffer."); - XFREE(tempBuf, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - tempBuf = NULL; - ret = MEMORY_E; - break; - } - else { - /* accumulate content */ - if (tempBuf != NULL && contBufSz != 0) { - XMEMCPY(pkcs7->stream->content, tempBuf, contBufSz); + if (pkcs7->stream->content == NULL) { + WOLFSSL_MSG("failed to grow content buffer."); + if (tempBuf != NULL) { + XFREE(tempBuf, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + tempBuf = NULL; + } + ret = MEMORY_E; + break; + } + else { + /* accumulate content */ + if (tempBuf != NULL && contBufSz != 0) { + XMEMCPY(pkcs7->stream->content, tempBuf, contBufSz); + } + XMEMCPY(pkcs7->stream->content + contBufSz, msg + *idx, + pkcs7->stream->expected); + if (tempBuf != NULL) { + XFREE(tempBuf, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + tempBuf = NULL; + } } - XMEMCPY(pkcs7->stream->content + contBufSz, msg + *idx, - pkcs7->stream->expected); - XFREE(tempBuf, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - tempBuf = NULL; } } @@ -5574,7 +5600,7 @@ static int PKCS7_VerifySignedData(wc_PKCS7* pkcs7, const byte* hashBuf, ret = ASN_PARSE_E; } /* store hashType for later hashing */ - pkcs7->stream->hashType = (int)hashType; + pkcs7->stream->hashType = hashType; /* restore idx */ idx = localIdx; @@ -5915,6 +5941,16 @@ static int PKCS7_VerifySignedData(wc_PKCS7* pkcs7, const byte* hashBuf, wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE3); #ifndef NO_PKCS7_STREAM + #ifdef ASN_BER_TO_DER + /* setup hash struct for creating hash of content if needed */ + if (pkcs7->streamOutCb) { + ret = wc_HashInit_ex(&pkcs7->stream->hashAlg, + pkcs7->stream->hashType, pkcs7->heap, pkcs7->devId); + if (ret != 0) + break; + } + #endif /* ASN_BER_TO_DER */ + /* free pkcs7->stream->content buffer */ XFREE(pkcs7->stream->content, pkcs7->heap, DYNAMIC_TYPE_PKCS7); pkcs7->stream->content = NULL; @@ -6210,7 +6246,6 @@ static int PKCS7_VerifySignedData(wc_PKCS7* pkcs7, const byte* hashBuf, /* store current index to get the signerInfo index later */ certIdx2 = idx; - /* store certificate if needed */ if (length > 0 && in2Sz == 0) { /* free tmpCert if not NULL */ @@ -6577,8 +6612,31 @@ static int PKCS7_VerifySignedData(wc_PKCS7* pkcs7, const byte* hashBuf, pkcs7->contentSz = (word32)contentSz; if (ret == 0) { - ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, (word32)sigSz, - signedAttrib, (word32)signedAttribSz, + #if !defined(NO_PKCS7_STREAM) && defined(ASN_BER_TO_DER) + byte streamHash[WC_MAX_DIGEST_SIZE]; + + /* get final hash if having done hash updates while + * streaming out the content */ + if (pkcs7->streamOutCb) { + ret = wc_HashFinal(&pkcs7->stream->hashAlg, + pkcs7->stream->hashType, streamHash); + hashBuf = streamHash; + length = wc_HashGetDigestSize(pkcs7->stream->hashType); + if (length < 0) { + WOLFSSL_MSG("Error getting digest size"); + ret = ASN_PARSE_E; + } + else { + hashSz = (word32)length; + } + wc_HashFree(&pkcs7->stream->hashAlg, + pkcs7->stream->hashType); + if (ret != 0) + break; + } + #endif /* !NO_PKCS7_STREAM && ASN_BER_TO_DER */ + ret = wc_PKCS7_SignedDataVerifySignature(pkcs7, sig, + (word32)sigSz, signedAttrib, (word32)signedAttribSz, hashBuf, hashSz); } } @@ -8400,34 +8458,21 @@ static int wc_PKCS7_EncryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, } -/* decrypt content using encryptOID algo - * returns 0 on success */ -static int wc_PKCS7_DecryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, - int keySz, byte* iv, int ivSz, byte* aad, word32 aadSz, byte* authTag, - word32 authTagSz, byte* in, int inSz, byte* out, int devId, void* heap) +static int wc_PKCS7_DecryptContentInit(wc_PKCS7* pkcs7, word32 encryptOID, + byte* key, word32 keySz, byte* iv, int ivSz, int devId, void* heap) { int ret; #ifndef NO_AES -#ifdef WOLFSSL_SMALL_STACK Aes *aes; -#else - Aes aes[1]; -#endif #endif #ifndef NO_DES3 - Des des; - Des3 des3; + Des *des; + Des3 *des3; #endif - if (iv == NULL || in == NULL || out == NULL) + if (iv == NULL) return BAD_FUNC_ARG; - if (pkcs7->decryptionCb != NULL) { - return pkcs7->decryptionCb(pkcs7, encryptOID, iv, ivSz, - aad, aadSz, authTag, authTagSz, in, - inSz, out, pkcs7->decryptionCtx); - } - if (key == NULL) return BAD_FUNC_ARG; @@ -8455,27 +8500,18 @@ static int wc_PKCS7_DecryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, #endif (ivSz != WC_AES_BLOCK_SIZE) ) return BAD_FUNC_ARG; -#ifdef WOLFSSL_SMALL_STACK - if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL, - DYNAMIC_TYPE_AES)) == NULL) + + pkcs7->decryptKey.aes = (Aes *)XMALLOC(sizeof *aes, NULL, + DYNAMIC_TYPE_AES); + aes = pkcs7->decryptKey.aes; + if (aes == NULL) return MEMORY_E; -#endif ret = wc_AesInit(aes, heap, devId); if (ret == 0) { ret = wc_AesSetKey(aes, key, (word32)keySz, iv, AES_DECRYPTION); - if (ret == 0) { - ret = wc_AesCbcDecrypt(aes, out, in, (word32)inSz); - #ifdef WOLFSSL_ASYNC_CRYPT - /* async decrypt not available here, so block till done */ - ret = wc_AsyncWait(ret, &aes->asyncDev, WC_ASYNC_FLAG_NONE); - #endif - } - wc_AesFree(aes); } -#ifdef WOLFSSL_SMALL_STACK - XFREE(aes, NULL, DYNAMIC_TYPE_AES); -#endif break; + #endif /* HAVE_AES_CBC */ #ifdef HAVE_AESGCM #ifdef WOLFSSL_AES_128 @@ -8489,31 +8525,15 @@ static int wc_PKCS7_DecryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, #endif #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \ defined(WOLFSSL_AES_256) - if (authTag == NULL) - return BAD_FUNC_ARG; - -#ifdef WOLFSSL_SMALL_STACK - if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL, - DYNAMIC_TYPE_AES)) == NULL) + pkcs7->decryptKey.aes = (Aes *)XMALLOC(sizeof *aes, NULL, + DYNAMIC_TYPE_AES); + aes = pkcs7->decryptKey.aes; + if (aes == NULL) return MEMORY_E; -#endif ret = wc_AesInit(aes, heap, devId); if (ret == 0) { ret = wc_AesGcmSetKey(aes, key, (word32)keySz); - if (ret == 0) { - ret = wc_AesGcmDecrypt(aes, out, in, (word32)inSz, iv, - (word32)ivSz, authTag, authTagSz, - aad, aadSz); - #ifdef WOLFSSL_ASYNC_CRYPT - /* async decrypt not available here, so block till done */ - ret = wc_AsyncWait(ret, &aes->asyncDev, WC_ASYNC_FLAG_NONE); - #endif - } - wc_AesFree(aes); } -#ifdef WOLFSSL_SMALL_STACK - XFREE(aes, NULL, DYNAMIC_TYPE_AES); -#endif break; #endif #endif /* HAVE_AESGCM */ @@ -8529,31 +8549,15 @@ static int wc_PKCS7_DecryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, #endif #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \ defined(WOLFSSL_AES_256) - if (authTag == NULL) - return BAD_FUNC_ARG; - -#ifdef WOLFSSL_SMALL_STACK - if ((aes = (Aes *)XMALLOC(sizeof *aes, NULL, - DYNAMIC_TYPE_AES)) == NULL) + pkcs7->decryptKey.aes = (Aes *)XMALLOC(sizeof *aes, NULL, + DYNAMIC_TYPE_AES); + aes = pkcs7->decryptKey.aes; + if (aes == NULL) return MEMORY_E; -#endif ret = wc_AesInit(aes, heap, devId); if (ret == 0) { ret = wc_AesCcmSetKey(aes, key, (word32)keySz); - if (ret == 0) { - ret = wc_AesCcmDecrypt(aes, out, in, (word32)inSz, iv, - (word32)ivSz, authTag, authTagSz, - aad, aadSz); - #ifdef WOLFSSL_ASYNC_CRYPT - /* async decrypt not available here, so block till done */ - ret = wc_AsyncWait(ret, &aes->asyncDev, WC_ASYNC_FLAG_NONE); - #endif - } - wc_AesFree(aes); } -#ifdef WOLFSSL_SMALL_STACK - XFREE(aes, NULL, DYNAMIC_TYPE_AES); -#endif break; #endif #endif /* HAVE_AESCCM */ @@ -8563,26 +8567,27 @@ static int wc_PKCS7_DecryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, if (keySz != DES_KEYLEN || ivSz != DES_BLOCK_SIZE) return BAD_FUNC_ARG; - ret = wc_Des_SetKey(&des, key, iv, DES_DECRYPTION); - if (ret == 0) - ret = wc_Des_CbcDecrypt(&des, out, in, (word32)inSz); - + pkcs7->decryptKey.des = (Des *)XMALLOC(sizeof *des, NULL, + DYNAMIC_TYPE_PKCS7); + des = pkcs7->decryptKey.des; + if (des == NULL) { + return MEMORY_E; + } + ret = wc_Des_SetKey(des, key, iv, DES_DECRYPTION); break; case DES3b: if (keySz != DES3_KEYLEN || ivSz != DES_BLOCK_SIZE) return BAD_FUNC_ARG; - ret = wc_Des3Init(&des3, heap, devId); + pkcs7->decryptKey.des3 = (Des3 *)XMALLOC(sizeof *des3, NULL, + DYNAMIC_TYPE_PKCS7); + des3 = pkcs7->decryptKey.des3; + if (des3 == NULL) { + return MEMORY_E; + } + ret = wc_Des3Init(des3, heap, devId); if (ret == 0) { - ret = wc_Des3_SetKey(&des3, key, iv, DES_DECRYPTION); - if (ret == 0) { - ret = wc_Des3_CbcDecrypt(&des3, out, in, (word32)inSz); - #ifdef WOLFSSL_ASYNC_CRYPT - /* async decrypt not available here, so block till done */ - ret = wc_AsyncWait(ret, &des3.asyncDev, WC_ASYNC_FLAG_NONE); - #endif - } - wc_Des3Free(&des3); + ret = wc_Des3_SetKey(des3, key, iv, DES_DECRYPTION); } break; @@ -8592,77 +8597,283 @@ static int wc_PKCS7_DecryptContent(wc_PKCS7* pkcs7, int encryptOID, byte* key, return ALGO_ID_E; }; -#if defined(NO_AES) || (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM)) - (void)authTag; - (void)authTagSz; - (void)aad; - (void)aadSz; -#endif - return ret; } -/* Generate random block, place in out, return 0 on success negative on error. - * Used for generation of IV, nonce, etc */ -static int wc_PKCS7_GenerateBlock(wc_PKCS7* pkcs7, WC_RNG* rng, byte* out, - word32 outSz) +/* Only does decryption of content using encryptOID algo and already set keys + * returns 0 on success */ +static int wc_PKCS7_DecryptContentEx(wc_PKCS7* pkcs7, word32 encryptOID, + byte* iv, int ivSz, byte* aad, word32 aadSz, byte* authTag, + word32 authTagSz, byte* in, int inSz, byte* out) { int ret; - WC_RNG* rnd = NULL; - if (out == NULL || outSz == 0) + if (in == NULL + #ifdef ASN_BER_TO_DER + && pkcs7->getContentCb == NULL + #endif + ) { return BAD_FUNC_ARG; + } - /* input RNG is optional, init local one if input rng is NULL */ - if (rng == NULL) { - rnd = (WC_RNG*)XMALLOC(sizeof(WC_RNG), pkcs7->heap, DYNAMIC_TYPE_RNG); - if (rnd == NULL) - return MEMORY_E; - - ret = wc_InitRng_ex(rnd, pkcs7->heap, pkcs7->devId); - if (ret != 0) { - XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG); - return ret; - } + switch (encryptOID) { +#ifndef NO_AES + #ifdef HAVE_AES_CBC + #ifdef WOLFSSL_AES_128 + case AES128CBCb: + #endif + #ifdef WOLFSSL_AES_192 + case AES192CBCb: + #endif + #ifdef WOLFSSL_AES_256 + case AES256CBCb: + #endif + ret = wc_AesCbcDecrypt(pkcs7->decryptKey.aes, out, in, + (word32)inSz); + #ifdef WOLFSSL_ASYNC_CRYPT + /* async decrypt not available here, so block till done */ + ret = wc_AsyncWait(ret, &pkcs7->decryptKey.aes->asyncDev, + WC_ASYNC_FLAG_NONE); + #endif + break; + #endif /* HAVE_AES_CBC */ + #ifdef HAVE_AESGCM + #ifdef WOLFSSL_AES_128 + case AES128GCMb: + #endif + #ifdef WOLFSSL_AES_192 + case AES192GCMb: + #endif + #ifdef WOLFSSL_AES_256 + case AES256GCMb: + #endif + #if defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_192) || \ + defined(WOLFSSL_AES_256) + if (authTag == NULL) + return BAD_FUNC_ARG; - } else { - rnd = rng; - } + ret = wc_AesGcmDecrypt(pkcs7->decryptKey.aes, out, in, + (word32)inSz, iv, (word32)ivSz, authTag, authTagSz, + aad, aadSz); + #ifdef WOLFSSL_ASYNC_CRYPT + /* async decrypt not available here, so block till done */ + ret = wc_AsyncWait(ret, &pkcs7->decryptKey.aes->asyncDev, + WC_ASYNC_FLAG_NONE); + #endif + break; + #endif + #endif /* HAVE_AESGCM */ + #ifdef HAVE_AESCCM + #ifdef WOLFSSL_AES_128 + case AES128CCMb: + #endif + #ifdef WOLFSSL_AES_192 + case AES192CCMb: + #endif + #ifdef WOLFSSL_AES_256 + case AES256CCMb: + #endif + ret = wc_AesCcmDecrypt(pkcs7->decryptKey.aes, out, in, + (word32)inSz, iv, (word32)ivSz, authTag, authTagSz, + aad, aadSz); + #ifdef WOLFSSL_ASYNC_CRYPT + /* async decrypt not available here, so block till done */ + ret = wc_AsyncWait(ret, &pkcs7->decryptKey.aes->asyncDev, + WC_ASYNC_FLAG_NONE); + #endif + break; + #endif /* HAVE_AESCCM */ +#endif /* !NO_AES */ +#ifndef NO_DES3 + case DESb: + ret = wc_Des_CbcDecrypt(pkcs7->decryptKey.des, out, in, + (word32)inSz); + break; - ret = wc_RNG_GenerateBlock(rnd, out, outSz); + case DES3b: + ret = wc_Des3_CbcDecrypt(pkcs7->decryptKey.des3, out, in, + (word32)inSz); + #ifdef WOLFSSL_ASYNC_CRYPT + /* async decrypt not available here, so block till done */ + ret = wc_AsyncWait(ret, + &pkcs7->decryptKey.des3->asyncDev, WC_ASYNC_FLAG_NONE); + #endif + break; +#endif /* !NO_DES3 */ + default: + WOLFSSL_MSG("Unsupported content cipher type"); + return ALGO_ID_E; + }; - if (rng == NULL) { - wc_FreeRng(rnd); - XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG); - } +#if defined(NO_AES) || (!defined(HAVE_AESGCM) && !defined(HAVE_AESCCM)) + (void)authTag; + (void)authTagSz; + (void)aad; + (void)aadSz; +#endif return ret; } -/* Set default SignerIdentifier type to be used. Is either - * IssuerAndSerialNumber or SubjectKeyIdentifier. Encoding defaults to using - * IssuerAndSerialNumber unless set with this function or explicitly - * overridden via options when adding RecipientInfo type. - * - * Using the type DEGENERATE_SID skips over signer information. In degenerate - * cases there are no signers. - * - * pkcs7 - pointer to initialized PKCS7 structure - * type - either CMS_ISSUER_AND_SERIAL_NUMBER, CMS_SKID or DEGENERATE_SID - * - * return 0 on success, negative upon error */ -int wc_PKCS7_SetSignerIdentifierType(wc_PKCS7* pkcs7, int type) +/* clears up struct for algo used and free's memory */ +static void wc_PKCS7_DecryptContentFree(wc_PKCS7* pkcs7, word32 encryptOID, + void* heap) { - if (pkcs7 == NULL) - return BAD_FUNC_ARG; - - if (type != CMS_ISSUER_AND_SERIAL_NUMBER && - type != CMS_SKID && - type != DEGENERATE_SID) { - return BAD_FUNC_ARG; - } + switch (encryptOID) { +#ifndef NO_AES + #ifdef HAVE_AES_CBC + #ifdef WOLFSSL_AES_128 + case AES128CBCb: + #endif + #ifdef WOLFSSL_AES_192 + case AES192CBCb: + #endif + #ifdef WOLFSSL_AES_256 + case AES256CBCb: + #endif + #endif /* HAVE_AES_CBC */ + #ifdef HAVE_AESGCM + #ifdef WOLFSSL_AES_128 + case AES128GCMb: + #endif + #ifdef WOLFSSL_AES_192 + case AES192GCMb: + #endif + #ifdef WOLFSSL_AES_256 + case AES256GCMb: + #endif + #endif /* HAVE_AESGCM */ + #ifdef HAVE_AESCCM + #ifdef WOLFSSL_AES_128 + case AES128CCMb: + #endif + #ifdef WOLFSSL_AES_192 + case AES192CCMb: + #endif + #ifdef WOLFSSL_AES_256 + case AES256CCMb: + #endif + #endif /* HAVE_AESCCM */ + if (pkcs7->decryptKey.aes != NULL) { + wc_AesFree(pkcs7->decryptKey.aes); + XFREE(pkcs7->decryptKey.aes, heap, DYNAMIC_TYPE_AES); + pkcs7->decryptKey.aes = NULL; + } + break; +#endif /* !NO_AES */ +#ifndef NO_DES3 + case DESb: + if (pkcs7->decryptKey.des != NULL) { + XFREE(pkcs7->decryptKey.des, heap, DYNAMIC_TYPE_PKCS7); + pkcs7->decryptKey.des = NULL; + } + break; + case DES3b: + if (pkcs7->decryptKey.des3 != NULL) { + wc_Des3Free(pkcs7->decryptKey.des3); + XFREE(pkcs7->decryptKey.des3, heap, DYNAMIC_TYPE_PKCS7); + pkcs7->decryptKey.des3 = NULL; + } + break; +#endif /* !NO_DES3 */ + default: + WOLFSSL_MSG("Unsupported content cipher type"); + }; +} + + +/* decrypts the content in one shot, doing init / decrypt / free + * returns 0 on success + */ +static int wc_PKCS7_DecryptContent(wc_PKCS7* pkcs7, word32 encryptOID, + byte* key, word32 keySz, byte* iv, int ivSz, byte* aad, word32 aadSz, + byte* authTag, word32 authTagSz, byte* in, int inSz, byte* out, + int devId, void* heap) +{ + int ret; + + if (pkcs7->decryptionCb != NULL) { + return pkcs7->decryptionCb(pkcs7, (int)encryptOID, iv, ivSz, + aad, aadSz, authTag, authTagSz, in, + inSz, out, pkcs7->decryptionCtx); + } + + ret = wc_PKCS7_DecryptContentInit(pkcs7, encryptOID, key, keySz, iv, ivSz, + devId, heap); + + if (ret == 0) { + ret = wc_PKCS7_DecryptContentEx(pkcs7, encryptOID, iv, ivSz, aad, + aadSz, authTag, authTagSz, in, inSz, out); + } + + wc_PKCS7_DecryptContentFree(pkcs7, encryptOID, heap); + + return ret; +} + + +/* Generate random block, place in out, return 0 on success negative on error. + * Used for generation of IV, nonce, etc */ +static int wc_PKCS7_GenerateBlock(wc_PKCS7* pkcs7, WC_RNG* rng, byte* out, + word32 outSz) +{ + int ret; + WC_RNG* rnd = NULL; + + if (out == NULL || outSz == 0) + return BAD_FUNC_ARG; + + /* input RNG is optional, init local one if input rng is NULL */ + if (rng == NULL) { + rnd = (WC_RNG*)XMALLOC(sizeof(WC_RNG), pkcs7->heap, DYNAMIC_TYPE_RNG); + if (rnd == NULL) + return MEMORY_E; + + ret = wc_InitRng_ex(rnd, pkcs7->heap, pkcs7->devId); + if (ret != 0) { + XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG); + return ret; + } + + } else { + rnd = rng; + } + + ret = wc_RNG_GenerateBlock(rnd, out, outSz); + + if (rng == NULL) { + wc_FreeRng(rnd); + XFREE(rnd, pkcs7->heap, DYNAMIC_TYPE_RNG); + } + + return ret; +} + + +/* Set default SignerIdentifier type to be used. Is either + * IssuerAndSerialNumber or SubjectKeyIdentifier. Encoding defaults to using + * IssuerAndSerialNumber unless set with this function or explicitly + * overridden via options when adding RecipientInfo type. + * + * Using the type DEGENERATE_SID skips over signer information. In degenerate + * cases there are no signers. + * + * pkcs7 - pointer to initialized PKCS7 structure + * type - either CMS_ISSUER_AND_SERIAL_NUMBER, CMS_SKID or DEGENERATE_SID + * + * return 0 on success, negative upon error */ +int wc_PKCS7_SetSignerIdentifierType(wc_PKCS7* pkcs7, int type) +{ + if (pkcs7 == NULL) + return BAD_FUNC_ARG; + + if (type != CMS_ISSUER_AND_SERIAL_NUMBER && + type != CMS_SKID && + type != DEGENERATE_SID) { + return BAD_FUNC_ARG; + } pkcs7->sidType = type; @@ -8697,14 +8908,10 @@ int wc_PKCS7_SetContentType(wc_PKCS7* pkcs7, byte* contentType, word32 sz) /* return size of padded data, padded to blockSz chunks, or negative on error */ int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz) { - word32 padSz; - if (blockSz == 0) return BAD_FUNC_ARG; - padSz = blockSz - (inputSz % blockSz); - - return (int)padSz; + return (int)(blockSz - (inputSz % blockSz)); } @@ -8713,28 +8920,16 @@ int wc_PKCS7_GetPadSize(word32 inputSz, word32 blockSz) int wc_PKCS7_PadData(byte* in, word32 inSz, byte* out, word32 outSz, word32 blockSz) { - int ret; - word32 i, padSz; - if (in == NULL || inSz == 0 || - out == NULL || outSz == 0) + out == NULL || outSz == 0 || blockSz == 0) return BAD_FUNC_ARG; - ret = wc_PKCS7_GetPadSize(inSz, blockSz); - if (ret < 0) - return ret; - padSz = (word32)ret; - - if (outSz < (inSz + padSz)) + if (outSz < wc_PkcsPad(NULL, inSz, blockSz)) return BAD_FUNC_ARG; XMEMCPY(out, in, inSz); - for (i = 0; i < padSz; i++) { - out[inSz + i] = (byte)padSz; - } - - return (int)(inSz + padSz); + return (int)wc_PkcsPad(out, inSz, blockSz); } @@ -8870,10 +9065,9 @@ static int wc_PKCS7_GenerateKEK_PWRI(wc_PKCS7* pkcs7, byte* passwd, word32 pLen, /* RFC3211 (Section 2.3.1) key wrap algorithm (id-alg-PWRI-KEK). * * Returns output size on success, negative upon error */ -static int wc_PKCS7_PwriKek_KeyWrap(wc_PKCS7* pkcs7, const byte* kek, word32 kekSz, - const byte* cek, word32 cekSz, - byte* out, word32 *outSz, - const byte* iv, word32 ivSz, int algID) +static int wc_PKCS7_PwriKek_KeyWrap(wc_PKCS7* pkcs7, const byte* kek, + word32 kekSz, const byte* cek, word32 cekSz, + byte* out, word32 *outSz, const byte* iv, word32 ivSz, int algID) { WC_RNG rng; int blockSz, outLen, ret; @@ -8926,8 +9120,8 @@ static int wc_PKCS7_PwriKek_KeyWrap(wc_PKCS7* pkcs7, const byte* kek, word32 kek if (ret == 0) { /* encrypt, normal */ ret = wc_PKCS7_EncryptContent(pkcs7, algID, (byte*)kek, (int)kekSz, - (byte*)iv, (int)ivSz, NULL, 0, NULL, 0, out, - outLen, out); + (byte*)iv, (int)ivSz, NULL, 0, NULL, 0, out, + outLen, out); } if (ret == 0) { @@ -8956,7 +9150,7 @@ static int wc_PKCS7_PwriKek_KeyWrap(wc_PKCS7* pkcs7, const byte* kek, word32 kek static int wc_PKCS7_PwriKek_KeyUnWrap(wc_PKCS7* pkcs7, const byte* kek, word32 kekSz, const byte* in, word32 inSz, byte* out, word32 outSz, const byte* iv, - word32 ivSz, int algID) + word32 ivSz, word32 algID) { int blockSz, cekLen, ret; byte* tmpIv = NULL; @@ -8973,7 +9167,7 @@ static int wc_PKCS7_PwriKek_KeyUnWrap(wc_PKCS7* pkcs7, const byte* kek, return MEMORY_E; /* get encryption algorithm block size */ - blockSz = wc_PKCS7_GetOIDBlockSize(algID); + blockSz = wc_PKCS7_GetOIDBlockSize((int)algID); if (blockSz <= 0) { XFREE(outTmp, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); if (blockSz < 0) @@ -8995,21 +9189,21 @@ static int wc_PKCS7_PwriKek_KeyUnWrap(wc_PKCS7* pkcs7, const byte* kek, tmpIv = lastBlock - blockSz; /* decrypt last block */ - ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, (int)kekSz, tmpIv, + ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz, tmpIv, blockSz, NULL, 0, NULL, 0, lastBlock, blockSz, outTmp + inSz - blockSz, pkcs7->devId, pkcs7->heap); if (ret == 0) { /* using last decrypted block as IV, decrypt [0 ... n-1] blocks */ lastBlock = outTmp + inSz - blockSz; - ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, (int)kekSz, + ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz, lastBlock, blockSz, NULL, 0, NULL, 0, (byte*)in, (int)inSz - blockSz, outTmp, pkcs7->devId, pkcs7->heap); } if (ret == 0) { /* decrypt using original kek and iv */ - ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, (int)kekSz, + ret = wc_PKCS7_DecryptContent(pkcs7, algID, (byte*)kek, kekSz, (byte*)iv, (int)ivSz, NULL, 0, NULL, 0, outTmp, (int)inSz, outTmp, pkcs7->devId, pkcs7->heap); } @@ -9224,7 +9418,8 @@ int wc_PKCS7_AddRecipient_PWRI(wc_PKCS7* pkcs7, byte* passwd, word32 pLen, totalSz += (kdfSaltOctetStrSz + saltSz); /* set KDF iteration count */ - kdfIterationsSz = (word32)SetMyVersion((word32)iterations, kdfIterations, 0); + kdfIterationsSz = (word32)SetMyVersion((word32)iterations, kdfIterations, + 0); totalSz += kdfIterationsSz; /* set KDF params SEQ */ @@ -9436,8 +9631,8 @@ int wc_PKCS7_AddRecipient_KEKRI(wc_PKCS7* pkcs7, int keyWrapOID, byte* kek, #endif encryptedKeySz = wc_PKCS7_KeyWrap(pkcs7->cek, pkcs7->cekSz, kek, kekSz, - encryptedKey, (word32)encryptedKeySz, keyWrapOID, - direction); + encryptedKey, (word32)encryptedKeySz, keyWrapOID, + direction); if (encryptedKeySz < 0) { #ifdef WOLFSSL_SMALL_STACK XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); @@ -9817,8 +10012,8 @@ int wc_PKCS7_EncodeEnvelopedData(wc_PKCS7* pkcs7, byte* output, word32 outputSz) return BAD_FUNC_ARG; } - encContentOctetSz = (int)SetImplicit(ASN_OCTET_STRING, 0, (word32)encryptedOutSz, - encContentOctet, pkcs7->encodeStream); + encContentOctetSz = (int)SetImplicit(ASN_OCTET_STRING, 0, + (word32)encryptedOutSz, encContentOctet, pkcs7->encodeStream); encContentSeqSz = (int)SetSequenceEx((word32)(contentTypeSz + contentEncAlgoSz + ivOctetStringSz + blockSz + encContentOctetSz + encryptedOutSz), @@ -9847,18 +10042,19 @@ int wc_PKCS7_EncodeEnvelopedData(wc_PKCS7* pkcs7, byte* output, word32 outputSz) /* resize encrypted content buffer */ if (encryptedContent != NULL) { - XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - encryptedContent = (byte*)XMALLOC(streamSz, pkcs7->heap, - DYNAMIC_TYPE_PKCS7); - if (encryptedContent == NULL) { - XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - wc_PKCS7_FreeEncodedRecipientSet(pkcs7); - return MEMORY_E; - } + XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + encryptedContent = (byte*)XMALLOC(streamSz, pkcs7->heap, + DYNAMIC_TYPE_PKCS7); + if (encryptedContent == NULL) { + XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + wc_PKCS7_FreeEncodedRecipientSet(pkcs7); + return MEMORY_E; + } } } #endif - envDataSeqSz = (int)SetSequenceEx((word32)totalSz, envDataSeq, pkcs7->encodeStream); + envDataSeqSz = (int)SetSequenceEx((word32)totalSz, envDataSeq, + pkcs7->encodeStream); totalSz += envDataSeqSz; #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { @@ -9867,7 +10063,8 @@ int wc_PKCS7_EncodeEnvelopedData(wc_PKCS7* pkcs7, byte* output, word32 outputSz) #endif /* outer content */ - outerContentSz = (int)SetExplicit(0, (word32)totalSz, outerContent, pkcs7->encodeStream); + outerContentSz = (int)SetExplicit(0, (word32)totalSz, outerContent, + pkcs7->encodeStream); #ifdef ASN_BER_TO_DER if (pkcs7->encodeStream) { totalSz += ASN_INDEF_END_SZ; @@ -10087,8 +10284,6 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, ret = BUFFER_E; break; } - pkcs7->stream->expected = (pkcs7->stream->maxLen - - pkcs7->stream->totalRd) + pkcs7->stream->length; #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_2); FALL_THROUGH; @@ -10127,7 +10322,7 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, } pkcs7->stream->expected = (word32)sz + MAX_ALGO_SZ + ASN_TAG_SZ + - MAX_LENGTH_SZ; + MAX_LENGTH_SZ + 512; if (pkcs7->stream->length > 0 && pkcs7->stream->length < pkcs7->stream->expected) { return WC_PKCS7_WANT_READ_E; @@ -10248,7 +10443,8 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, (word32)encryptedKeySz, sidType, version); + wc_PKCS7_StreamStoreVar(pkcs7, (word32)encryptedKeySz, sidType, + version); pkcs7->stream->expected = (word32)encryptedKeySz; #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_3); @@ -10331,8 +10527,8 @@ static int wc_PKCS7_DecryptKtri(wc_PKCS7* pkcs7, byte* in, word32 inSz, if (encOID != RSAESOAEPk) { #endif keySz = wc_RsaPrivateDecryptInline(encryptedKey, - (word32)encryptedKeySz, &outKey, - privKey); + (word32)encryptedKeySz, &outKey, + privKey); #ifndef WC_NO_RSA_OAEP } else { @@ -10964,7 +11160,8 @@ static int wc_PKCS7_DecryptOri(wc_PKCS7* pkcs7, byte* in, word32 inSz, return PKCS7_RECIP_E; } - /* mark recipFound, since we only support one RecipientInfo for now */ + /* mark recipFound, since we only support one RecipientInfo for + * now */ *recipFound = 1; #ifndef NO_PKCS7_STREAM @@ -11120,7 +11317,8 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz, } if (length != blockSz) { - WOLFSSL_MSG("Incorrect IV length, must be of content alg block size"); + WOLFSSL_MSG("Incorrect IV length, must be of content alg block " + "size"); XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7); return ASN_PARSE_E; } @@ -11175,7 +11373,7 @@ static int wc_PKCS7_DecryptPwri(wc_PKCS7* pkcs7, byte* in, word32 inSz, ret = wc_PKCS7_PwriKek_KeyUnWrap(pkcs7, kek, (word32)kekKeySz, pkiMsg + (*idx), (word32)length, cek, cekSz, tmpIv, (word32)blockSz, - (int)pwriEncAlgoId); + pwriEncAlgoId); if (ret < 0) { XFREE(salt, pkcs7->heap, DYNAMIC_TYPE_PKCS7); XFREE(kek, pkcs7->heap, DYNAMIC_TYPE_PKCS7); @@ -11275,8 +11473,8 @@ static int wc_PKCS7_DecryptKekri(wc_PKCS7* pkcs7, byte* in, word32 inSz, localIdx = *idx; if ((*idx < kekIdSz) && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 && tag == ASN_GENERALIZED_TIME) { - if (wc_GetDateInfo(pkiMsg + *idx, (int)pkiMsgSz, &datePtr, &dateFormat, - &dateLen) != 0) { + if (wc_GetDateInfo(pkiMsg + *idx, (int)pkiMsgSz, &datePtr, + &dateFormat, &dateLen) != 0) { return ASN_PARSE_E; } *idx += (word32)(dateLen + 1); @@ -11303,7 +11501,8 @@ static int wc_PKCS7_DecryptKekri(wc_PKCS7* pkcs7, byte* in, word32 inSz, } /* get KeyEncryptionAlgorithmIdentifier */ - if (GetAlgoId(pkiMsg, idx, &keyWrapOID, oidKeyWrapType, pkiMsgSz) < 0) + if (GetAlgoId(pkiMsg, idx, &keyWrapOID, oidKeyWrapType, pkiMsgSz) + < 0) return ASN_PARSE_E; /* get EncryptedKey */ @@ -11324,22 +11523,24 @@ static int wc_PKCS7_DecryptKekri(wc_PKCS7* pkcs7, byte* in, word32 inSz, /* decrypt CEK with KEK */ if (pkcs7->wrapCEKCb) { - keySz = pkcs7->wrapCEKCb(pkcs7, pkiMsg + *idx, (word32)length, keyId, - keyIdSz, NULL, 0, decryptedKey, - *decryptedKeySz, (int)keyWrapOID, - (int)PKCS7_KEKRI, direction); + keySz = pkcs7->wrapCEKCb(pkcs7, pkiMsg + *idx, (word32)length, + keyId, keyIdSz, NULL, 0, decryptedKey, + *decryptedKeySz, (int)keyWrapOID, + (int)PKCS7_KEKRI, direction); } else { - keySz = wc_PKCS7_KeyWrap(pkiMsg + *idx, (word32)length, pkcs7->privateKey, - pkcs7->privateKeySz, decryptedKey, *decryptedKeySz, - (int)keyWrapOID, direction); + keySz = wc_PKCS7_KeyWrap(pkiMsg + *idx, (word32)length, + pkcs7->privateKey, pkcs7->privateKeySz, + decryptedKey, *decryptedKeySz, + (int)keyWrapOID, direction); } if (keySz <= 0) return keySz; *decryptedKeySz = (word32)keySz; - /* mark recipFound, since we only support one RecipientInfo for now */ + /* mark recipFound, since we only support one RecipientInfo for + * now */ *recipFound = 1; *idx += (word32)length; @@ -11387,7 +11588,6 @@ static int wc_PKCS7_DecryptKari(wc_PKCS7* pkcs7, byte* in, word32 inSz, #ifndef NO_PKCS7_STREAM word32 tmpIdx = (idx) ? *idx : 0; #endif - WOLFSSL_ENTER("wc_PKCS7_DecryptKari"); if (pkcs7 == NULL || pkiMsg == NULL || idx == NULL || decryptedKey == NULL || decryptedKeySz == NULL) { @@ -11431,9 +11631,10 @@ static int wc_PKCS7_DecryptKari(wc_PKCS7* pkcs7, byte* in, word32 inSz, /* parse cert and key */ ret = wc_PKCS7_KariParseRecipCert(kari, (byte*)pkcs7->singleCert, - pkcs7->singleCertSz, pkcs7->privateKey, - pkcs7->privateKeySz); - if (ret != 0) { + pkcs7->singleCertSz, pkcs7->privateKey, + pkcs7->privateKeySz); + + if (ret != 0) { wc_PKCS7_KariFree(kari); #ifdef WOLFSSL_SMALL_STACK XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); @@ -11453,7 +11654,8 @@ static int wc_PKCS7_DecryptKari(wc_PKCS7* pkcs7, byte* in, word32 inSz, } /* try and remove optional UserKeyingMaterial */ - ret = wc_PKCS7_KariGetUserKeyingMaterial(kari, pkiMsg, pkiMsgSz, idx); + ret = wc_PKCS7_KariGetUserKeyingMaterial(kari, pkiMsg, pkiMsgSz, + idx); if (ret != 0) { wc_PKCS7_KariFree(kari); #ifdef WOLFSSL_SMALL_STACK @@ -11473,7 +11675,8 @@ static int wc_PKCS7_DecryptKari(wc_PKCS7* pkcs7, byte* in, word32 inSz, return ret; } - /* if user has not explicitly set keyAgreeOID, set from one in bundle */ + /* if user has not explicitly set keyAgreeOID, set from one in + * bundle */ if (pkcs7->keyAgreeOID == 0) pkcs7->keyAgreeOID = (int)keyAgreeOID; @@ -11528,6 +11731,10 @@ static int wc_PKCS7_DecryptKari(wc_PKCS7* pkcs7, byte* in, word32 inSz, ret = wc_ecc_export_x963(kari->senderKey, NULL, &tmpKeySz); PRIVATE_KEY_LOCK(); if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) { + wc_PKCS7_KariFree(kari); + #ifdef WOLFSSL_SMALL_STACK + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + #endif return ret; } @@ -11542,21 +11749,29 @@ static int wc_PKCS7_DecryptKari(wc_PKCS7* pkcs7, byte* in, word32 inSz, tmpKeyDer = (byte*)XMALLOC(tmpKeySz, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); if (tmpKeyDer == NULL) { + wc_PKCS7_KariFree(kari); + #ifdef WOLFSSL_SMALL_STACK + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + #endif return MEMORY_E; } ret = wc_EccPublicKeyToDer(kari->senderKey, tmpKeyDer, tmpKeySz, 1); if (ret < 0) { + wc_PKCS7_KariFree(kari); + #ifdef WOLFSSL_SMALL_STACK + XFREE(encryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + #endif XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); return ret; } tmpKeySz = (word32)ret; - keySz = pkcs7->wrapCEKCb(pkcs7, encryptedKey, (word32)encryptedKeySz, - rid, (word32)keyIdSize, tmpKeyDer, tmpKeySz, - decryptedKey, *decryptedKeySz, - (int)keyWrapOID, (int)PKCS7_KARI, direction); + keySz = pkcs7->wrapCEKCb(pkcs7, encryptedKey, + (word32)encryptedKeySz, rid, (word32)keyIdSize, tmpKeyDer, + tmpKeySz, decryptedKey, *decryptedKeySz, + (int)keyWrapOID, (int)PKCS7_KARI, direction); XFREE(tmpKeyDer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); if (keySz > 0) { @@ -11569,8 +11784,8 @@ static int wc_PKCS7_DecryptKari(wc_PKCS7* pkcs7, byte* in, word32 inSz, } else { /* create KEK */ - ret = wc_PKCS7_KariGenerateKEK(kari, pkcs7->rng, (int)keyWrapOID, - pkcs7->keyAgreeOID); + ret = wc_PKCS7_KariGenerateKEK(kari, pkcs7->rng, + (int)keyWrapOID, pkcs7->keyAgreeOID); if (ret != 0) { wc_PKCS7_KariFree(kari); #ifdef WOLFSSL_SMALL_STACK @@ -11580,9 +11795,9 @@ static int wc_PKCS7_DecryptKari(wc_PKCS7* pkcs7, byte* in, word32 inSz, } /* decrypt CEK with KEK */ - keySz = wc_PKCS7_KeyWrap(encryptedKey, (word32)encryptedKeySz, kari->kek, - kari->kekSz, decryptedKey, *decryptedKeySz, - (int)keyWrapOID, direction); + keySz = wc_PKCS7_KeyWrap(encryptedKey, (word32)encryptedKeySz, + kari->kek, kari->kekSz, decryptedKey, *decryptedKeySz, + (int)keyWrapOID, direction); } if (keySz <= 0) { wc_PKCS7_KariFree(kari); @@ -11710,7 +11925,7 @@ static int wc_PKCS7_DecryptRecipientInfos(wc_PKCS7* pkcs7, byte* in, /* when looking for next recipient, use first sequence and version to * indicate there is another, if not, move on */ - while(*recipFound == 0) { + while (*recipFound == 0) { /* remove RecipientInfo, if we don't have a SEQUENCE, back up idx to * last good saved one */ @@ -11902,7 +12117,6 @@ static int wc_PKCS7_ParseToRecipientInfoSet(wc_PKCS7* pkcs7, byte* in, switch (pkcs7->state) { case WC_PKCS7_INFOSET_START: - case WC_PKCS7_INFOSET_BER: case WC_PKCS7_INFOSET_STAGE1: case WC_PKCS7_INFOSET_STAGE2: case WC_PKCS7_INFOSET_END: @@ -11934,41 +12148,7 @@ static int wc_PKCS7_ParseToRecipientInfoSet(wc_PKCS7* pkcs7, byte* in, if (ret == 0 && length == 0 && pkiMsg[(*idx)-1] == 0x80) { #ifdef ASN_BER_TO_DER - word32 len; - - wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_INFOSET_BER); - FALL_THROUGH; - - /* full buffer is needed for conversion */ - case WC_PKCS7_INFOSET_BER: - #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, - pkcs7->stream->maxLen - pkcs7->stream->length, - &pkiMsg, idx)) != 0) { - return ret; - } - pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: - inSz; - #endif - - len = 0; - - ret = wc_BerToDer(pkiMsg, pkiMsgSz, NULL, &len); - if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) - return ret; - pkcs7->der = (byte*)XMALLOC(len, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - if (pkcs7->der == NULL) - return MEMORY_E; - ret = wc_BerToDer(pkiMsg, pkiMsgSz, pkcs7->der, &len); - if (ret < 0) - return ret; - - pkiMsg = in = pkcs7->der; - pkiMsgSz = pkcs7->derSz = inSz = len; - *idx = 0; - - if (GetSequence(pkiMsg, idx, &length, pkiMsgSz) < 0) - return ASN_PARSE_E; + pkcs7->indefDepth++; #else return BER_INDEF_E; #endif @@ -11997,7 +12177,8 @@ static int wc_PKCS7_ParseToRecipientInfoSet(wc_PKCS7* pkcs7, byte* in, ret = ASN_PARSE_E; if (ret == 0) { - if (type == ENVELOPED_DATA && contentType != ENVELOPED_DATA) { + if (type == ENVELOPED_DATA && contentType != + ENVELOPED_DATA) { WOLFSSL_MSG("PKCS#7 input not of type EnvelopedData"); ret = PKCS7_OID_E; } else if (type == AUTH_ENVELOPED_DATA && @@ -12087,7 +12268,8 @@ static int wc_PKCS7_ParseToRecipientInfoSet(wc_PKCS7* pkcs7, byte* in, } else { /* AuthEnvelopedData version MUST be 0 */ if (version != 0) { - WOLFSSL_MSG("PKCS#7 AuthEnvelopedData needs to be of version 0"); + WOLFSSL_MSG( + "PKCS#7 AuthEnvelopedData needs to be of version 0"); ret = ASN_VERSION_E; } } @@ -12101,6 +12283,7 @@ static int wc_PKCS7_ParseToRecipientInfoSet(wc_PKCS7* pkcs7, byte* in, break; #ifndef NO_PKCS7_STREAM + pkcs7->stream->expected = (word32)length; if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) { break; } @@ -12137,6 +12320,7 @@ WOLFSSL_API int wc_PKCS7_SetKey(wc_PKCS7* pkcs7, byte* key, word32 keySz) } +#if 0 /* append data to encrypted content cache in PKCS7 structure * return 0 on success, negative on error */ static int PKCS7_CacheEncryptedContent(wc_PKCS7* pkcs7, byte* in, word32 inSz) @@ -12170,6 +12354,7 @@ static int PKCS7_CacheEncryptedContent(wc_PKCS7* pkcs7, byte* in, word32 inSz) return 0; } +#endif /* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */ @@ -12198,15 +12383,22 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, byte padLen; byte* encryptedContent = NULL; int explicitOctet = 0; - word32 localIdx; + word32 localIdx = 0; byte tag = 0; if (pkcs7 == NULL) return BAD_FUNC_ARG; - if (pkiMsg == NULL || pkiMsgSz == 0 || - output == NULL || outputSz == 0) + if (pkiMsg == NULL || pkiMsgSz == 0) + return BAD_FUNC_ARG; + + if ((output == NULL || outputSz == 0) + #ifdef ASN_BER_TO_DER + && pkcs7->streamOutCb == NULL + #endif + ) { return BAD_FUNC_ARG; + } #ifndef NO_PKCS7_STREAM (void)tmpIv; /* help out static analysis */ @@ -12220,7 +12412,6 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, switch (pkcs7->state) { case WC_PKCS7_START: case WC_PKCS7_INFOSET_START: - case WC_PKCS7_INFOSET_BER: case WC_PKCS7_INFOSET_STAGE1: case WC_PKCS7_INFOSET_STAGE2: case WC_PKCS7_INFOSET_END: @@ -12230,17 +12421,6 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, break; } - #ifdef ASN_BER_TO_DER - /* check if content was BER and has been converted to DER */ - if (pkcs7->derSz > 0) { - pkiMsg = in = pkcs7->der; - inSz = pkcs7->derSz; - #ifdef NO_PKCS7_STREAM - pkiMsgSz = pkcs7->derSz; - #endif - } - #endif - decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap, DYNAMIC_TYPE_PKCS7); if (decryptedKey == NULL) @@ -12278,7 +12458,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, decryptedKey, &decryptedKeySz, &recipFound); if (ret == 0 && recipFound == 0) { - WOLFSSL_MSG("No recipient found in envelopedData that matches input"); + WOLFSSL_MSG( + "No recipient found in envelopedData that matches input"); ret = PKCS7_RECIP_E; } @@ -12287,6 +12468,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, #ifndef NO_PKCS7_STREAM tmpIdx = idx; pkcs7->stream->aadSz = decryptedKeySz; + pkcs7->stream->expected = MAX_LENGTH_SZ + MAX_VERSION_SZ + + ASN_TAG_SZ + MAX_LENGTH_SZ; #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_3); FALL_THROUGH; @@ -12294,10 +12477,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, case WC_PKCS7_ENV_3: #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ + - MAX_VERSION_SZ + ASN_TAG_SZ + - MAX_LENGTH_SZ, &pkiMsg, &idx)) - != 0) { + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { return ret; } pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz; @@ -12311,6 +12492,40 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, ret = ASN_PARSE_E; } + #ifndef NO_PKCS7_STREAM + if (length == 0) { + /* if indefinite length, assume worst case size + * - Content Type OID + tag/length + * - Algorithm ID structure (OID + parameters) + * - Version + */ + pkcs7->stream->expected = MAX_SEQ_SZ + /* outer sequence */ + MAX_OID_SZ + /* content type OID */ + MAX_ALGO_SZ + /* algo identifier */ + MAX_VERSION_SZ +/* version */ + ASN_TAG_SZ + /* tag */ + MAX_LENGTH_SZ; /* length */ + } + else { + /* revize expected size if known */ + pkcs7->stream->expected = (word32)length + ASN_TAG_SZ; + } + + /* Did we get enough for the expected length? */ + if (pkcs7->stream->expected > pkiMsgSz) { + localIdx = idx; + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { + return ret; + } + pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: + inSz; + if (pkcs7->stream->length > 0) { + idx = localIdx; /* account for byte used with seq read */ + } + } + #endif + if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) { ret = ASN_PARSE_E; @@ -12350,7 +12565,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, } if (ret == 0 && length != expBlockSz) { - WOLFSSL_MSG("Incorrect IV length, must be of content alg block size"); + WOLFSSL_MSG( + "Incorrect IV length, must be of content alg block size"); ret = ASN_PARSE_E; } @@ -12362,8 +12578,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, } wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, length); pkcs7->stream->contentSz = (word32)blockKeySz; - pkcs7->stream->expected = (word32)length + MAX_LENGTH_SZ + MAX_LENGTH_SZ + - ASN_TAG_SZ + ASN_TAG_SZ; + pkcs7->stream->expected = (word32)length + MAX_LENGTH_SZ + + MAX_LENGTH_SZ + ASN_TAG_SZ + ASN_TAG_SZ; #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_4); FALL_THROUGH; @@ -12405,8 +12621,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, } idx++; - if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentTotalSz, - pkiMsgSz) <= 0) { + if (ret == 0 && GetLength_ex(pkiMsg, &idx, &encryptedContentTotalSz, + pkiMsgSz, 0) < 0) { ret = ASN_PARSE_E; } @@ -12418,8 +12634,24 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, break; } pkcs7->stream->expected = (word32)encryptedContentTotalSz; + if (explicitOctet) { + pkcs7->stream->expected = MAX_OCTET_STR_SZ; + } wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, 0); wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, explicitOctet); + + if (explicitOctet) { + /* initialize decryption state in preparation */ + if (pkcs7->decryptionCb == NULL) { + ret = wc_PKCS7_DecryptContentInit(pkcs7, encOID, + pkcs7->stream->aad, pkcs7->stream->aadSz, + pkcs7->stream->tmpIv, expBlockSz, + pkcs7->devId, pkcs7->heap); + if (ret != 0) + break; + } + } + #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_5); FALL_THROUGH; @@ -12436,6 +12668,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, tmpIv = pkcs7->stream->tmpIv; encryptedContentTotalSz = (int)pkcs7->stream->expected; + pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz; + /* restore decrypted key */ decryptedKey = pkcs7->stream->aad; decryptedKeySz = pkcs7->stream->aadSz; @@ -12447,11 +12681,27 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, if (explicitOctet) { /* encrypted content may be fragmented into multiple * consecutive OCTET STRINGs, if so loop through - * collecting and caching encrypted content bytes */ - localIdx = idx; - while (idx < (localIdx + (word32)encryptedContentTotalSz)) { + * decrypting and outputting or caching contents until the indef + * ending tag is found */ - if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) { + while (1) { + encryptedContentSz = 0; + if (pkiMsgSz <= localIdx + MAX_OCTET_STR_SZ) { + #ifndef NO_PKCS7_STREAM + /* ran out of data to parse */ + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { + break; + } + pkiMsgSz = (pkcs7->stream->length > 0) ? + pkcs7->stream->length : inSz; + #else + ret = BUFFER_E; + #endif + } + + localIdx = idx; + if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) < 0) { ret = ASN_PARSE_E; } @@ -12459,61 +12709,175 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in, ret = ASN_PARSE_E; } - if (ret == 0 && GetLength(pkiMsg, &idx, - &encryptedContentSz, pkiMsgSz) <= 0) { + if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, + &encryptedContentSz, pkiMsgSz, 0) <= 0) { ret = ASN_PARSE_E; } + #ifndef NO_PKCS7_STREAM + if (ret == 0) { + /* always try to get 2 extra bytes to catch indef ending */ + pkcs7->stream->expected = (word32)encryptedContentSz + + (localIdx - idx) + ASN_INDEF_END_SZ; + } + #endif + + if (ret == 0 && + pkcs7->cachedEncryptedContentSz < + (word32)encryptedContentSz) { + if (pkcs7->cachedEncryptedContent != NULL) { + XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, + DYNAMIC_TYPE_PKCS7); + } + pkcs7->cachedEncryptedContent = (byte*)XMALLOC( + (word32)encryptedContentSz, pkcs7->heap, + DYNAMIC_TYPE_PKCS7); + if (pkcs7->cachedEncryptedContent == NULL) { + ret = MEMORY_E; + } + } + pkcs7->cachedEncryptedContentSz = + (word32)encryptedContentSz; + + /* sanity check that the buffer has all of the data */ + if (ret == 0 && (localIdx + (word32)encryptedContentSz) > + pkiMsgSz) { + #ifndef NO_PKCS7_STREAM + word32 ofsetIdx = localIdx - idx; + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + pkcs7->stream->expected, &pkiMsg, &localIdx)) + != 0) { + return ret; + } + localIdx += ofsetIdx; + pkiMsgSz = (pkcs7->stream->length > 0)? + pkcs7->stream->length: inSz; + #else + ret = BUFFER_E; + #endif + } + + /* Use callback for decryption still, if set */ + if (ret == 0 && pkcs7->decryptionCb != NULL) { + ret = pkcs7->decryptionCb(pkcs7, (int)encOID, tmpIv, + expBlockSz, NULL, 0, NULL, 0, &pkiMsg[localIdx], + encryptedContentSz, pkcs7->cachedEncryptedContent, + pkcs7->decryptionCtx); + } if (ret == 0) { - ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx], - (word32)encryptedContentSz); + ret = wc_PKCS7_DecryptContentEx(pkcs7, encOID, + tmpIv, expBlockSz, NULL, 0, NULL, 0, + &pkiMsg[localIdx], encryptedContentSz, + pkcs7->cachedEncryptedContent); } + #ifndef NO_PKCS7_STREAM if (ret != 0) { + if (ret == WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)) { + wc_PKCS7_StreamEndCase(pkcs7, &localIdx, &idx); + } break; } + #endif /* advance idx past encrypted content */ - idx += (word32)encryptedContentSz; + localIdx += (word32)encryptedContentSz; + + if (localIdx + ASN_INDEF_END_SZ <= pkiMsgSz) { + if (pkiMsg[localIdx] == ASN_EOC && + pkiMsg[localIdx+1] == ASN_EOC) { + /* found the end of encrypted content */ + localIdx += ASN_INDEF_END_SZ; + break; + } + } + #ifndef NO_PKCS7_STREAM + pkcs7->stream->expected = MAX_OCTET_STR_SZ; + if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &localIdx, + &localIdx)) != 0) { + break; + } + #endif + + /* save last decrypted string to handle padding (this output + * flush happens outside of the while loop in the case that + * the indef end was found) */ + if (ret == 0) { + #ifdef ASN_BER_TO_DER + if (pkcs7->streamOutCb) { + ret = pkcs7->streamOutCb(pkcs7, + pkcs7->cachedEncryptedContent, + (word32)encryptedContentSz, pkcs7->streamCtx); + } + #endif /* ASN_BER_TO_DER */ + } + + idx = localIdx; } if (ret != 0) { + if (ret != WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)) { + /* free up in an error case if not looking for more + * data */ + wc_PKCS7_DecryptContentFree(pkcs7, encOID, + pkcs7->heap); + } break; } - + wc_PKCS7_DecryptContentFree(pkcs7, encOID, pkcs7->heap); } else { - /* cache encrypted content, no OCTET STRING */ - ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx], - (word32)encryptedContentTotalSz); + pkcs7->cachedEncryptedContentSz = + (word32)encryptedContentTotalSz; + pkcs7->cachedEncryptedContent = (byte*)XMALLOC( + pkcs7->cachedEncryptedContentSz, pkcs7->heap, + DYNAMIC_TYPE_PKCS7); + + /* decrypt encryptedContent */ + ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey, + (word32)blockKeySz, tmpIv, expBlockSz, NULL, 0, NULL, 0, + &pkiMsg[idx], encryptedContentTotalSz, + pkcs7->cachedEncryptedContent, + pkcs7->devId, pkcs7->heap); if (ret != 0) { break; } + idx += (word32)encryptedContentTotalSz; } /* use cached content */ encryptedContent = pkcs7->cachedEncryptedContent; encryptedContentSz = (int)pkcs7->cachedEncryptedContentSz; - - /* decrypt encryptedContent */ - ret = wc_PKCS7_DecryptContent(pkcs7, (int)encOID, decryptedKey, - blockKeySz, tmpIv, expBlockSz, NULL, 0, NULL, 0, - encryptedContent, encryptedContentSz, encryptedContent, - pkcs7->devId, pkcs7->heap); - if (ret != 0) { - break; - } - padLen = encryptedContent[encryptedContentSz-1]; /* copy plaintext to output */ - if (padLen > encryptedContentSz || - (word32)(encryptedContentSz - padLen) > outputSz) { + if (padLen > encryptedContentSz) { ret = BUFFER_E; break; } - XMEMCPY(output, encryptedContent, + + #ifdef ASN_BER_TO_DER + if (pkcs7->streamOutCb) { + ret = pkcs7->streamOutCb(pkcs7, encryptedContent, + (word32)encryptedContentSz - padLen, + pkcs7->streamCtx); + if (ret != 0) { + WOLFSSL_MSG("Stream out callback returned failure"); + ret = BUFFER_E; + break; + } + } + else + #endif /* ASN_BER_TO_DER */ + { + if (output == NULL || (word32)(encryptedContentSz - padLen) > + outputSz) { + ret = BUFFER_E; + break; + } + XMEMCPY(output, encryptedContent, (word32)encryptedContentSz - padLen); + } /* free memory, zero out keys */ ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ); @@ -12887,17 +13251,20 @@ int wc_PKCS7_EncodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* output, (int)pkcs7->unauthAttribsSz); unauthAttribsCount = pkcs7->unauthAttribsSz; - flatUnauthAttribs = (byte*)XMALLOC(unauthAttribsSz, pkcs7->heap, - DYNAMIC_TYPE_PKCS7); - if (flatUnauthAttribs == NULL) { - wc_PKCS7_FreeEncodedRecipientSet(pkcs7); - XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - return MEMORY_E; + if (unauthAttribsSz > 0) { + flatUnauthAttribs = (byte*)XMALLOC(unauthAttribsSz, pkcs7->heap, + DYNAMIC_TYPE_PKCS7); + if (flatUnauthAttribs == NULL) { + wc_PKCS7_FreeEncodedRecipientSet(pkcs7); + XFREE(aadBuffer, pkcs7->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(flatAuthAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return MEMORY_E; + } + + FlattenAttributes(pkcs7, flatUnauthAttribs, unauthAttribs, + (int)unauthAttribsCount); } - FlattenAttributes(pkcs7, flatUnauthAttribs, unauthAttribs, - (int)unauthAttribsCount); unauthAttribsSetSz = SetImplicit(ASN_SET, 2, unauthAttribsSz, unauthAttribSet, 0); } @@ -12997,8 +13364,8 @@ int wc_PKCS7_EncodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* output, return BAD_FUNC_ARG; } - encContentOctetSz = (int)SetImplicit(ASN_OCTET_STRING, 0, (word32)encryptedOutSz, - encContentOctet, 0); + encContentOctetSz = (int)SetImplicit(ASN_OCTET_STRING, 0, + (word32)encryptedOutSz, encContentOctet, 0); encContentSeqSz = (int)SetSequence((word32)contentTypeSz + (word32)contentEncAlgoSz + (word32)nonceOctetStringSz + nonceSz + macIntSz + @@ -13137,19 +13504,14 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, int expBlockSz = 0, blockKeySz = 0; byte authTag[WC_AES_BLOCK_SIZE]; byte nonce[GCM_NONCE_MID_SZ]; /* GCM nonce is larger than CCM */ - int nonceSz = 0, authTagSz = 0, macSz = 0; - -#ifdef WOLFSSL_SMALL_STACK + int nonceSz = 0, macSz = 0; + word32 authTagSz = 0; byte* decryptedKey = NULL; -#else - byte decryptedKey[MAX_ENCRYPTED_KEY_SZ]; -#endif int encryptedContentSz = 0; int encryptedAllocSz = 0; byte* encryptedContent = NULL; int explicitOctet = 0; - byte authAttribSetByte = 0; byte* encodedAttribs = NULL; word32 encodedAttribIdx = 0, encodedAttribSz = 0; byte* authAttrib = NULL; @@ -13195,9 +13557,8 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, break; } #endif - #ifdef WOLFSSL_SMALL_STACK decryptedKey = (byte*)XMALLOC(MAX_ENCRYPTED_KEY_SZ, pkcs7->heap, - DYNAMIC_TYPE_PKCS7); + DYNAMIC_TYPE_PKCS7); if (decryptedKey == NULL) { ret = MEMORY_E; break; @@ -13207,7 +13568,6 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, } #ifndef NO_PKCS7_STREAM pkcs7->stream->key = decryptedKey; - #endif #endif XMEMSET(decryptedKey, 0, MAX_ENCRYPTED_KEY_SZ); FALL_THROUGH; @@ -13221,10 +13581,8 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, case WC_PKCS7_DECRYPT_ORI: decryptedKeySz = MAX_ENCRYPTED_KEY_SZ; - #ifdef WOLFSSL_SMALL_STACK - #ifndef NO_PKCS7_STREAM + #ifndef NO_PKCS7_STREAM decryptedKey = pkcs7->stream->key; - #endif #endif ret = wc_PKCS7_DecryptRecipientInfos(pkcs7, in, inSz, &idx, @@ -13235,32 +13593,48 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, } if (recipFound == 0) { - WOLFSSL_MSG("No recipient found in envelopedData that matches input"); + WOLFSSL_MSG( + "No recipient found in envelopedData that matches input"); ret = PKCS7_RECIP_E; break; } #ifndef NO_PKCS7_STREAM tmpIdx = idx; + pkcs7->stream->expected = MAX_SEQ_SZ; #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_3); FALL_THROUGH; case WC_PKCS7_AUTHENV_3: #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_SEQ_SZ + - MAX_ALGO_SZ + MAX_ALGO_SZ + ASN_TAG_SZ, - &pkiMsg, &idx)) != 0) { + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { break; } pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz; #endif /* remove EncryptedContentInfo */ - if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) { + if (ret == 0 && GetSequence_ex(pkiMsg, &idx, &length, pkiMsgSz, 0) + < 0) { ret = ASN_PARSE_E; } + #ifndef NO_PKCS7_STREAM + /* check that the expected size was accurate */ + if (ret == 0) { + if (length > (int)pkcs7->stream->expected && length > + (int)pkiMsgSz) { + pkcs7->stream->expected = (word32)length + 1; + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { + break; + } + } + } + #endif + if (ret == 0 && wc_GetContentType(pkiMsg, &idx, &contentType, pkiMsgSz) < 0) { ret = ASN_PARSE_E; @@ -13370,8 +13744,8 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, ret = ASN_PARSE_E; } - if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz, - pkiMsgSz) <= 0) { + if (ret == 0 && GetLength_ex(pkiMsg, &idx, &encryptedContentSz, + pkiMsgSz, 0) <= 0) { ret = ASN_PARSE_E; } @@ -13411,7 +13785,8 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, } } - pkcs7->stream->expected = (word32)encryptedContentSz; + pkcs7->stream->expected = (word32)encryptedContentSz + + MAX_LENGTH_SZ + ASN_TAG_SZ + ASN_TAG_SZ; wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz, encryptedContentSz); #endif @@ -13421,21 +13796,20 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, case WC_PKCS7_AUTHENV_5: #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ + - ASN_TAG_SZ + ASN_TAG_SZ + pkcs7->stream->expected, - &pkiMsg, &idx)) != 0) { + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { break; } pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz; - encryptedContentSz = (int)pkcs7->stream->expected; + wc_PKCS7_StreamGetVar(pkcs7, &encOID, &blockKeySz, + &encryptedContentSz); #else pkiMsgSz = inSz; #endif if (expBlockSz == 0) { #ifndef NO_PKCS7_STREAM - wc_PKCS7_StreamGetVar(pkcs7, &encOID, NULL, NULL); #endif if (encOID == 0) expBlockSz = 1; @@ -13468,7 +13842,7 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, idx += (word32)encryptedContentSz; } #ifndef NO_PKCS7_STREAM - pkcs7->stream->bufferPt = encryptedContent; + pkcs7->stream->bufferPt = encryptedContent; #endif /* may have IMPLICIT [1] authenticatedAttributes */ @@ -13476,11 +13850,11 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 && tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 1)) { encodedAttribIdx = idx; - encodedAttribs = pkiMsg + idx; idx++; - if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) <= 0) + if (GetLength_ex(pkiMsg, &idx, &length, pkiMsgSz, 0) <= 0) { ret = ASN_PARSE_E; + } #ifndef NO_PKCS7_STREAM pkcs7->stream->expected = (word32)length; #endif @@ -13489,19 +13863,19 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, if (ret != 0) break; - #ifndef NO_PKCS7_STREAM if (encodedAttribSz > 0) { - pkcs7->stream->aadSz = encodedAttribSz; - pkcs7->stream->aad = (byte*)XMALLOC(encodedAttribSz, + encodedAttribs = (byte*)XMALLOC(encodedAttribSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - if (pkcs7->stream->aad == NULL) { + if (encodedAttribs == NULL) { ret = MEMORY_E; break; } - else { - XMEMCPY(pkcs7->stream->aad, encodedAttribs, - (idx - encodedAttribIdx)); - } + } + + #ifndef NO_PKCS7_STREAM + if (encodedAttribSz > 0) { + pkcs7->stream->aadSz = encodedAttribSz; + pkcs7->stream->aad = encodedAttribs; } if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) { @@ -13515,7 +13889,9 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) { break; } + pkcs7->stream->expected = MAX_LENGTH_SZ + ASN_TAG_SZ; #endif + wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_ATRBEND); goto authenv_atrbend; /* jump over attribute cases */ } FALL_THROUGH; @@ -13535,7 +13911,24 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, authAttrib = &pkiMsg[idx]; authAttribSz = length; - if (ret == 0 && wc_PKCS7_ParseAttribs(pkcs7, authAttrib, authAttribSz) < 0) { + { + word32 ofst; + + /* From RFC5083, "For the purpose of constructing the + * AAD, the IMPLICIT [1] tag in the authAttrs field is + * not used for the DER encoding: rather a universal SET + * OF tag is used. */ + ofst = SetSet((word32)length, encodedAttribs); + + XMEMCPY(encodedAttribs + ofst, authAttrib, + (word32)authAttribSz); + } + + /* ignoring the size returned, we know it is + * idx - encodedAttribIdx from parsing what's given */ + + if (ret == 0 && wc_PKCS7_ParseAttribs(pkcs7, authAttrib, + authAttribSz) < 0) { WOLFSSL_MSG("Error parsing authenticated attributes"); ret = ASN_PARSE_E; break; @@ -13544,14 +13937,14 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, idx += (word32)length; #ifndef NO_PKCS7_STREAM - if (encodedAttribSz > 0) { - XMEMCPY(pkcs7->stream->aad + (encodedAttribSz - (word32)length), - authAttrib, (word32)authAttribSz); + if (pkcs7->stream->aadSz > 0) { + XMEMCPY(pkcs7->stream->aad + (pkcs7->stream->aadSz - + (word32)length), authAttrib, (word32)authAttribSz); } if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) { break; } - + pkcs7->stream->expected = MAX_LENGTH_SZ + ASN_TAG_SZ; #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_ATRBEND); FALL_THROUGH; @@ -13559,8 +13952,8 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, case WC_PKCS7_AUTHENV_ATRBEND: authenv_atrbend: #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, MAX_LENGTH_SZ + - ASN_TAG_SZ, &pkiMsg, &idx)) != 0) { + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { return ret; } pkiMsgSz = (pkcs7->stream->length > 0)? pkcs7->stream->length: inSz; @@ -13572,34 +13965,44 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, #endif - /* get authTag OCTET STRING */ - if (ret == 0 && GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) { + localIdx = idx; + + /* Get authTag OCTET STRING */ + if (ret == 0 && pkiMsg[localIdx] != ASN_OCTET_STRING) { ret = ASN_PARSE_E; } - if (ret == 0 && tag != ASN_OCTET_STRING) { + localIdx++; /* move past ASN_OCTET_STRING */ + + if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, &length, + pkiMsgSz, 0) < 0) { ret = ASN_PARSE_E; } + authTagSz = (word32)length; - if (ret == 0 && GetLength(pkiMsg, &idx, &authTagSz, pkiMsgSz) < 0) { - ret = ASN_PARSE_E; + #ifndef NO_PKCS7_STREAM + /* there might not be enough data for the auth tag too */ + if (ret == 0) { + if ((authTagSz + (localIdx - idx)) > pkcs7->stream->expected && + (authTagSz + (localIdx - idx)) > pkiMsgSz) { + pkcs7->stream->expected = authTagSz + + (localIdx - idx); + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { + return ret; + } + } } + #endif + idx = localIdx; - if (ret == 0 && authTagSz > (int)sizeof(authTag)) { + if (ret == 0 && authTagSz > (word32)sizeof(authTag)) { WOLFSSL_MSG("AuthEnvelopedData authTag too large for buffer"); ret = ASN_PARSE_E; } if (ret == 0) { - XMEMCPY(authTag, &pkiMsg[idx], (word32)authTagSz); - idx += (word32)authTagSz; - } - - if (ret == 0 && authAttrib != NULL) { - /* temporarily swap authAttribs byte[0] to SET OF instead of - * IMPLICIT [1], for aad calculation */ - authAttribSetByte = encodedAttribs[0]; - - encodedAttribs[0] = ASN_SET | ASN_CONSTRUCTED; + XMEMCPY(authTag, &pkiMsg[idx], authTagSz); + idx += authTagSz; } if (ret < 0) @@ -13615,15 +14018,15 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, /* store tag for later */ if (authTagSz > 0) { - pkcs7->stream->tagSz = (word32)authTagSz; - pkcs7->stream->tag = (byte*)XMALLOC((word32)authTagSz, + pkcs7->stream->tagSz = authTagSz; + pkcs7->stream->tag = (byte*)XMALLOC(authTagSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7); if (pkcs7->stream->tag == NULL) { ret = MEMORY_E; break; } else { - XMEMCPY(pkcs7->stream->tag, authTag, (word32)authTagSz); + XMEMCPY(pkcs7->stream->tag, authTag, authTagSz); } } @@ -13652,14 +14055,14 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, } if (pkcs7->stream->tagSz > 0) { - authTagSz = (int)pkcs7->stream->tagSz; + authTagSz = pkcs7->stream->tagSz; if (authTagSz > WC_AES_BLOCK_SIZE) { WOLFSSL_MSG("PKCS7 saved tag is too large"); ret = BUFFER_E; break; } else { - XMEMCPY(authTag, pkcs7->stream->tag, (word32)authTagSz); + XMEMCPY(authTag, pkcs7->stream->tag, authTagSz); } } @@ -13671,25 +14074,26 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, wc_PKCS7_StreamGetVar(pkcs7, &encOID, &blockKeySz, &encryptedContentSz); encryptedContent = pkcs7->stream->bufferPt; - #ifdef WOLFSSL_SMALL_STACK decryptedKey = pkcs7->stream->key; - #endif #endif /* decrypt encryptedContent */ - ret = wc_PKCS7_DecryptContent(pkcs7, (int)encOID, decryptedKey, - blockKeySz, nonce, nonceSz, encodedAttribs, encodedAttribSz, - authTag, (word32)authTagSz, encryptedContent, - encryptedContentSz, encryptedContent, pkcs7->devId, - pkcs7->heap); + ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey, + (word32)blockKeySz, nonce, nonceSz, encodedAttribs, + encodedAttribSz, authTag, authTagSz, + encryptedContent, encryptedContentSz, encryptedContent, + pkcs7->devId, pkcs7->heap); if (ret != 0) { XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); return ret; } - if (authAttrib != NULL) { - /* restore authAttrib IMPLICIT [1] */ - encodedAttribs[0] = authAttribSetByte; + if (encodedAttribs != NULL) { + XFREE(encodedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + encodedAttribs = NULL; + #ifndef NO_PKCS7_STREAM + pkcs7->stream->aad = NULL; + #endif } /* copy plaintext to output */ @@ -13700,12 +14104,10 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); encryptedContent = NULL; ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ); - #ifdef WOLFSSL_SMALL_STACK XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); decryptedKey = NULL; - #ifndef NO_PKCS7_STREAM + #ifndef NO_PKCS7_STREAM pkcs7->stream->key = NULL; - #endif #endif ret = encryptedContentSz; #ifndef NO_PKCS7_STREAM @@ -13718,23 +14120,33 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(wc_PKCS7* pkcs7, byte* in, ret = BAD_FUNC_ARG; } -#ifdef WOLFSSL_SMALL_STACK if (ret != 0 && ret != WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)) { if (decryptedKey != NULL) { ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ); + XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + decryptedKey = NULL; + #ifndef NO_PKCS7_STREAM + pkcs7->stream->key = NULL; + #endif } - XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - } -#else - if (ret < 0) { + if (encryptedContent != NULL) { ForceZero(encryptedContent, (word32)encryptedContentSz); XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); encryptedContent = NULL; + #ifndef NO_PKCS7_STREAM + pkcs7->stream->bufferPt = NULL; + #endif + } + + if (encodedAttribs != NULL) { + XFREE(encodedAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + encodedAttribs = NULL; + #ifndef NO_PKCS7_STREAM + pkcs7->stream->aad = NULL; + #endif } - ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ); } -#endif #ifndef NO_PKCS7_STREAM if (ret != 0 && ret != WC_NO_ERR_TRACE(WC_PKCS7_WANT_READ_E)) { @@ -13924,23 +14336,27 @@ int wc_PKCS7_EncodeEncryptedData(wc_PKCS7* pkcs7, byte* output, word32 outputSz) pkcs7->unprotectedAttribs, (int)pkcs7->unprotectedAttribsSz); - flatAttribs = (byte*)XMALLOC(attribsSz, pkcs7->heap, - DYNAMIC_TYPE_PKCS7); - if (flatAttribs == NULL) { - XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - return MEMORY_E; - } + if (attribsSz > 0) { + flatAttribs = (byte*)XMALLOC(attribsSz, pkcs7->heap, + DYNAMIC_TYPE_PKCS7); + if (flatAttribs == NULL) { + XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return MEMORY_E; + } - ret = FlattenAttributes(pkcs7, flatAttribs, attribs, (int)attribsCount); - if (ret != 0) { - XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - return ret; + ret = FlattenAttributes(pkcs7, flatAttribs, attribs, + (int)attribsCount); + if (ret != 0) { + XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(plain, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(flatAttribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return ret; + } } + attribsSetSz = SetImplicit(ASN_SET, 1, attribsSz, attribSet, 0); } else { @@ -14007,8 +14423,10 @@ int wc_PKCS7_EncodeEncryptedData(wc_PKCS7* pkcs7, byte* output, word32 outputSz) if (pkcs7->unprotectedAttribsSz != 0) { XMEMCPY(output + idx, attribSet, attribsSetSz); idx += (int)attribsSetSz; - XMEMCPY(output + idx, flatAttribs, attribsSz); - idx += (int)attribsSz; + if (attribsSz > 0) { + XMEMCPY(output + idx, flatAttribs, attribsSz); + idx += (int)attribsSz; + } } XFREE(attribs, pkcs7->heap, DYNAMIC_TYPE_PKCS7); @@ -14202,7 +14620,8 @@ int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* in, word32 inSz, if (ret == 0 && (ret = GetAlgoId(pkiMsg, &idx, &encOID, oidBlkType, pkiMsgSz)) < 0) ret = ASN_PARSE_E; - if (ret == 0 && (expBlockSz = wc_PKCS7_GetOIDBlockSize((int)encOID)) < 0) + if (ret == 0 && (expBlockSz = + wc_PKCS7_GetOIDBlockSize((int)encOID)) < 0) ret = expBlockSz; if (ret != 0) break; @@ -14243,7 +14662,8 @@ int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* in, word32 inSz, ret = ASN_PARSE_E; if (ret == 0 && length != expBlockSz) { - WOLFSSL_MSG("Incorrect IV length, must be of content alg block size"); + WOLFSSL_MSG( + "Incorrect IV length, must be of content alg block size"); ret = ASN_PARSE_E; } @@ -14322,6 +14742,11 @@ int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* in, word32 inSz, version = (int)pkcs7->stream->vers; tmpIv = pkcs7->stream->tmpIv; #endif + if (encryptedContentSz <= 0) { + ret = BUFFER_E; + break; + } + if (ret == 0 && (encryptedContent = (byte*)XMALLOC( (unsigned int)encryptedContentSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7)) == NULL) { @@ -14335,8 +14760,8 @@ int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* in, word32 inSz, idx += (word32)encryptedContentSz; /* decrypt encryptedContent */ - ret = wc_PKCS7_DecryptContent(pkcs7, (int)encOID, - pkcs7->encryptionKey, (int)pkcs7->encryptionKeySz, + ret = wc_PKCS7_DecryptContent(pkcs7, encOID, + pkcs7->encryptionKey, pkcs7->encryptionKeySz, tmpIv, expBlockSz, NULL, 0, NULL, 0, encryptedContent, encryptedContentSz, encryptedContent, pkcs7->devId, pkcs7->heap); @@ -14374,7 +14799,8 @@ int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* in, word32 inSz, pkiMsgSz, &idx); if (ret != 0) { ForceZero(encryptedContent, (word32)encryptedContentSz); - XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + XFREE(encryptedContent, pkcs7->heap, + DYNAMIC_TYPE_PKCS7); ret = ASN_PARSE_E; } } @@ -14384,7 +14810,8 @@ int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* in, word32 inSz, ForceZero(encryptedContent, (word32)encryptedContentSz); XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - /* go back and check the version now that attribs have been processed */ + /* go back and check the version now that attribs have been + * processed */ if (pkcs7->version == 3 && version != 0) { WOLFSSL_MSG("Wrong PKCS#7 FirmwareEncryptedData version"); return ASN_VERSION_E; @@ -14514,7 +14941,8 @@ int wc_PKCS7_GetNoCerts(wc_PKCS7* pkcs7) #if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA) /* build PKCS#7 compressedData content type, return encrypted size */ -int wc_PKCS7_EncodeCompressedData(wc_PKCS7* pkcs7, byte* output, word32 outputSz) +int wc_PKCS7_EncodeCompressedData(wc_PKCS7* pkcs7, byte* output, + word32 outputSz) { byte contentInfoSeq[MAX_SEQ_SZ]; byte contentInfoTypeOid[MAX_OID_SZ]; @@ -14625,7 +15053,8 @@ int wc_PKCS7_EncodeCompressedData(wc_PKCS7* pkcs7, byte* output, word32 outputSz */ /* ContentInfo content EXPLICIT SEQUENCE */ - contentInfoContentSeqSz = SetExplicit(0, totalSz, contentInfoContentSeq, 0); + contentInfoContentSeqSz = SetExplicit(0, totalSz, contentInfoContentSeq, + 0); totalSz += contentInfoContentSeqSz; ret = wc_SetContentType(COMPRESSED_DATA, contentInfoTypeOid, @@ -14686,8 +15115,8 @@ int wc_PKCS7_EncodeCompressedData(wc_PKCS7* pkcs7, byte* output, word32 outputSz /* unwrap and decompress PKCS#7/CMS compressedData object, * Handles content wrapped compressed data and raw compressed data packet * returned decoded size */ -int wc_PKCS7_DecodeCompressedData(wc_PKCS7* pkcs7, byte* pkiMsg, word32 pkiMsgSz, - byte* output, word32 outputSz) +int wc_PKCS7_DecodeCompressedData(wc_PKCS7* pkcs7, byte* pkiMsg, + word32 pkiMsgSz, byte* output, word32 outputSz) { int length, version, ret; word32 idx = 0, algOID, contentType; diff --git a/src/wolfcrypt/src/poly1305.c b/src/wolfcrypt/src/poly1305.c index 718289c..bd72a40 100644 --- a/src/wolfcrypt/src/poly1305.c +++ b/src/wolfcrypt/src/poly1305.c @@ -1,6 +1,6 @@ /* poly1305.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -36,16 +36,10 @@ and Daniel J. Bernstein * 303.004 MiB/s with and 1874.194 MiB/s without. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef HAVE_POLY1305 #include -#include -#include #include #ifdef NO_INLINE #include @@ -529,6 +523,7 @@ int wc_Poly1305SetKey(Poly1305* ctx, const byte* key, word32 keySz) #endif poly1305_setkey_avx(ctx, key); RESTORE_VECTOR_REGISTERS(); + ctx->started = 0; #elif defined(POLY130564) /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ @@ -813,13 +808,49 @@ int wc_Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes) printf("\n"); #endif +#if defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_ARMASM_THUMB2) && \ + !defined(WOLFSSL_ARMASM_NO_NEON) + /* handle leftover */ + if (ctx->leftover) { + size_t want = sizeof(ctx->buffer) - ctx->leftover; + if (want > bytes) + want = bytes; + + for (i = 0; i < want; i++) + ctx->buffer[ctx->leftover + i] = m[i]; + bytes -= (word32)want; + m += want; + ctx->leftover += want; + if (ctx->leftover < sizeof(ctx->buffer)) { + return 0; + } + + poly1305_blocks(ctx, ctx->buffer, sizeof(ctx->buffer)); + ctx->leftover = 0; + } + + /* process full blocks */ + if (bytes >= sizeof(ctx->buffer)) { + size_t want = bytes & ~((size_t)POLY1305_BLOCK_SIZE - 1); + + poly1305_blocks(ctx, m, want); + m += want; + bytes -= (word32)want; + } + + /* store leftover */ + if (bytes) { + for (i = 0; i < bytes; i++) + ctx->buffer[ctx->leftover + i] = m[i]; + ctx->leftover += bytes; + } +#else #ifdef USE_INTEL_POLY1305_SPEEDUP #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_AVX2(intel_flags)) { SAVE_VECTOR_REGISTERS(return _svr_ret;); /* handle leftover */ - if (ctx->leftover) { size_t want = sizeof(ctx->buffer) - ctx->leftover; if (want > bytes) @@ -835,8 +866,10 @@ int wc_Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes) return 0; } - if (!ctx->started) + if (!ctx->started) { poly1305_calc_powers_avx2(ctx); + ctx->started = 1; + } poly1305_blocks_avx2(ctx, ctx->buffer, sizeof(ctx->buffer)); ctx->leftover = 0; } @@ -845,8 +878,10 @@ int wc_Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes) if (bytes >= sizeof(ctx->buffer)) { size_t want = bytes & ~(sizeof(ctx->buffer) - 1); - if (!ctx->started) + if (!ctx->started) { poly1305_calc_powers_avx2(ctx); + ctx->started = 1; + } poly1305_blocks_avx2(ctx, m, want); m += want; bytes -= (word32)want; @@ -902,6 +937,7 @@ int wc_Poly1305Update(Poly1305* ctx, const byte* m, word32 bytes) ctx->leftover += bytes; } } +#endif return 0; } diff --git a/src/wolfcrypt/src/port/Espressif/esp32_aes.c b/src/wolfcrypt/src/port/Espressif/esp32_aes.c index fc0fd7f..b1479de 100644 --- a/src/wolfcrypt/src/port/Espressif/esp32_aes.c +++ b/src/wolfcrypt/src/port/Espressif/esp32_aes.c @@ -1,6 +1,6 @@ /* esp32_aes.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfcrypt/src/port/Espressif/esp32_mp.c b/src/wolfcrypt/src/port/Espressif/esp32_mp.c index 6d9d2ab..dbfd133 100644 --- a/src/wolfcrypt/src/port/Espressif/esp32_mp.c +++ b/src/wolfcrypt/src/port/Espressif/esp32_mp.c @@ -1,6 +1,6 @@ /* esp32_mp.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfcrypt/src/port/Espressif/esp32_sha.c b/src/wolfcrypt/src/port/Espressif/esp32_sha.c index 65d635d..f9f8d90 100644 --- a/src/wolfcrypt/src/port/Espressif/esp32_sha.c +++ b/src/wolfcrypt/src/port/Espressif/esp32_sha.c @@ -1,6 +1,6 @@ /* esp32_sha.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfcrypt/src/port/Espressif/esp32_util.c b/src/wolfcrypt/src/port/Espressif/esp32_util.c index f133875..90b3cdc 100644 --- a/src/wolfcrypt/src/port/Espressif/esp32_util.c +++ b/src/wolfcrypt/src/port/Espressif/esp32_util.c @@ -1,6 +1,6 @@ /* esp32_util.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -37,7 +37,9 @@ #if ESP_IDF_VERSION_MAJOR > 4 #include #include + #include #endif + /* wolfSSL */ #include /* needed to print MATH_INT_T value */ #include @@ -739,15 +741,25 @@ esp_err_t esp_DisableWatchdog(void) #elif defined(CONFIG_IDF_TARGET_ESP32C2) || \ defined(CONFIG_IDF_TARGET_ESP32C3) || \ defined(CONFIG_IDF_TARGET_ESP32C6) || \ - defined(CONFIG_IDF_TARGET_ESP32H2) - ESP_LOGW(TAG, "No known rtc_wdt_protect_off for this platform."); + defined(CONFIG_IDF_TARGET_ESP32H2) || \ + defined(CONFIG_IDF_TARGET_ESP32P4) + #if ESP_IDF_VERSION_MINOR >= 3 + #if CONFIG_ESP_TASK_WDT + ret = esp_task_wdt_deinit(); + #else + /* CONFIG_ESP_TASK_WDT=y needed in sdkconfig */ + ESP_LOGW(TAG, "esp_task_wdt_deinit not available"); + #endif + #else + ESP_LOGW(TAG, "esp_task_wdt_deinit not implemented"); + #endif #else rtc_wdt_protect_off(); rtc_wdt_disable(); #endif } #else - ESP_LOGW(TAG, "esp_DisableWatchdog not implemented on ESP_OIDF v%d", + ESP_LOGW(TAG, "esp_DisableWatchdog not implemented on ESP_IDF v%d", ESP_IDF_VERSION_MAJOR); #endif #endif @@ -780,8 +792,17 @@ esp_err_t esp_EnabledWatchdog(void) #elif defined(CONFIG_IDF_TARGET_ESP32C2) || \ defined(CONFIG_IDF_TARGET_ESP32C3) || \ defined(CONFIG_IDF_TARGET_ESP32C6) || \ - defined(CONFIG_IDF_TARGET_ESP32H2) + defined(CONFIG_IDF_TARGET_ESP32H2) || \ + defined(CONFIG_IDF_TARGET_ESP32P4) + ESP_LOGW(TAG, "No known rtc_wdt_protect_off for this platform."); + esp_task_wdt_config_t twdt_config = { + .timeout_ms = 5000, /* Timeout in milliseconds */ + .trigger_panic = true, /* trigger panic on timeout */ + .idle_core_mask = (1 << 0), /* Enable on Core 0 */ + }; ESP_LOGW(TAG, "No known rtc_wdt_protect_off for this platform."); + esp_task_wdt_init(&twdt_config); + esp_task_wdt_add(NULL); #else rtc_wdt_protect_on(); rtc_wdt_enable(); diff --git a/src/wolfcrypt/src/port/Espressif/esp_sdk_mem_lib.c b/src/wolfcrypt/src/port/Espressif/esp_sdk_mem_lib.c index 81d88a6..5bd7a64 100644 --- a/src/wolfcrypt/src/port/Espressif/esp_sdk_mem_lib.c +++ b/src/wolfcrypt/src/port/Espressif/esp_sdk_mem_lib.c @@ -1,6 +1,6 @@ /* esp_sdk_mem_lib.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfcrypt/src/port/Espressif/esp_sdk_time_lib.c b/src/wolfcrypt/src/port/Espressif/esp_sdk_time_lib.c index 678de3b..036174e 100644 --- a/src/wolfcrypt/src/port/Espressif/esp_sdk_time_lib.c +++ b/src/wolfcrypt/src/port/Espressif/esp_sdk_time_lib.c @@ -1,6 +1,6 @@ /* esp_sdk_time_lib.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfcrypt/src/port/Espressif/esp_sdk_wifi_lib.c b/src/wolfcrypt/src/port/Espressif/esp_sdk_wifi_lib.c index 9a200a9..db7c954 100644 --- a/src/wolfcrypt/src/port/Espressif/esp_sdk_wifi_lib.c +++ b/src/wolfcrypt/src/port/Espressif/esp_sdk_wifi_lib.c @@ -1,6 +1,6 @@ /* esp_sdk_wifi_lib.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfcrypt/src/port/atmel/atmel.c b/src/wolfcrypt/src/port/atmel/atmel.c index 31ad98f..6aabe5d 100644 --- a/src/wolfcrypt/src/port/atmel/atmel.c +++ b/src/wolfcrypt/src/port/atmel/atmel.c @@ -1,6 +1,6 @@ /* atmel.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfcrypt/src/pwdbased.c b/src/wolfcrypt/src/pwdbased.c index 208f667..c60db6a 100644 --- a/src/wolfcrypt/src/pwdbased.c +++ b/src/wolfcrypt/src/pwdbased.c @@ -1,6 +1,6 @@ /* pwdbased.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifndef NO_PWDBASED @@ -42,7 +37,6 @@ #include #include #include -#include #ifdef NO_INLINE #include @@ -52,9 +46,6 @@ #endif #if FIPS_VERSION3_GE(6,0,0) - #ifdef DEBUG_WOLFSSL - #include - #endif const unsigned int wolfCrypt_FIPS_pbkdf_ro_sanity[2] = { 0x1a2b3c4d, 0x00000010 }; int wolfCrypt_FIPS_PBKDF_sanity(void) @@ -840,6 +831,8 @@ int wc_scrypt(byte* output, const byte* passwd, int passLen, goto end; } + XMEMSET(y, 0, (size_t)(blockSize * 128)); + /* Step 1. */ ret = wc_PBKDF2(blocks, passwd, passLen, salt, saltLen, 1, (int)blocksSz, WC_SHA256); diff --git a/src/wolfcrypt/src/random.c b/src/wolfcrypt/src/random.c index febc292..746a06b 100644 --- a/src/wolfcrypt/src/random.c +++ b/src/wolfcrypt/src/random.c @@ -1,6 +1,6 @@ /* random.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -25,15 +25,26 @@ DESCRIPTION This library contains implementation for the random number generator. */ -#ifdef HAVE_CONFIG_H - #include -#endif -#include -#include -#if defined(DEBUG_WOLFSSL) - #include -#endif +/* Possible defines: + * ENTROPY_NUM_UPDATE default: 18 + * Number of updates to perform. A hash is created and memory accessed + * based on the hash values in each update of a sample. + * More updates will result in better entropy quality but longer sample + * times. + * ENTROPY_NUM_UPDATES_BITS default: 5 + * Number of bits needed to represent ENTROPY_NUM_UPDATE. + * = upper(log2(ENTROPY_NUM_UPDATE)) + * ENTROPY_NUM_WORDS_BITS default: 14 + * State has 2^ENTROPY_NUMN_WORDS_BITS entries. Range: 8-30 + * The value should be based on the cache sizes. + * Use a value that is at least as large as the L1 cache if possible. + * The higher the value, the more likely there will be cache misses and + * better the entropy quality. + * A larger value will use more static memory. + */ + +#include /* on HPUX 11 you may need to install /dev/random see http://h20293.www2.hp.com/portal/swdepot/displayProductInfo.do?productNumber=KRNG11I @@ -87,11 +98,12 @@ This library contains implementation for the random number generator. #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0400 #endif + #define _WINSOCKAPI_ /* block inclusion of winsock.h header file */ #include #include + #undef _WINSOCKAPI_ /* undefine it for MINGW winsock2.h header file */ #elif defined(HAVE_WNR) #include - #include wolfSSL_Mutex wnr_mutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(wnr_mutex); /* global netRandom mutex */ int wnr_timeout = 0; /* entropy timeout, milliseconds */ #ifndef WOLFSSL_MUTEX_INITIALIZER @@ -794,8 +806,13 @@ static wc_Sha3 entropyHash; /* Reset the health tests. */ static void Entropy_HealthTest_Reset(void); -#if !defined(ENTROPY_MEMUSE_THREAD) && \ - (defined(__x86_64__) || defined(__i386__)) +#ifdef CUSTOM_ENTROPY_TIMEHIRES +static WC_INLINE word64 Entropy_TimeHiRes(void) +{ + return CUSTOM_ENTROPY_TIMEHIRES(); +} +#elif !defined(ENTROPY_MEMUSE_THREAD) && \ + (defined(__x86_64__) || defined(__i386__)) /* Get the high resolution time counter. * * @return 64-bit count of CPU cycles. @@ -818,7 +835,7 @@ static WC_INLINE word64 Entropy_TimeHiRes(void) */ static WC_INLINE word64 Entropy_TimeHiRes(void) { - return mach_absolute_time(); + return clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW); } #elif !defined(ENTROPY_MEMUSE_THREAD) && defined(__aarch64__) /* Get the high resolution time counter. @@ -913,7 +930,8 @@ static WC_INLINE word64 Entropy_TimeHiRes(void) * @param [in,out] args Entropy data including: counter and stop flag. * @return NULL always. */ -static THREAD_RETURN WOLFSSL_THREAD_NO_JOIN Entropy_IncCounter(void* args) +static THREAD_RETURN_NOJOIN WOLFSSL_THREAD_NO_JOIN + Entropy_IncCounter(void* args) { (void)args; @@ -926,8 +944,9 @@ static THREAD_RETURN WOLFSSL_THREAD_NO_JOIN Entropy_IncCounter(void* args) #ifdef WOLFSSL_DEBUG_ENTROPY_MEMUSE fprintf(stderr, "EXITING ENTROPY COUNTER THREAD\n"); #endif + /* Exit from thread. */ - WOLFSSL_RETURN_FROM_THREAD(0); + RETURN_FROM_THREAD_NOJOIN(0); } /* Start a thread that increments counter if not one already. @@ -1031,9 +1050,18 @@ static void Entropy_StopThread(void) #elif !defined(ENTROPY_NUM_UPDATES_BITS) #define ENTROPY_NUM_UPDATES_BITS ENTROPY_BLOCK_SZ #endif -/* Amount to shift offset to get better coverage of a block */ -#define ENTROPY_OFFSET_SHIFTING \ - (ENTROPY_BLOCK_SZ / ENTROPY_NUM_UPDATES_BITS) +#ifndef ENTROPY_NUM_UPDATES_BITS + #error "ENTROPY_NUM_UPDATES_BITS must be defined - " \ + "upper(log2(ENTROPY_NUM_UPDATES))" +#endif +#if ENTROPY_NUM_UPDATES_BITS != 0 + /* Amount to shift offset to get better coverage of a block */ + #define ENTROPY_OFFSET_SHIFTING \ + (ENTROPY_BLOCK_SZ / ENTROPY_NUM_UPDATES_BITS) +#else + /* Amount to shift offset to get better coverage of a block */ + #define ENTROPY_OFFSET_SHIFTING ENTROPY_BLOCK_SZ +#endif #ifndef ENTROPY_NUM_64BIT_WORDS /* Number of 64-bit words to update - 32. */ @@ -1042,8 +1070,14 @@ static void Entropy_StopThread(void) #error "ENTROPY_NUM_64BIT_WORDS must be <= SHA3-256 digest size in bytes" #endif +#if ENTROPY_BLOCK_SZ < ENTROPY_NUM_UPDATES_BITS +#define EXTRA_ENTROPY_WORDS ENTROPY_NUM_UPDATES +#else +#define EXTRA_ENTROPY_WORDS 0 +#endif + /* State to update that is multiple cache lines long. */ -static word64 entropy_state[ENTROPY_NUM_WORDS] = {0}; +static word64 entropy_state[ENTROPY_NUM_WORDS + EXTRA_ENTROPY_WORDS] = {0}; /* Using memory will take different amount of times depending on the CPU's * caches and business. @@ -1721,16 +1755,21 @@ static int _InitRng(WC_RNG* rng, byte* nonce, word32 nonceSz, #else ret = wc_GenerateSeed(&rng->seed, seed, seedSz); #endif /* WC_RNG_SEED_CB */ - if (ret == 0) - ret = wc_RNG_TestSeed(seed, seedSz); - else { + if (ret != 0) { #if defined(DEBUG_WOLFSSL) - WOLFSSL_MSG_EX("wc_RNG_TestSeed failed... %d", ret); + WOLFSSL_MSG_EX("Seed generation failed... %d", ret); #endif ret = DRBG_FAILURE; rng->status = DRBG_FAILED; } + if (ret == 0) + ret = wc_RNG_TestSeed(seed, seedSz); + #if defined(DEBUG_WOLFSSL) + if (ret != 0) { + WOLFSSL_MSG_EX("wc_RNG_TestSeed failed... %d", ret); + } + #endif if (ret == DRBG_SUCCESS) ret = Hash_DRBG_Instantiate((DRBG_internal *)rng->drbg, seed + SEED_BLOCK_SZ, seedSz - SEED_BLOCK_SZ, @@ -2184,7 +2223,7 @@ static int wc_RNG_HealthTestLocal(int reseed, void* heap, int devId) #endif #ifdef WOLFSSL_SMALL_STACK - check = (byte*)XMALLOC(RNG_HEALTH_TEST_CHECK_SIZE, NULL, + check = (byte*)XMALLOC(RNG_HEALTH_TEST_CHECK_SIZE, heap, DYNAMIC_TYPE_TMP_BUFFER); if (check == NULL) { return MEMORY_E; @@ -2304,7 +2343,7 @@ static int wc_RNG_HealthTestLocal(int reseed, void* heap, int devId) } #ifdef WOLFSSL_SMALL_STACK - XFREE(check, NULL, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(check, heap, DYNAMIC_TYPE_TMP_BUFFER); #endif return ret; @@ -2766,7 +2805,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) return ret; } -#elif defined(MICROCHIP_PIC32) +#elif defined(MICROCHIP_PIC32) || defined(MICROCHIP_MPLAB_HARMONY) #ifdef MICROCHIP_MPLAB_HARMONY #ifdef MICROCHIP_MPLAB_HARMONY_3 diff --git a/src/wolfcrypt/src/rc2.c b/src/wolfcrypt/src/rc2.c index 67dc7d6..33d2bd2 100644 --- a/src/wolfcrypt/src/rc2.c +++ b/src/wolfcrypt/src/rc2.c @@ -1,6 +1,6 @@ /* rc2.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,17 +19,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include + /* DESCRIPTION This library provides the interface to the RC2 encryption algorithm (RFC 2268) */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include #ifdef WC_RC2 @@ -41,7 +38,6 @@ This library provides the interface to the RC2 encryption algorithm (RFC 2268) #endif #include -#include /* Table based on value of PI, defined in RFC 2268 */ static const byte pitable[256] = { diff --git a/src/wolfcrypt/src/ripemd.c b/src/wolfcrypt/src/ripemd.c index 36cca1b..7f3b6d8 100644 --- a/src/wolfcrypt/src/ripemd.c +++ b/src/wolfcrypt/src/ripemd.c @@ -1,6 +1,6 @@ /* ripemd.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,13 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLFSSL_RIPEMD @@ -37,8 +31,6 @@ #include #endif -#include - int wc_InitRipeMd(RipeMd* ripemd) { if (ripemd == NULL) { diff --git a/src/wolfcrypt/src/rsa.c b/src/wolfcrypt/src/rsa.c index a3c0292..94d57bd 100644 --- a/src/wolfcrypt/src/rsa.c +++ b/src/wolfcrypt/src/rsa.c @@ -1,6 +1,6 @@ /* rsa.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -26,12 +26,8 @@ This library provides the interface to the RSA. RSA keys can be used to encrypt, decrypt, sign and verify data. */ -#ifdef HAVE_CONFIG_H - #include -#endif -#include -#include +#include #ifndef NO_RSA @@ -53,7 +49,7 @@ RSA keys can be used to encrypt, decrypt, sign and verify data. #if defined(WOLFSSL_XILINX_CRYPT_VERSAL) #include #endif -#ifdef WOLFSSL_SE050 +#if defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA) #include #endif #ifdef WOLFSSL_HAVE_SP_RSA @@ -95,7 +91,6 @@ RSA Key Size Configuration: #include -#include #ifdef WOLF_CRYPTO_CB #include #endif @@ -298,7 +293,7 @@ int wc_InitRsaKey_Id(RsaKey* key, unsigned char* id, int len, void* heap, int devId) { int ret = 0; -#ifdef WOLFSSL_SE050 +#if defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA) /* SE050 TLS users store a word32 at id, need to cast back */ word32* keyPtr = NULL; #endif @@ -312,7 +307,7 @@ int wc_InitRsaKey_Id(RsaKey* key, unsigned char* id, int len, void* heap, if (ret == 0 && id != NULL && len != 0) { XMEMCPY(key->id, id, (size_t)len); key->idLen = len; - #ifdef WOLFSSL_SE050 + #if defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA) /* Set SE050 ID from word32, populate RsaKey with public from SE050 */ if (len == (int)sizeof(word32)) { keyPtr = (word32*)key->id; @@ -521,7 +516,7 @@ static int cc310_RSA_GenerateKeyPair(RsaKey* key, int size, long e) } #endif /* WOLFSSL_CRYPTOCELL */ -#ifdef WOLFSSL_SE050 +#if defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA) /* Use specified hardware key ID with RsaKey operations. Unlike devId, * keyId is a word32 so can handle key IDs larger than an int. * @@ -646,6 +641,8 @@ static int _ifc_pairwise_consistency_test(RsaKey* key, WC_RNG* rng) ret = wc_RsaEncryptSize(key); if (ret < 0) return ret; + else if (ret == 0) + return BAD_FUNC_ARG; sigLen = (word32)ret; WOLFSSL_MSG("Doing RSA consistency test"); @@ -1756,6 +1753,7 @@ static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen, if (tmp == NULL) { return MEMORY_E; } + XMEMSET(tmp, 0, (size_t)maskLen); #endif if ((ret = RsaMGF(mgf, pkcsBlock + maskLen, (word32)hLen, tmp, (word32)maskLen, @@ -3162,12 +3160,13 @@ static int wc_RsaFunction_ex(const byte* in, word32 inLen, byte* out, int checkSmallCt) { int ret = 0; - (void)rng; - (void)checkSmallCt; #if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_RSA_PAD) RsaPadding padding; #endif + (void)rng; + (void)checkSmallCt; + if (key == NULL || in == NULL || inLen == 0 || out == NULL || outLen == NULL || *outLen == 0 || type == RSA_TYPE_UNKNOWN) { return BAD_FUNC_ARG; @@ -3365,7 +3364,7 @@ static int RsaPublicEncryptEx(const byte* in, word32 inLen, byte* out, return cc310_RsaSSL_Sign(in, inLen, out, outLen, key, cc310_hashModeRSA(hash, 0)); } - #elif defined(WOLFSSL_SE050) + #elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA) if (rsa_type == RSA_PUBLIC_ENCRYPT && pad_value == RSA_BLOCK_TYPE_2) { return se050_rsa_public_encrypt(in, inLen, out, outLen, key, rsa_type, pad_value, pad_type, hash, @@ -3527,7 +3526,7 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out, return cc310_RsaSSL_Verify(in, inLen, out, key, cc310_hashModeRSA(hash, 0)); } - #elif defined(WOLFSSL_SE050) + #elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA) if (rsa_type == RSA_PRIVATE_DECRYPT && pad_value == RSA_BLOCK_TYPE_2) { ret = se050_rsa_private_decrypt(in, inLen, out, outLen, key, rsa_type, pad_value, pad_type, hash, @@ -3600,6 +3599,9 @@ static int RsaPrivateDecryptEx(const byte* in, word32 inLen, byte* out, ret = wc_CryptoCb_RsaPad(in, inLen, out, &outLen, rsa_type, key, rng, &padding); if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + if (ret == 0) { + ret = (int)outLen; + } break; } } @@ -4061,11 +4063,12 @@ int wc_RsaPSS_CheckPadding_ex2(const byte* in, word32 inSz, byte* sig, int ret = 0; byte sigCheckBuf[WC_MAX_DIGEST_SIZE*2 + RSA_PSS_PAD_SZ]; byte *sigCheck = sigCheckBuf; - + int digSz; (void)bits; - if (in == NULL || sig == NULL || - inSz != (word32)wc_HashGetDigestSize(hashType)) { + digSz = wc_HashGetDigestSize(hashType); + + if (in == NULL || sig == NULL || digSz < 0 || inSz != (word32)digSz) { ret = BAD_FUNC_ARG; } @@ -4780,7 +4783,8 @@ int wc_CheckProbablePrime(const byte* pRaw, word32 pRawSz, int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) { #ifndef WC_NO_RNG -#if !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SE050) +#if !defined(WOLFSSL_CRYPTOCELL) && \ + (!defined(WOLFSSL_SE050) || defined(WOLFSSL_SE050_NO_RSA)) #ifdef WOLFSSL_SMALL_STACK mp_int *p = NULL; mp_int *q = NULL; @@ -4823,7 +4827,7 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) #if defined(WOLFSSL_CRYPTOCELL) err = cc310_RSA_GenerateKeyPair(key, size, e); goto out; -#elif defined(WOLFSSL_SE050) +#elif defined(WOLFSSL_SE050) && !defined(WOLFSSL_SE050_NO_RSA) err = se050_rsa_create_key(key, size, e); goto out; #else @@ -4859,17 +4863,17 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) #endif { err = wc_CryptoCb_MakeRsaKey(key, size, e, rng); - #ifndef WOLF_CRYPTO_CB_ONLY_RSA - if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) - goto out; - /* fall-through when unavailable */ - #endif - #ifdef WOLF_CRYPTO_CB_ONLY_RSA - if (err == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) + #ifdef WOLF_CRYPTO_CB_ONLY_RSA + if (err == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { err = NO_VALID_DEVID; goto out; } - #endif + #else + if (err != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) { + goto out; + } + /* fall-through when unavailable */ + #endif } #endif diff --git a/src/wolfcrypt/src/sakke.c b/src/wolfcrypt/src/sakke.c index fab1067..d428c59 100644 --- a/src/wolfcrypt/src/sakke.c +++ b/src/wolfcrypt/src/sakke.c @@ -1,6 +1,6 @@ /* sakke.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,13 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef NO_INLINE #include @@ -40,7 +34,6 @@ #ifdef WOLFCRYPT_HAVE_SAKKE -#include #include #include diff --git a/src/wolfcrypt/src/sha.c b/src/wolfcrypt/src/sha.c index 78ce918..887541a 100644 --- a/src/wolfcrypt/src/sha.c +++ b/src/wolfcrypt/src/sha.c @@ -1,6 +1,6 @@ /* sha.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,18 +19,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef DEBUG_WOLFSSL_VERBOSE #if defined(WOLFSSL_ESPIDF) #include - #else - #include #endif #endif @@ -47,7 +40,6 @@ #endif #include -#include #include #ifdef WOLF_CRYPTO_CB @@ -110,7 +102,6 @@ #else -#include #ifdef NO_INLINE #include #else diff --git a/src/wolfcrypt/src/sha256.c b/src/wolfcrypt/src/sha256.c index c9c3b10..5b990a2 100644 --- a/src/wolfcrypt/src/sha256.c +++ b/src/wolfcrypt/src/sha256.c @@ -1,6 +1,6 @@ /* sha256.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -38,12 +38,7 @@ on the specific device platform. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include -#include +#include /* * SHA256 Build Options: @@ -77,7 +72,6 @@ on the specific device platform. #endif #include -#include #include #include @@ -127,8 +121,6 @@ on the specific device platform. /* #include */ #else -#include - #ifdef NO_INLINE #include #else @@ -209,7 +201,8 @@ on the specific device platform. #define SHA256_UPDATE_REV_BYTES(ctx) (sha256->sha_method == SHA256_C) #else #define SHA256_UPDATE_REV_BYTES(ctx) \ - (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags)) + (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags) && \ + !IS_INTEL_SHA(intel_flags)) #endif #elif defined(FREESCALE_MMCAU_SHA) #define SHA256_UPDATE_REV_BYTES(ctx) 0 /* reverse not needed on update */ @@ -1652,7 +1645,8 @@ static int InitSha256(wc_Sha256* sha256) #ifdef WC_C_DYNAMIC_FALLBACK if (sha256->sha_method != SHA256_C) #else - if (IS_INTEL_AVX1(intel_flags) || IS_INTEL_AVX2(intel_flags)) + if (IS_INTEL_AVX1(intel_flags) || IS_INTEL_AVX2(intel_flags) || + IS_INTEL_SHA(intel_flags)) #endif #endif { @@ -2590,7 +2584,7 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) #endif #ifdef WOLFSSL_HASH_FLAGS - dst->flags |= WC_HASH_FLAG_ISCOPY; + dst->flags |= WC_HASH_FLAG_ISCOPY; #endif #if defined(WOLFSSL_HASH_KEEP) diff --git a/src/wolfcrypt/src/sha3.c b/src/wolfcrypt/src/sha3.c index 4ced66e..a9795ff 100644 --- a/src/wolfcrypt/src/sha3.c +++ b/src/wolfcrypt/src/sha3.c @@ -1,6 +1,6 @@ /* sha3.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_XILINX_CRYPT) && \ !defined(WOLFSSL_AFALG_XILINX_SHA3) @@ -40,7 +35,6 @@ #endif #include -#include #include #ifdef WOLF_CRYPTO_CB @@ -761,7 +755,9 @@ static int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p) if (SHA3_BLOCK == sha3_block_avx2) RESTORE_VECTOR_REGISTERS(); #endif - XMEMCPY(sha3->t, data, len); + if (len > 0) { + XMEMCPY(sha3->t, data, len); + } sha3->i = (byte)(sha3->i + len); return 0; @@ -1499,6 +1495,10 @@ int wc_Shake128_Absorb(wc_Shake* shake, const byte* data, word32 len) { int ret; + if ((shake == NULL) || (data == NULL && len != 0)) { + return BAD_FUNC_ARG; + } + ret = Sha3Update(shake, data, len, WC_SHA3_128_COUNT); if (ret == 0) { byte hash[1]; @@ -1526,6 +1526,9 @@ int wc_Shake128_Absorb(wc_Shake* shake, const byte* data, word32 len) */ int wc_Shake128_SqueezeBlocks(wc_Shake* shake, byte* out, word32 blockCnt) { + if ((shake == NULL) || (out == NULL && blockCnt != 0)) { + return BAD_FUNC_ARG; + } #if defined(WOLFSSL_LINUXKM) && defined(USE_INTEL_SPEEDUP) if (SHA3_BLOCK == sha3_block_avx2) SAVE_VECTOR_REGISTERS(return _svr_ret;); @@ -1644,6 +1647,10 @@ int wc_Shake256_Absorb(wc_Shake* shake, const byte* data, word32 len) { int ret; + if ((shake == NULL) || (data == NULL && len != 0)) { + return BAD_FUNC_ARG; + } + ret = Sha3Update(shake, data, len, WC_SHA3_256_COUNT); if (ret == 0) { byte hash[1]; @@ -1664,6 +1671,9 @@ int wc_Shake256_Absorb(wc_Shake* shake, const byte* data, word32 len) */ int wc_Shake256_SqueezeBlocks(wc_Shake* shake, byte* out, word32 blockCnt) { + if ((shake == NULL) || (out == NULL && blockCnt != 0)) { + return BAD_FUNC_ARG; + } #if defined(WOLFSSL_LINUXKM) && defined(USE_INTEL_SPEEDUP) if (SHA3_BLOCK == sha3_block_avx2) SAVE_VECTOR_REGISTERS(return _svr_ret;); diff --git a/src/wolfcrypt/src/sha512.c b/src/wolfcrypt/src/sha512.c index 16c3c0f..73ef412 100644 --- a/src/wolfcrypt/src/sha512.c +++ b/src/wolfcrypt/src/sha512.c @@ -1,6 +1,6 @@ /* sha512.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if (defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)) && \ (!defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_ARMASM_NO_NEON)) && \ @@ -56,7 +51,6 @@ #endif #include -#include #include #include @@ -73,8 +67,6 @@ #define USE_SLOW_SHA512 #endif -#include - #ifdef NO_INLINE #include #else @@ -1402,22 +1394,16 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512) static int Sha512FinalRaw(wc_Sha512* sha512, byte* hash, size_t digestSz) { -#ifdef LITTLE_ENDIAN_ORDER - word64 digest[WC_SHA512_DIGEST_SIZE / sizeof(word64)]; -#endif - if (sha512 == NULL || hash == NULL) { return BAD_FUNC_ARG; } #ifdef LITTLE_ENDIAN_ORDER - ByteReverseWords64((word64*)digest, (word64*)sha512->digest, - WC_SHA512_DIGEST_SIZE); - XMEMCPY(hash, digest, digestSz); -#else - XMEMCPY(hash, sha512->digest, digestSz); + ByteReverseWords64(sha512->digest, sha512->digest, WC_SHA512_DIGEST_SIZE); #endif + XMEMCPY(hash, sha512->digest, digestSz); + return 0; } @@ -1807,22 +1793,16 @@ int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len) int wc_Sha384FinalRaw(wc_Sha384* sha384, byte* hash) { -#ifdef LITTLE_ENDIAN_ORDER - word64 digest[WC_SHA384_DIGEST_SIZE / sizeof(word64)]; -#endif - if (sha384 == NULL || hash == NULL) { return BAD_FUNC_ARG; } #ifdef LITTLE_ENDIAN_ORDER - ByteReverseWords64((word64*)digest, (word64*)sha384->digest, - WC_SHA384_DIGEST_SIZE); - XMEMCPY(hash, digest, WC_SHA384_DIGEST_SIZE); -#else - XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE); + ByteReverseWords64(sha384->digest, sha384->digest, WC_SHA384_DIGEST_SIZE); #endif + XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE); + return 0; } diff --git a/src/wolfcrypt/src/signature.c b/src/wolfcrypt/src/signature.c index 83c92d8..5576e2e 100644 --- a/src/wolfcrypt/src/signature.c +++ b/src/wolfcrypt/src/signature.c @@ -1,6 +1,6 @@ /* signature.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,15 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include -#ifdef HAVE_CONFIG_H - #include -#endif - -#include #include -#include -#include #ifndef NO_ASN #include #endif diff --git a/src/wolfcrypt/src/siphash.c b/src/wolfcrypt/src/siphash.c index b7c63c3..05c2690 100644 --- a/src/wolfcrypt/src/siphash.c +++ b/src/wolfcrypt/src/siphash.c @@ -1,6 +1,6 @@ /* siphash.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,16 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include -#include +#include #include -#include #ifdef NO_INLINE #include @@ -582,7 +575,7 @@ int wc_SipHash(const unsigned char* key, const unsigned char* in, word32 inSz, return 0; } -#elif !defined(WOLFSSL_NO_ASM) && defined(__GNUC__) && defined(__aarch64__) && \ +#elif defined(WOLFSSL_ARMASM) && defined(__GNUC__) && defined(__aarch64__) && \ (WOLFSSL_SIPHASH_CROUNDS == 1 || WOLFSSL_SIPHASH_CROUNDS == 2) && \ (WOLFSSL_SIPHASH_DROUNDS == 2 || WOLFSSL_SIPHASH_DROUNDS == 4) diff --git a/src/wolfcrypt/src/sm2.c b/src/wolfcrypt/src/sm2.c index 24b8df9..b866522 100644 --- a/src/wolfcrypt/src/sm2.c +++ b/src/wolfcrypt/src/sm2.c @@ -1,6 +1,6 @@ /* sm2.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLFSSL_SM2 diff --git a/src/wolfcrypt/src/sm3.c b/src/wolfcrypt/src/sm3.c index dfbef2e..b4723d8 100644 --- a/src/wolfcrypt/src/sm3.c +++ b/src/wolfcrypt/src/sm3.c @@ -1,6 +1,6 @@ /* sm3.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLFSSL_SM3 diff --git a/src/wolfcrypt/src/sm4.c b/src/wolfcrypt/src/sm4.c index c29cc2b..4da6f0b 100644 --- a/src/wolfcrypt/src/sm4.c +++ b/src/wolfcrypt/src/sm4.c @@ -1,6 +1,6 @@ /* sm4.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLFSSL_SM4 diff --git a/src/wolfcrypt/src/sp_arm32.c b/src/wolfcrypt/src/sp_arm32.c index 13f5578..a70eb35 100644 --- a/src/wolfcrypt/src/sp_arm32.c +++ b/src/wolfcrypt/src/sp_arm32.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -21,16 +21,11 @@ /* Implementation by Sean Parkinson. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \ defined(WOLFSSL_HAVE_SP_ECC) -#include #include #ifdef NO_INLINE #include @@ -114,9 +109,9 @@ static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -256,11 +251,18 @@ static void sp_2048_to_bin_64(sp_digit* r, byte* a) * a A single precision integer. * b A single precision integer. */ -static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #32\n\t" @@ -2238,8 +2240,13 @@ static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ "stm %[r]!, {r3, r4, r5, r6}\n\t" "ldm sp!, {r3, r4, r5, r6}\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", "r12" ); @@ -2252,11 +2259,18 @@ static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ * a A single precision integer. * b A single precision integer. */ -static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #36\n\t" @@ -2592,8 +2606,13 @@ static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ "sub %[r], %[r], #32\n\t" "stm %[r], {r3, r4, r5, r6, r7, r8, r9, r10}\n\t" "add sp, sp, #36\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr" ); @@ -2606,11 +2625,18 @@ static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ * a A single precision integer. * b A single precision integer. */ -static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #44\n\t" @@ -2724,8 +2750,13 @@ static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ "ldm sp, {r3, r4, r5, r6, r7, r8, r9, r10}\n\t" "stm lr, {r3, r4, r5, r6, r7, r8, r9, r10}\n\t" "add sp, sp, #44\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r10", "r11", "r12", "r7", "r8", "r9", "lr" ); @@ -2738,11 +2769,18 @@ static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_2048_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_2048_add_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_2048_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -2761,8 +2799,13 @@ static sp_digit sp_2048_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit "stm %[r]!, {r3, r4, r5, r6}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -2773,10 +2816,16 @@ static sp_digit sp_2048_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit * a A single precision integer and result. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_2048_sub_in_place_16(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_2048_sub_in_place_16(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3, r4, r5}\n\t" @@ -2808,8 +2857,13 @@ static sp_digit sp_2048_sub_in_place_16(sp_digit* a_p, const sp_digit* b_p) "sbcs r5, r5, r9\n\t" "stm %[a]!, {r2, r3, r4, r5}\n\t" "sbc %[a], r9, r9\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; @@ -2821,11 +2875,19 @@ static sp_digit sp_2048_sub_in_place_16(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_2048_add_16(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_2048_add_16(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_2048_add_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -2858,8 +2920,13 @@ static sp_digit sp_2048_add_16(sp_digit* r_p, const sp_digit* a_p, const sp_digi "stm %[r]!, {r3, r4, r5, r6}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -2935,10 +3002,16 @@ SP_NOINLINE static void sp_2048_mul_16(sp_digit* r, const sp_digit* a, * a A single precision integer and result. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_2048_sub_in_place_32(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_2048_sub_in_place_32(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3, r4, r5}\n\t" @@ -2998,8 +3071,13 @@ static sp_digit sp_2048_sub_in_place_32(sp_digit* a_p, const sp_digit* b_p) "sbcs r5, r5, r9\n\t" "stm %[a]!, {r2, r3, r4, r5}\n\t" "sbc %[a], r9, r9\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; @@ -3011,11 +3089,19 @@ static sp_digit sp_2048_sub_in_place_32(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_2048_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_2048_add_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -3076,8 +3162,13 @@ static sp_digit sp_2048_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digi "stm %[r]!, {r3, r4, r5, r6}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -3157,10 +3248,16 @@ SP_NOINLINE static void sp_2048_mul_32(sp_digit* r, const sp_digit* a, * a A single precision integer and result. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_2048_sub_in_place_64(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_2048_sub_in_place_64(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3, r4, r5}\n\t" @@ -3276,8 +3373,13 @@ static sp_digit sp_2048_sub_in_place_64(sp_digit* a_p, const sp_digit* b_p) "sbcs r5, r5, r9\n\t" "stm %[a]!, {r2, r3, r4, r5}\n\t" "sbc %[a], r9, r9\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; @@ -3289,11 +3391,19 @@ static sp_digit sp_2048_sub_in_place_64(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_2048_add_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_2048_add_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -3410,8 +3520,13 @@ static sp_digit sp_2048_add_64(sp_digit* r_p, const sp_digit* a_p, const sp_digi "stm %[r]!, {r3, r4, r5, r6}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -3492,10 +3607,16 @@ SP_NOINLINE static void sp_2048_mul_64(sp_digit* r, const sp_digit* a, * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_2048_sqr_8(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #32\n\t" @@ -4690,8 +4811,13 @@ static void sp_2048_sqr_8(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r2, r3, r4, r8}\n\t" "ldm sp!, {r2, r3, r4, r8}\n\t" "stm %[r]!, {r2, r3, r4, r8}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12" ); @@ -4703,10 +4829,16 @@ static void sp_2048_sqr_8(sp_digit* r_p, const sp_digit* a_p) * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_2048_sqr_8(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x44\n\t" @@ -4934,8 +5066,13 @@ static void sp_2048_sqr_8(sp_digit* r_p, const sp_digit* a_p) "sub %[r], %[r], #32\n\t" "stm %[r], {r3, r4, r5, r6, r7, r8, r9, r10}\n\t" "add sp, sp, #0x44\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr" ); @@ -4947,10 +5084,16 @@ static void sp_2048_sqr_8(sp_digit* r_p, const sp_digit* a_p) * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_2048_sqr_8(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #32\n\t" @@ -5051,8 +5194,13 @@ static void sp_2048_sqr_8(sp_digit* r_p, const sp_digit* a_p) "ldm sp, {r0, r1, r2, r3, r4, r5, r6}\n\t" "stm lr, {r0, r1, r2, r3, r4, r5, r6}\n\t" "add sp, sp, #32\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr" ); @@ -5065,11 +5213,18 @@ static void sp_2048_sqr_8(sp_digit* r_p, const sp_digit* a_p) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_2048_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_2048_sub_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_2048_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -5087,8 +5242,13 @@ static sp_digit sp_2048_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit "sbcs r6, r6, r10\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -5136,11 +5296,19 @@ SP_NOINLINE static void sp_2048_sqr_16(sp_digit* r, const sp_digit* a) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_2048_sub_16(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_2048_sub_16(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_2048_sub_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -5172,8 +5340,13 @@ static sp_digit sp_2048_sub_16(sp_digit* r_p, const sp_digit* a_p, const sp_digi "sbcs r6, r6, r10\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -5221,11 +5394,19 @@ SP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_2048_sub_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_2048_sub_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_2048_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -5285,8 +5466,13 @@ static sp_digit sp_2048_sub_32(sp_digit* r_p, const sp_digit* a_p, const sp_digi "sbcs r6, r6, r10\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -5336,11 +5522,19 @@ SP_NOINLINE static void sp_2048_sqr_64(sp_digit* r, const sp_digit* a) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_2048_add_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_2048_add_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r3, #0\n\t" @@ -5360,8 +5554,13 @@ static sp_digit sp_2048_add_64(sp_digit* r_p, const sp_digit* a_p, const sp_digi "cmp %[a], r12\n\t" "bne L_sp_2048_add_64_word_%=\n\t" "mov %[r], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); @@ -5375,10 +5574,16 @@ static sp_digit sp_2048_add_64(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a A single precision integer. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_2048_sub_in_place_64(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_2048_sub_in_place_64(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -5397,8 +5602,13 @@ static sp_digit sp_2048_sub_in_place_64(sp_digit* a_p, const sp_digit* b_p) "cmp %[a], lr\n\t" "bne L_sp_2048_sub_in_pkace_64_word_%=\n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12", "lr" ); @@ -5413,11 +5623,18 @@ static sp_digit sp_2048_sub_in_place_64(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision integer. */ -static void sp_2048_mul_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_2048_mul_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_2048_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x200\n\t" @@ -5600,8 +5817,13 @@ static void sp_2048_mul_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_2048_mul_64_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -5612,10 +5834,16 @@ static void sp_2048_mul_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_2048_sqr_64(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_2048_sqr_64(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x200\n\t" @@ -5758,8 +5986,13 @@ static void sp_2048_sqr_64(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_2048_sqr_64_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -5791,11 +6024,19 @@ static void sp_2048_mask_32(sp_digit* r, const sp_digit* a, sp_digit m) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_2048_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_2048_add_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r3, #0\n\t" @@ -5815,8 +6056,13 @@ static sp_digit sp_2048_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digi "cmp %[a], r12\n\t" "bne L_sp_2048_add_32_word_%=\n\t" "mov %[r], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); @@ -5830,10 +6076,16 @@ static sp_digit sp_2048_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a A single precision integer. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_2048_sub_in_place_32(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_2048_sub_in_place_32(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -5852,8 +6104,13 @@ static sp_digit sp_2048_sub_in_place_32(sp_digit* a_p, const sp_digit* b_p) "cmp %[a], lr\n\t" "bne L_sp_2048_sub_in_pkace_32_word_%=\n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12", "lr" ); @@ -5868,11 +6125,18 @@ static sp_digit sp_2048_sub_in_place_32(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision integer. */ -static void sp_2048_mul_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_2048_mul_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_2048_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x100\n\t" @@ -6055,8 +6319,13 @@ static void sp_2048_mul_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_2048_mul_32_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -6067,10 +6336,16 @@ static void sp_2048_mul_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_2048_sqr_32(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x100\n\t" @@ -6213,8 +6488,13 @@ static void sp_2048_sqr_32(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_2048_sqr_32_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -6250,11 +6530,17 @@ static void sp_2048_mont_setup(const sp_digit* a, sp_digit* rho) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_2048_mul_d_64(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_2048_mul_d_64(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -6335,8 +6621,13 @@ static void sp_2048_mul_d_64(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) "cmp r9, #0x100\n\t" "blt L_sp_2048_mul_d_64_word_%=\n\t" "str r3, [%[r], #256]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -6348,11 +6639,17 @@ static void sp_2048_mul_d_64(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_2048_mul_d_64(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_2048_mul_d_64(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -8400,8 +8697,13 @@ static void sp_2048_mul_d_64(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) #endif "stm %[r]!, {r3}\n\t" "str r4, [%[r]]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -8431,13 +8733,20 @@ static void sp_2048_mont_norm_32(sp_digit* r, const sp_digit* m) * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_2048_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r6, #0\n\t" @@ -8456,8 +8765,13 @@ static sp_digit sp_2048_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, "cmp lr, #0x80\n\t" "blt L_sp_2048_cond_sub_32_words_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -8472,13 +8786,20 @@ static sp_digit sp_2048_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_2048_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -8595,8 +8916,13 @@ static sp_digit sp_2048_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, "sbcs r5, r5, r7\n\t" "stm %[r]!, {r4, r5}\n\t" "sbc %[r], lr, lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7" ); return (word32)(size_t)r; @@ -8610,11 +8936,19 @@ static sp_digit sp_2048_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( #if !(defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 4)) @@ -9576,8 +9910,13 @@ static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a_p, const sp_digit* m_ "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -9591,11 +9930,19 @@ static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a_p, const sp_digit* m_ * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldr r11, [%[m]]\n\t" @@ -9872,8 +10219,13 @@ static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a_p, const sp_digit* m_ "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -9887,11 +10239,19 @@ static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a_p, const sp_digit* m_ * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* i = 0 */ @@ -10078,8 +10438,13 @@ static SP_NOINLINE void sp_2048_mont_reduce_32(sp_digit* a_p, const sp_digit* m_ "str r7, [%[a], #12]\n\t" "str r8, [%[a], #16]\n\t" "mov %[mp], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -10124,11 +10489,17 @@ SP_NOINLINE static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_2048_mul_d_32(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -10209,8 +10580,13 @@ static void sp_2048_mul_d_32(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) "cmp r9, #0x80\n\t" "blt L_sp_2048_mul_d_32_word_%=\n\t" "str r3, [%[r], #128]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -10222,11 +10598,17 @@ static void sp_2048_mul_d_32(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_2048_mul_d_32(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -11250,8 +11632,13 @@ static void sp_2048_mul_d_32(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) #endif "stm %[r]!, {r4}\n\t" "str r5, [%[r]]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -11267,11 +11654,17 @@ static void sp_2048_mul_d_32(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_2048_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_2048_word_32(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr r6, %[div], #16\n\t" @@ -11309,8 +11702,13 @@ static sp_digit div_2048_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "sub %[d0], %[d0], r3\n\t" "udiv r3, %[d0], %[div]\n\t" "add %[d1], r4, r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -11326,11 +11724,17 @@ static sp_digit div_2048_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_2048_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_2048_word_32(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr lr, %[div], #1\n\t" @@ -11447,8 +11851,13 @@ static sp_digit div_2048_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "subs r6, %[div], r7\n\t" "sbc r6, r6, r6\n\t" "sub %[d1], r3, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -11462,10 +11871,16 @@ static sp_digit div_2048_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) * return -ve, 0 or +ve if a is less than, equal to or greater than b * respectively. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_int32 sp_2048_cmp_32(const sp_digit* a_p, const sp_digit* b_p) +#else +static sp_int32 sp_2048_cmp_32(const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r2, #-1\n\t" @@ -11846,8 +12261,13 @@ static sp_int32 sp_2048_cmp_32(const sp_digit* a_p, const sp_digit* b_p) "eor r2, r2, r3\n\t" #endif /*WOLFSSL_SP_SMALL */ "mov %[a], r2\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)a; @@ -12257,13 +12677,20 @@ static void sp_2048_mont_norm_64(sp_digit* r, const sp_digit* m) * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_2048_cond_sub_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r6, #0\n\t" @@ -12282,8 +12709,13 @@ static sp_digit sp_2048_cond_sub_64(sp_digit* r_p, const sp_digit* a_p, "cmp lr, #0x100\n\t" "blt L_sp_2048_cond_sub_64_words_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -12298,13 +12730,20 @@ static sp_digit sp_2048_cond_sub_64(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_2048_cond_sub_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -12533,8 +12972,13 @@ static sp_digit sp_2048_cond_sub_64(sp_digit* r_p, const sp_digit* a_p, "sbcs r5, r5, r7\n\t" "stm %[r]!, {r4, r5}\n\t" "sbc %[r], lr, lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7" ); return (word32)(size_t)r; @@ -12548,11 +12992,19 @@ static sp_digit sp_2048_cond_sub_64(sp_digit* r_p, const sp_digit* a_p, * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( #if !(defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 4)) @@ -14442,8 +14894,13 @@ static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a_p, const sp_digit* m_ "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -14457,11 +14914,19 @@ static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a_p, const sp_digit* m_ * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldr r11, [%[m]]\n\t" @@ -14994,8 +15459,13 @@ static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a_p, const sp_digit* m_ "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -15009,11 +15479,19 @@ static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a_p, const sp_digit* m_ * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* i = 0 */ @@ -15360,8 +15838,13 @@ static SP_NOINLINE void sp_2048_mont_reduce_64(sp_digit* a_p, const sp_digit* m_ "str r7, [%[a], #12]\n\t" "str r8, [%[a], #16]\n\t" "mov %[mp], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -15406,11 +15889,19 @@ SP_NOINLINE static void sp_2048_mont_sqr_64(sp_digit* r, const sp_digit* a, * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_2048_sub_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_2048_sub_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_2048_sub_64(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -15429,8 +15920,13 @@ static sp_digit sp_2048_sub_64(sp_digit* r_p, const sp_digit* a_p, const sp_digi "cmp %[a], lr\n\t" "bne L_sp_2048_sub_64_word_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "lr" ); @@ -15444,11 +15940,19 @@ static sp_digit sp_2048_sub_64(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_2048_sub_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_2048_sub_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_2048_sub_64(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -15564,8 +16068,13 @@ static sp_digit sp_2048_sub_64(sp_digit* r_p, const sp_digit* a_p, const sp_digi "sbcs r6, r6, r10\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -15582,11 +16091,17 @@ static sp_digit sp_2048_sub_64(sp_digit* r_p, const sp_digit* a_p, const sp_digi * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_2048_word_64(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_2048_word_64(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr r6, %[div], #16\n\t" @@ -15624,8 +16139,13 @@ static sp_digit div_2048_word_64(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "sub %[d0], %[d0], r3\n\t" "udiv r3, %[d0], %[div]\n\t" "add %[d1], r4, r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -15641,11 +16161,17 @@ static sp_digit div_2048_word_64(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_2048_word_64(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_2048_word_64(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr lr, %[div], #1\n\t" @@ -15762,8 +16288,13 @@ static sp_digit div_2048_word_64(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "subs r6, %[div], r7\n\t" "sbc r6, r6, r6\n\t" "sub %[d1], r3, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -15881,10 +16412,16 @@ static void sp_2048_mask_64(sp_digit* r, const sp_digit* a, sp_digit m) * return -ve, 0 or +ve if a is less than, equal to or greater than b * respectively. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_int32 sp_2048_cmp_64(const sp_digit* a_p, const sp_digit* b_p) +#else +static sp_int32 sp_2048_cmp_64(const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r2, #-1\n\t" @@ -16617,8 +17154,13 @@ static sp_int32 sp_2048_cmp_64(const sp_digit* a_p, const sp_digit* b_p) "eor r2, r2, r3\n\t" #endif /*WOLFSSL_SP_SMALL */ "mov %[a], r2\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)a; @@ -17150,13 +17692,20 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, const mp_int* em, * b A single precision number to add. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_2048_cond_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_2048_cond_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -17175,8 +17724,13 @@ static sp_digit sp_2048_cond_add_32(sp_digit* r_p, const sp_digit* a_p, "cmp r12, #0x80\n\t" "blt L_sp_2048_cond_add_32_words_%=\n\t" "mov %[r], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -17191,13 +17745,20 @@ static sp_digit sp_2048_cond_add_32(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to add. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_2048_cond_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_2048_cond_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r8, #0\n\t" @@ -17314,8 +17875,13 @@ static sp_digit sp_2048_cond_add_32(sp_digit* r_p, const sp_digit* a_p, "adcs r5, r5, r7\n\t" "stm %[r]!, {r4, r5}\n\t" "adc %[r], r8, r8\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; @@ -17636,11 +18202,17 @@ int sp_ModExp_2048(const mp_int* base, const mp_int* exp, const mp_int* mod, #ifdef WOLFSSL_HAVE_SP_DH #ifdef HAVE_FFDHE_2048 +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_2048_lshift_64(sp_digit* r_p, const sp_digit* a_p, byte n_p) +#else +static void sp_2048_lshift_64(sp_digit* r, const sp_digit* a, byte n) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register byte n asm ("r2") = (byte)n_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "rsb r12, %[n], #31\n\t" @@ -18028,8 +18600,13 @@ static void sp_2048_lshift_64(sp_digit* r_p, const sp_digit* a_p, byte n_p) "orr r6, r6, r3\n\t" "str r5, [%[r]]\n\t" "str r6, [%[r], #4]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [n] "+r" (n) : +#else + : + : [r] "r" (r), [a] "r" (a), [n] "r" (n) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r3", "r12" ); } @@ -18317,9 +18894,9 @@ static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -18458,11 +19035,18 @@ static void sp_3072_to_bin_96(sp_digit* r, byte* a) * a A single precision integer. * b A single precision integer. */ -static void sp_3072_mul_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_3072_mul_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #48\n\t" @@ -23942,8 +24526,13 @@ static void sp_3072_mul_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b "stm %[r]!, {r3, r4, r5, r6}\n\t" "ldm sp!, {r3, r4, r5, r6}\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", "r12" ); @@ -23955,11 +24544,19 @@ static void sp_3072_mul_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_3072_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_3072_add_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_3072_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -23985,8 +24582,13 @@ static sp_digit sp_3072_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digi "stm %[r]!, {r3, r4, r5, r6}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -23997,10 +24599,16 @@ static sp_digit sp_3072_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a A single precision integer and result. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_3072_sub_in_place_24(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_3072_sub_in_place_24(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3, r4, r5}\n\t" @@ -24046,8 +24654,13 @@ static sp_digit sp_3072_sub_in_place_24(sp_digit* a_p, const sp_digit* b_p) "sbcs r5, r5, r9\n\t" "stm %[a]!, {r2, r3, r4, r5}\n\t" "sbc %[a], r9, r9\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; @@ -24059,11 +24672,19 @@ static sp_digit sp_3072_sub_in_place_24(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_3072_add_24(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_3072_add_24(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_3072_add_24(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -24110,8 +24731,13 @@ static sp_digit sp_3072_add_24(sp_digit* r_p, const sp_digit* a_p, const sp_digi "stm %[r]!, {r3, r4, r5, r6}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -24191,10 +24817,16 @@ SP_NOINLINE static void sp_3072_mul_24(sp_digit* r, const sp_digit* a, * a A single precision integer and result. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_3072_sub_in_place_48(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_3072_sub_in_place_48(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3, r4, r5}\n\t" @@ -24282,8 +24914,13 @@ static sp_digit sp_3072_sub_in_place_48(sp_digit* a_p, const sp_digit* b_p) "sbcs r5, r5, r9\n\t" "stm %[a]!, {r2, r3, r4, r5}\n\t" "sbc %[a], r9, r9\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; @@ -24295,11 +24932,19 @@ static sp_digit sp_3072_sub_in_place_48(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_3072_add_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_3072_add_48(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -24388,8 +25033,13 @@ static sp_digit sp_3072_add_48(sp_digit* r_p, const sp_digit* a_p, const sp_digi "stm %[r]!, {r3, r4, r5, r6}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -24469,10 +25119,16 @@ SP_NOINLINE static void sp_3072_mul_48(sp_digit* r, const sp_digit* a, * a A single precision integer and result. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_3072_sub_in_place_96(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_3072_sub_in_place_96(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3, r4, r5}\n\t" @@ -24644,8 +25300,13 @@ static sp_digit sp_3072_sub_in_place_96(sp_digit* a_p, const sp_digit* b_p) "sbcs r5, r5, r9\n\t" "stm %[a]!, {r2, r3, r4, r5}\n\t" "sbc %[a], r9, r9\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; @@ -24657,11 +25318,19 @@ static sp_digit sp_3072_sub_in_place_96(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_3072_add_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_3072_add_96(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -24834,8 +25503,13 @@ static sp_digit sp_3072_add_96(sp_digit* r_p, const sp_digit* a_p, const sp_digi "stm %[r]!, {r3, r4, r5, r6}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -24915,10 +25589,16 @@ SP_NOINLINE static void sp_3072_mul_96(sp_digit* r, const sp_digit* a, * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_3072_sqr_12(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #48\n\t" @@ -27966,8 +28646,13 @@ static void sp_3072_sqr_12(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r2, r3, r4, r8}\n\t" "ldm sp!, {r2, r3, r4, r8}\n\t" "stm %[r]!, {r2, r3, r4, r8}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12" ); @@ -27979,11 +28664,19 @@ static void sp_3072_sqr_12(sp_digit* r_p, const sp_digit* a_p) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_3072_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_3072_sub_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_3072_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -28008,8 +28701,13 @@ static sp_digit sp_3072_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digi "sbcs r6, r6, r10\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -28057,11 +28755,19 @@ SP_NOINLINE static void sp_3072_sqr_24(sp_digit* r, const sp_digit* a) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_3072_sub_24(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_3072_sub_24(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_3072_sub_24(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -28107,8 +28813,13 @@ static sp_digit sp_3072_sub_24(sp_digit* r_p, const sp_digit* a_p, const sp_digi "sbcs r6, r6, r10\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -28156,11 +28867,19 @@ SP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_3072_sub_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_3072_sub_48(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_3072_sub_48(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -28248,8 +28967,13 @@ static sp_digit sp_3072_sub_48(sp_digit* r_p, const sp_digit* a_p, const sp_digi "sbcs r6, r6, r10\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -28299,11 +29023,19 @@ SP_NOINLINE static void sp_3072_sqr_96(sp_digit* r, const sp_digit* a) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_3072_add_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_3072_add_96(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r3, #0\n\t" @@ -28323,8 +29055,13 @@ static sp_digit sp_3072_add_96(sp_digit* r_p, const sp_digit* a_p, const sp_digi "cmp %[a], r12\n\t" "bne L_sp_3072_add_96_word_%=\n\t" "mov %[r], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); @@ -28338,10 +29075,16 @@ static sp_digit sp_3072_add_96(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a A single precision integer. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_3072_sub_in_place_96(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_3072_sub_in_place_96(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -28360,8 +29103,13 @@ static sp_digit sp_3072_sub_in_place_96(sp_digit* a_p, const sp_digit* b_p) "cmp %[a], lr\n\t" "bne L_sp_3072_sub_in_pkace_96_word_%=\n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12", "lr" ); @@ -28376,11 +29124,18 @@ static sp_digit sp_3072_sub_in_place_96(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision integer. */ -static void sp_3072_mul_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_3072_mul_96(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_3072_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x300\n\t" @@ -28563,8 +29318,13 @@ static void sp_3072_mul_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_3072_mul_96_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -28575,10 +29335,16 @@ static void sp_3072_mul_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_3072_sqr_96(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_3072_sqr_96(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x300\n\t" @@ -28721,8 +29487,13 @@ static void sp_3072_sqr_96(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_3072_sqr_96_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -28754,11 +29525,19 @@ static void sp_3072_mask_48(sp_digit* r, const sp_digit* a, sp_digit m) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_3072_add_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_3072_add_48(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r3, #0\n\t" @@ -28778,8 +29557,13 @@ static sp_digit sp_3072_add_48(sp_digit* r_p, const sp_digit* a_p, const sp_digi "cmp %[a], r12\n\t" "bne L_sp_3072_add_48_word_%=\n\t" "mov %[r], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); @@ -28793,10 +29577,16 @@ static sp_digit sp_3072_add_48(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a A single precision integer. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_3072_sub_in_place_48(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_3072_sub_in_place_48(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -28815,8 +29605,13 @@ static sp_digit sp_3072_sub_in_place_48(sp_digit* a_p, const sp_digit* b_p) "cmp %[a], lr\n\t" "bne L_sp_3072_sub_in_pkace_48_word_%=\n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12", "lr" ); @@ -28831,11 +29626,18 @@ static sp_digit sp_3072_sub_in_place_48(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision integer. */ -static void sp_3072_mul_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_3072_mul_48(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_3072_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x180\n\t" @@ -29018,8 +29820,13 @@ static void sp_3072_mul_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_3072_mul_48_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -29030,10 +29837,16 @@ static void sp_3072_mul_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_3072_sqr_48(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x180\n\t" @@ -29176,8 +29989,13 @@ static void sp_3072_sqr_48(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_3072_sqr_48_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -29213,11 +30031,17 @@ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_3072_mul_d_96(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_3072_mul_d_96(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -29298,8 +30122,13 @@ static void sp_3072_mul_d_96(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) "cmp r9, #0x180\n\t" "blt L_sp_3072_mul_d_96_word_%=\n\t" "str r3, [%[r], #384]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -29311,11 +30140,17 @@ static void sp_3072_mul_d_96(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_3072_mul_d_96(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_3072_mul_d_96(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -32387,8 +33222,13 @@ static void sp_3072_mul_d_96(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) #endif "stm %[r]!, {r5}\n\t" "str r3, [%[r]]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -32418,13 +33258,20 @@ static void sp_3072_mont_norm_48(sp_digit* r, const sp_digit* m) * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_3072_cond_sub_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r6, #0\n\t" @@ -32443,8 +33290,13 @@ static sp_digit sp_3072_cond_sub_48(sp_digit* r_p, const sp_digit* a_p, "cmp lr, #0xc0\n\t" "blt L_sp_3072_cond_sub_48_words_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -32459,13 +33311,20 @@ static sp_digit sp_3072_cond_sub_48(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_3072_cond_sub_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -32638,8 +33497,13 @@ static sp_digit sp_3072_cond_sub_48(sp_digit* r_p, const sp_digit* a_p, "sbcs r5, r5, r7\n\t" "stm %[r]!, {r4, r5}\n\t" "sbc %[r], lr, lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7" ); return (word32)(size_t)r; @@ -32653,11 +33517,19 @@ static sp_digit sp_3072_cond_sub_48(sp_digit* r_p, const sp_digit* a_p, * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( #if !(defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 4)) @@ -34083,8 +34955,13 @@ static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a_p, const sp_digit* m_ "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -34098,11 +34975,19 @@ static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a_p, const sp_digit* m_ * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldr r11, [%[m]]\n\t" @@ -34507,8 +35392,13 @@ static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a_p, const sp_digit* m_ "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -34522,11 +35412,19 @@ static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a_p, const sp_digit* m_ * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* i = 0 */ @@ -34793,8 +35691,13 @@ static SP_NOINLINE void sp_3072_mont_reduce_48(sp_digit* a_p, const sp_digit* m_ "str r7, [%[a], #12]\n\t" "str r8, [%[a], #16]\n\t" "mov %[mp], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -34839,11 +35742,17 @@ SP_NOINLINE static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_3072_mul_d_48(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -34924,8 +35833,13 @@ static void sp_3072_mul_d_48(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) "cmp r9, #0xc0\n\t" "blt L_sp_3072_mul_d_48_word_%=\n\t" "str r3, [%[r], #192]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -34937,11 +35851,17 @@ static void sp_3072_mul_d_48(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_3072_mul_d_48(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -36477,8 +37397,13 @@ static void sp_3072_mul_d_48(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) #endif "stm %[r]!, {r5}\n\t" "str r3, [%[r]]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -36494,11 +37419,17 @@ static void sp_3072_mul_d_48(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_3072_word_48(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_3072_word_48(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr r6, %[div], #16\n\t" @@ -36536,8 +37467,13 @@ static sp_digit div_3072_word_48(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "sub %[d0], %[d0], r3\n\t" "udiv r3, %[d0], %[div]\n\t" "add %[d1], r4, r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -36553,11 +37489,17 @@ static sp_digit div_3072_word_48(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_3072_word_48(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_3072_word_48(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr lr, %[div], #1\n\t" @@ -36674,8 +37616,13 @@ static sp_digit div_3072_word_48(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "subs r6, %[div], r7\n\t" "sbc r6, r6, r6\n\t" "sub %[d1], r3, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -36689,10 +37636,16 @@ static sp_digit div_3072_word_48(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) * return -ve, 0 or +ve if a is less than, equal to or greater than b * respectively. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_int32 sp_3072_cmp_48(const sp_digit* a_p, const sp_digit* b_p) +#else +static sp_int32 sp_3072_cmp_48(const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r2, #-1\n\t" @@ -37249,8 +38202,13 @@ static sp_int32 sp_3072_cmp_48(const sp_digit* a_p, const sp_digit* b_p) "eor r2, r2, r3\n\t" #endif /*WOLFSSL_SP_SMALL */ "mov %[a], r2\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)a; @@ -37660,13 +38618,20 @@ static void sp_3072_mont_norm_96(sp_digit* r, const sp_digit* m) * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_3072_cond_sub_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r6, #0\n\t" @@ -37685,8 +38650,13 @@ static sp_digit sp_3072_cond_sub_96(sp_digit* r_p, const sp_digit* a_p, "cmp lr, #0x180\n\t" "blt L_sp_3072_cond_sub_96_words_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -37701,13 +38671,20 @@ static sp_digit sp_3072_cond_sub_96(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_3072_cond_sub_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -38048,8 +39025,13 @@ static sp_digit sp_3072_cond_sub_96(sp_digit* r_p, const sp_digit* a_p, "sbcs r5, r5, r7\n\t" "stm %[r]!, {r4, r5}\n\t" "sbc %[r], lr, lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7" ); return (word32)(size_t)r; @@ -38063,11 +39045,19 @@ static sp_digit sp_3072_cond_sub_96(sp_digit* r_p, const sp_digit* a_p, * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( #if !(defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 4)) @@ -40885,8 +41875,13 @@ static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a_p, const sp_digit* m_ "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -40900,11 +41895,19 @@ static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a_p, const sp_digit* m_ * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldr r11, [%[m]]\n\t" @@ -41693,8 +42696,13 @@ static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a_p, const sp_digit* m_ "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -41708,11 +42716,19 @@ static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a_p, const sp_digit* m_ * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* i = 0 */ @@ -42219,8 +43235,13 @@ static SP_NOINLINE void sp_3072_mont_reduce_96(sp_digit* a_p, const sp_digit* m_ "str r7, [%[a], #12]\n\t" "str r8, [%[a], #16]\n\t" "mov %[mp], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -42265,11 +43286,19 @@ SP_NOINLINE static void sp_3072_mont_sqr_96(sp_digit* r, const sp_digit* a, * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_3072_sub_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_3072_sub_96(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_3072_sub_96(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -42288,8 +43317,13 @@ static sp_digit sp_3072_sub_96(sp_digit* r_p, const sp_digit* a_p, const sp_digi "cmp %[a], lr\n\t" "bne L_sp_3072_sub_96_word_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "lr" ); @@ -42303,11 +43337,19 @@ static sp_digit sp_3072_sub_96(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_3072_sub_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_3072_sub_96(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_3072_sub_96(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -42479,8 +43521,13 @@ static sp_digit sp_3072_sub_96(sp_digit* r_p, const sp_digit* a_p, const sp_digi "sbcs r6, r6, r10\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -42497,11 +43544,17 @@ static sp_digit sp_3072_sub_96(sp_digit* r_p, const sp_digit* a_p, const sp_digi * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_3072_word_96(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_3072_word_96(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr r6, %[div], #16\n\t" @@ -42539,8 +43592,13 @@ static sp_digit div_3072_word_96(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "sub %[d0], %[d0], r3\n\t" "udiv r3, %[d0], %[div]\n\t" "add %[d1], r4, r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -42556,11 +43614,17 @@ static sp_digit div_3072_word_96(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_3072_word_96(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_3072_word_96(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr lr, %[div], #1\n\t" @@ -42677,8 +43741,13 @@ static sp_digit div_3072_word_96(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "subs r6, %[div], r7\n\t" "sbc r6, r6, r6\n\t" "sub %[d1], r3, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -42796,10 +43865,16 @@ static void sp_3072_mask_96(sp_digit* r, const sp_digit* a, sp_digit m) * return -ve, 0 or +ve if a is less than, equal to or greater than b * respectively. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_int32 sp_3072_cmp_96(const sp_digit* a_p, const sp_digit* b_p) +#else +static sp_int32 sp_3072_cmp_96(const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r2, #-1\n\t" @@ -42808,9 +43883,8 @@ static sp_int32 sp_3072_cmp_96(const sp_digit* a_p, const sp_digit* b_p) "mov r3, #-1\n\t" #ifdef WOLFSSL_SP_SMALL #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r4, #0x1\n\t" - "lsl r4, r4, #8\n\t" - "add r4, r4, #0x7c\n\t" + "mov r4, #0x7c\n\t" + "orr r4, r4, #0x100\n\t" #else "mov r4, #0x17c\n\t" #endif @@ -43890,8 +44964,13 @@ static sp_int32 sp_3072_cmp_96(const sp_digit* a_p, const sp_digit* b_p) "eor r2, r2, r3\n\t" #endif /*WOLFSSL_SP_SMALL */ "mov %[a], r2\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)a; @@ -44423,13 +45502,20 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, const mp_int* em, * b A single precision number to add. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_3072_cond_add_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_3072_cond_add_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -44448,8 +45534,13 @@ static sp_digit sp_3072_cond_add_48(sp_digit* r_p, const sp_digit* a_p, "cmp r12, #0xc0\n\t" "blt L_sp_3072_cond_add_48_words_%=\n\t" "mov %[r], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -44464,13 +45555,20 @@ static sp_digit sp_3072_cond_add_48(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to add. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_3072_cond_add_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_3072_cond_add_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r8, #0\n\t" @@ -44643,8 +45741,13 @@ static sp_digit sp_3072_cond_add_48(sp_digit* r_p, const sp_digit* a_p, "adcs r5, r5, r7\n\t" "stm %[r]!, {r4, r5}\n\t" "adc %[r], r8, r8\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; @@ -44965,11 +46068,17 @@ int sp_ModExp_3072(const mp_int* base, const mp_int* exp, const mp_int* mod, #ifdef WOLFSSL_HAVE_SP_DH #ifdef HAVE_FFDHE_3072 +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_3072_lshift_96(sp_digit* r_p, const sp_digit* a_p, byte n_p) +#else +static void sp_3072_lshift_96(sp_digit* r, const sp_digit* a, byte n) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register byte n asm ("r2") = (byte)n_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "rsb r12, %[n], #31\n\t" @@ -45549,8 +46658,13 @@ static void sp_3072_lshift_96(sp_digit* r_p, const sp_digit* a_p, byte n_p) "orr r4, r4, r3\n\t" "str r6, [%[r]]\n\t" "str r4, [%[r], #4]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [n] "+r" (n) : +#else + : + : [r] "r" (r), [a] "r" (a), [n] "r" (n) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r3", "r12" ); } @@ -45838,9 +46952,9 @@ static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -45978,10 +47092,16 @@ static void sp_4096_to_bin_128(sp_digit* r, byte* a) * a A single precision integer and result. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_4096_sub_in_place_128(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_4096_sub_in_place_128(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3, r4, r5}\n\t" @@ -46209,8 +47329,13 @@ static sp_digit sp_4096_sub_in_place_128(sp_digit* a_p, const sp_digit* b_p) "sbcs r5, r5, r9\n\t" "stm %[a]!, {r2, r3, r4, r5}\n\t" "sbc %[a], r9, r9\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; @@ -46222,12 +47347,19 @@ static sp_digit sp_4096_sub_in_place_128(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_4096_add_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -46456,8 +47588,13 @@ static sp_digit sp_4096_add_128(sp_digit* r_p, const sp_digit* a_p, "stm %[r]!, {r3, r4, r5, r6}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -46546,12 +47683,19 @@ SP_NOINLINE static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a) * a A single precision integer. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_4096_add_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r3, #0\n\t" @@ -46571,8 +47715,13 @@ static sp_digit sp_4096_add_128(sp_digit* r_p, const sp_digit* a_p, "cmp %[a], r12\n\t" "bne L_sp_4096_add_128_word_%=\n\t" "mov %[r], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); @@ -46586,10 +47735,16 @@ static sp_digit sp_4096_add_128(sp_digit* r_p, const sp_digit* a_p, * a A single precision integer. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_4096_sub_in_place_128(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_4096_sub_in_place_128(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -46608,8 +47763,13 @@ static sp_digit sp_4096_sub_in_place_128(sp_digit* a_p, const sp_digit* b_p) "cmp %[a], lr\n\t" "bne L_sp_4096_sub_in_pkace_128_word_%=\n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12", "lr" ); @@ -46624,11 +47784,18 @@ static sp_digit sp_4096_sub_in_place_128(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision integer. */ -static void sp_4096_mul_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_4096_mul_128(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_4096_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x400\n\t" @@ -46811,8 +47978,13 @@ static void sp_4096_mul_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_4096_mul_128_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -46823,10 +47995,16 @@ static void sp_4096_mul_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_4096_sqr_128(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x400\n\t" @@ -46969,8 +48147,13 @@ static void sp_4096_sqr_128(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_4096_sqr_128_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -47004,11 +48187,17 @@ static void sp_4096_mont_setup(const sp_digit* a, sp_digit* rho) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_4096_mul_d_128(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_4096_mul_d_128(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -47089,8 +48278,13 @@ static void sp_4096_mul_d_128(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) "cmp r9, #0x200\n\t" "blt L_sp_4096_mul_d_128_word_%=\n\t" "str r3, [%[r], #512]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -47102,11 +48296,17 @@ static void sp_4096_mul_d_128(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_4096_mul_d_128(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_4096_mul_d_128(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -51202,8 +52402,13 @@ static void sp_4096_mul_d_128(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) #endif "stm %[r]!, {r4}\n\t" "str r5, [%[r]]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -51234,13 +52439,20 @@ static void sp_4096_mont_norm_128(sp_digit* r, const sp_digit* m) * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_4096_cond_sub_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r6, #0\n\t" @@ -51259,8 +52471,13 @@ static sp_digit sp_4096_cond_sub_128(sp_digit* r_p, const sp_digit* a_p, "cmp lr, #0x200\n\t" "blt L_sp_4096_cond_sub_128_words_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -51275,13 +52492,20 @@ static sp_digit sp_4096_cond_sub_128(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_4096_cond_sub_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -51734,8 +52958,13 @@ static sp_digit sp_4096_cond_sub_128(sp_digit* r_p, const sp_digit* a_p, "sbcs r5, r5, r7\n\t" "stm %[r]!, {r4, r5}\n\t" "sbc %[r], lr, lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7" ); return (word32)(size_t)r; @@ -51749,11 +52978,19 @@ static sp_digit sp_4096_cond_sub_128(sp_digit* r_p, const sp_digit* a_p, * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( #if !(defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 4)) @@ -55499,8 +56736,13 @@ static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a_p, const sp_digit* m "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -55514,11 +56756,19 @@ static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a_p, const sp_digit* m * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldr r11, [%[m]]\n\t" @@ -56563,8 +57813,13 @@ static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a_p, const sp_digit* m "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -56578,11 +57833,19 @@ static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a_p, const sp_digit* m * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* i = 0 */ @@ -57249,8 +58512,13 @@ static SP_NOINLINE void sp_4096_mont_reduce_128(sp_digit* a_p, const sp_digit* m "str r7, [%[a], #12]\n\t" "str r8, [%[a], #16]\n\t" "mov %[mp], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -57295,12 +58563,19 @@ SP_NOINLINE static void sp_4096_mont_sqr_128(sp_digit* r, const sp_digit* a, * a A single precision integer. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_4096_sub_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_4096_sub_128(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -57319,8 +58594,13 @@ static sp_digit sp_4096_sub_128(sp_digit* r_p, const sp_digit* a_p, "cmp %[a], lr\n\t" "bne L_sp_4096_sub_128_word_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "lr" ); @@ -57334,12 +58614,19 @@ static sp_digit sp_4096_sub_128(sp_digit* r_p, const sp_digit* a_p, * a A single precision integer. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_4096_sub_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_4096_sub_128(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -57567,8 +58854,13 @@ static sp_digit sp_4096_sub_128(sp_digit* r_p, const sp_digit* a_p, "sbcs r6, r6, r10\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -57585,11 +58877,17 @@ static sp_digit sp_4096_sub_128(sp_digit* r_p, const sp_digit* a_p, * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_4096_word_128(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_4096_word_128(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr r6, %[div], #16\n\t" @@ -57627,8 +58925,13 @@ static sp_digit div_4096_word_128(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "sub %[d0], %[d0], r3\n\t" "udiv r3, %[d0], %[div]\n\t" "add %[d1], r4, r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -57644,11 +58947,17 @@ static sp_digit div_4096_word_128(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_4096_word_128(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_4096_word_128(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr lr, %[div], #1\n\t" @@ -57765,8 +59074,13 @@ static sp_digit div_4096_word_128(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "subs r6, %[div], r7\n\t" "sbc r6, r6, r6\n\t" "sub %[d1], r3, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -57884,10 +59198,16 @@ static void sp_4096_mask_128(sp_digit* r, const sp_digit* a, sp_digit m) * return -ve, 0 or +ve if a is less than, equal to or greater than b * respectively. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_int32 sp_4096_cmp_128(const sp_digit* a_p, const sp_digit* b_p) +#else +static sp_int32 sp_4096_cmp_128(const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r2, #-1\n\t" @@ -57896,9 +59216,8 @@ static sp_int32 sp_4096_cmp_128(const sp_digit* a_p, const sp_digit* b_p) "mov r3, #-1\n\t" #ifdef WOLFSSL_SP_SMALL #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r4, #0x1\n\t" - "lsl r4, r4, #8\n\t" - "add r4, r4, #0xfc\n\t" + "mov r4, #0xfc\n\t" + "orr r4, r4, #0x100\n\t" #else "mov r4, #0x1fc\n\t" #endif @@ -59330,8 +60649,13 @@ static sp_int32 sp_4096_cmp_128(const sp_digit* a_p, const sp_digit* b_p) "eor r2, r2, r3\n\t" #endif /*WOLFSSL_SP_SMALL */ "mov %[a], r2\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)a; @@ -59863,13 +61187,20 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, const mp_int* em, * b A single precision number to add. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_4096_cond_add_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_4096_cond_add_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -59888,8 +61219,13 @@ static sp_digit sp_4096_cond_add_64(sp_digit* r_p, const sp_digit* a_p, "cmp r12, #0x100\n\t" "blt L_sp_4096_cond_add_64_words_%=\n\t" "mov %[r], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -59904,13 +61240,20 @@ static sp_digit sp_4096_cond_add_64(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to add. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_4096_cond_add_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_4096_cond_add_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r8, #0\n\t" @@ -60139,8 +61482,13 @@ static sp_digit sp_4096_cond_add_64(sp_digit* r_p, const sp_digit* a_p, "adcs r5, r5, r7\n\t" "stm %[r]!, {r4, r5}\n\t" "adc %[r], r8, r8\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; @@ -60461,11 +61809,17 @@ int sp_ModExp_4096(const mp_int* base, const mp_int* exp, const mp_int* mod, #ifdef WOLFSSL_HAVE_SP_DH #ifdef HAVE_FFDHE_4096 +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_4096_lshift_128(sp_digit* r_p, const sp_digit* a_p, byte n_p) +#else +static void sp_4096_lshift_128(sp_digit* r, const sp_digit* a, byte n) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register byte n asm ("r2") = (byte)n_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "rsb r12, %[n], #31\n\t" @@ -61237,8 +62591,13 @@ static void sp_4096_lshift_128(sp_digit* r_p, const sp_digit* a_p, byte n_p) "orr r5, r5, r3\n\t" "str r4, [%[r]]\n\t" "str r5, [%[r], #4]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [n] "+r" (n) : +#else + : + : [r] "r" (r), [a] "r" (a), [n] "r" (n) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r3", "r12" ); } @@ -61531,11 +62890,18 @@ static const sp_digit p256_b[8] = { * a A single precision integer. * b A single precision integer. */ -static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x40\n\t" @@ -61718,8 +63084,13 @@ static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_256_mul_8_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -61733,11 +63104,18 @@ static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p * a A single precision integer. * b A single precision integer. */ -static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #32\n\t" @@ -63715,8 +65093,13 @@ static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p "stm %[r]!, {r3, r4, r5, r6}\n\t" "ldm sp!, {r3, r4, r5, r6}\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", "r12" ); @@ -63729,11 +65112,18 @@ static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p * a A single precision integer. * b A single precision integer. */ -static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #36\n\t" @@ -64069,8 +65459,13 @@ static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p "sub %[r], %[r], #32\n\t" "stm %[r], {r3, r4, r5, r6, r7, r8, r9, r10}\n\t" "add sp, sp, #36\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr" ); @@ -64083,11 +65478,18 @@ static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p * a A single precision integer. * b A single precision integer. */ -static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #44\n\t" @@ -64201,8 +65603,13 @@ static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p "ldm sp, {r3, r4, r5, r6, r7, r8, r9, r10}\n\t" "stm lr, {r3, r4, r5, r6, r7, r8, r9, r10}\n\t" "add sp, sp, #44\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r10", "r11", "r12", "r7", "r8", "r9", "lr" ); @@ -64216,10 +65623,16 @@ static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_256_sqr_8(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x40\n\t" @@ -64362,8 +65775,13 @@ static void sp_256_sqr_8(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_256_sqr_8_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -64376,10 +65794,16 @@ static void sp_256_sqr_8(sp_digit* r_p, const sp_digit* a_p) * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_256_sqr_8(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #32\n\t" @@ -65574,8 +66998,13 @@ static void sp_256_sqr_8(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r2, r3, r4, r8}\n\t" "ldm sp!, {r2, r3, r4, r8}\n\t" "stm %[r]!, {r2, r3, r4, r8}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12" ); @@ -65587,10 +67016,16 @@ static void sp_256_sqr_8(sp_digit* r_p, const sp_digit* a_p) * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_256_sqr_8(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x44\n\t" @@ -65818,8 +67253,13 @@ static void sp_256_sqr_8(sp_digit* r_p, const sp_digit* a_p) "sub %[r], %[r], #32\n\t" "stm %[r], {r3, r4, r5, r6, r7, r8, r9, r10}\n\t" "add sp, sp, #0x44\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr" ); @@ -65831,10 +67271,16 @@ static void sp_256_sqr_8(sp_digit* r_p, const sp_digit* a_p) * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_256_sqr_8(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #32\n\t" @@ -65935,8 +67381,13 @@ static void sp_256_sqr_8(sp_digit* r_p, const sp_digit* a_p) "ldm sp, {r0, r1, r2, r3, r4, r5, r6}\n\t" "stm lr, {r0, r1, r2, r3, r4, r5, r6}\n\t" "add sp, sp, #32\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr" ); @@ -65951,11 +67402,18 @@ static void sp_256_sqr_8(sp_digit* r_p, const sp_digit* a_p) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_256_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_256_add_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r3, #0\n\t" @@ -65975,8 +67433,13 @@ static sp_digit sp_256_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* "cmp %[a], r12\n\t" "bne L_sp_256_add_8_word_%=\n\t" "mov %[r], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); @@ -65990,11 +67453,18 @@ static sp_digit sp_256_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_256_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_256_add_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -66013,8 +67483,13 @@ static sp_digit sp_256_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* "stm %[r]!, {r3, r4, r5, r6}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -66027,11 +67502,18 @@ static sp_digit sp_256_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* * a The number to convert. * m The modulus (prime). */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static int sp_256_mod_mul_norm_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +#else +static int sp_256_mod_mul_norm_8(sp_digit* r, const sp_digit* a, + const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #24\n\t" @@ -66250,12 +67732,21 @@ static int sp_256_mod_mul_norm_8(sp_digit* r_p, const sp_digit* a_p, "stm %[r], {r2, r3, r4, r5, r6, r7, r8, lr}\n\t" "mov %[r], #0\n\t" "add sp, sp, #24\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12", "lr", "r10" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ return (word32)(size_t)r; } @@ -66464,12 +67955,19 @@ static int sp_256_point_to_ecc_point_8(const sp_point_256* p, ecc_point* pm) * m Modulus (prime). * mp Montgomery multiplier. */ -static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, - const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x44\n\t" @@ -68567,13 +70065,26 @@ static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, co "ldr %[r], [sp, #64]\n\t" "stm %[r], {r1, r2, r3, r4, r5, r6, r7, r8}\n\t" "add sp, sp, #0x44\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r12" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)mp_p; +#else + (void)mp; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #elif defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) @@ -68586,12 +70097,19 @@ static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, co * m Modulus (prime). * mp Montgomery multiplier. */ -static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, - const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x44\n\t" @@ -69046,13 +70564,26 @@ static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, co "ldr %[r], [sp, #64]\n\t" "stm %[r], {r1, r2, r3, r4, r5, r6, r7, r8}\n\t" "add sp, sp, #0x44\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)mp_p; +#else + (void)mp; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #else @@ -69065,12 +70596,19 @@ static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, co * m Modulus (prime). * mp Montgomery multiplier. */ -static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, - const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x4c\n\t" @@ -69303,13 +70841,26 @@ static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, co "ldr %[r], [sp, #68]\n\t" "stm %[r], {r1, r2, r3, r4, r5, r6, r7, r8}\n\t" "add sp, sp, #0x4c\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r10", "r11", "r12", "r7", "r8", "r9", "lr" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)mp_p; +#else + (void)mp; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #endif @@ -69321,11 +70872,18 @@ static SP_NOINLINE void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, co * m Modulus (prime). * mp Montgomery multiplier. */ -static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p, - sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x44\n\t" @@ -70503,13 +72061,26 @@ static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, co "ldr %[r], [sp, #64]\n\t" "stm %[r], {r1, r2, r3, r4, r5, r6, r7, r8}\n\t" "add sp, sp, #0x44\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r12", "r8", "r9", "r10", "lr" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)mp_p; +#else + (void)mp; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #elif defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) @@ -70520,11 +72091,18 @@ static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, co * m Modulus (prime). * mp Montgomery multiplier. */ -static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p, - sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x44\n\t" @@ -70871,13 +72449,26 @@ static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, co "ldr %[r], [sp, #64]\n\t" "stm %[r], {r1, r2, r3, r4, r5, r6, r7, r8}\n\t" "add sp, sp, #0x44\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)mp_p; +#else + (void)mp; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #else @@ -70888,11 +72479,18 @@ static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, co * m Modulus (prime). * mp Montgomery multiplier. */ -static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p, - sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x44\n\t" @@ -71113,13 +72711,26 @@ static SP_NOINLINE void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, co "ldr %[r], [sp, #64]\n\t" "stm %[r], {r1, r2, r3, r4, r5, r6, r7, r8}\n\t" "add sp, sp, #0x44\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)mp_p; +#else + (void)mp; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #endif @@ -71226,10 +72837,16 @@ static void sp_256_mont_inv_8(sp_digit* r, const sp_digit* a, sp_digit* td) * return -ve, 0 or +ve if a is less than, equal to or greater than b * respectively. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_int32 sp_256_cmp_8(const sp_digit* a_p, const sp_digit* b_p) +#else +static sp_int32 sp_256_cmp_8(const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r2, #-1\n\t" @@ -71346,8 +72963,13 @@ static sp_int32 sp_256_cmp_8(const sp_digit* a_p, const sp_digit* b_p) "eor r2, r2, r3\n\t" #endif /*WOLFSSL_SP_SMALL */ "mov %[a], r2\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)a; @@ -71368,13 +72990,20 @@ static sp_int32 sp_256_cmp_8(const sp_digit* a_p, const sp_digit* b_p) * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_256_cond_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r6, #0\n\t" @@ -71393,8 +73022,13 @@ static sp_digit sp_256_cond_sub_8(sp_digit* r_p, const sp_digit* a_p, "cmp lr, #32\n\t" "blt L_sp_256_cond_sub_8_words_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -71409,13 +73043,20 @@ static sp_digit sp_256_cond_sub_8(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_256_cond_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -71448,8 +73089,13 @@ static sp_digit sp_256_cond_sub_8(sp_digit* r_p, const sp_digit* a_p, "sbcs r5, r5, r7\n\t" "stm %[r]!, {r4, r5}\n\t" "sbc %[r], lr, lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7" ); return (word32)(size_t)r; @@ -71466,11 +73112,19 @@ static sp_digit sp_256_cond_sub_8(sp_digit* r_p, const sp_digit* a_p, * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, + sp_digit mp_p) +#else +static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( #if !(defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 4)) @@ -71736,8 +73390,13 @@ static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -71751,11 +73410,19 @@ static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, + sp_digit mp_p) +#else +static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldr r11, [%[m]]\n\t" @@ -71840,8 +73507,13 @@ static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -71855,11 +73527,19 @@ static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, + sp_digit mp_p) +#else +static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* i = 0 */ @@ -71926,8 +73606,13 @@ static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, "str r7, [%[a], #12]\n\t" "str r8, [%[a], #16]\n\t" "mov %[mp], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -71942,9 +73627,17 @@ static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, + sp_digit mp_p) +#else +static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x44\n\t" @@ -72078,13 +73771,26 @@ static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, "ldr %[a], [sp, #64]\n\t" "stm %[a], {r1, r2, r3, r4, r5, r6, r7, r8}\n\t" "add sp, sp, #0x44\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a) : +#else + : + : [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)mp_p; +#else + (void)mp; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 4) @@ -72094,12 +73800,19 @@ static SP_NOINLINE void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a_p, const sp_digit* m_p, - sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a, + const sp_digit* m, sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( #if !(defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 4)) @@ -72365,8 +74078,13 @@ static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a_p, const sp_digit "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -72380,12 +74098,19 @@ static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a_p, const sp_digit * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a_p, const sp_digit* m_p, - sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a, + const sp_digit* m, sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldr r11, [%[m]]\n\t" @@ -72470,8 +74195,13 @@ static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a_p, const sp_digit "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -72485,12 +74215,19 @@ static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a_p, const sp_digit * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a_p, const sp_digit* m_p, - sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a, + const sp_digit* m, sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* i = 0 */ @@ -72557,8 +74294,13 @@ static SP_NOINLINE void sp_256_mont_reduce_order_8(sp_digit* a_p, const sp_digit "str r7, [%[a], #12]\n\t" "str r8, [%[a], #16]\n\t" "mov %[mp], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -72614,12 +74356,19 @@ static void sp_256_map_8(sp_point_256* r, const sp_point_256* p, * b Second number to add in Montgomery form. * m Modulus (prime). */ -static void sp_256_mont_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, - const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_256_mont_add_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) +#else +static void sp_256_mont_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -72657,12 +74406,21 @@ static void sp_256_mont_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit "sbcs r11, r11, lr, lsr #31\n\t" "sbc r12, r12, lr\n\t" "stm %[r], {r5, r6, r7, r8, r9, r10, r11, r12}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } /* Double a Montgomery form number (r = a + a % m). @@ -72671,10 +74429,17 @@ static void sp_256_mont_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit * a Number to double in Montgomery form. * m Modulus (prime). */ -static void sp_256_mont_dbl_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_256_mont_dbl_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) +#else +static void sp_256_mont_dbl_8(sp_digit* r, const sp_digit* a, const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r2, #0\n\t" @@ -72708,12 +74473,21 @@ static void sp_256_mont_dbl_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit "sbcs r10, r10, r2, lsr #31\n\t" "sbc r11, r11, r2\n\t" "stm %[r], {r4, r5, r6, r7, r8, r9, r10, r11}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r2" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } /* Triple a Montgomery form number (r = a + a + a % m). @@ -72722,10 +74496,17 @@ static void sp_256_mont_dbl_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit * a Number to triple in Montgomery form. * m Modulus (prime). */ -static void sp_256_mont_tpl_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_256_mont_tpl_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) +#else +static void sp_256_mont_tpl_8(sp_digit* r, const sp_digit* a, const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -72791,12 +74572,21 @@ static void sp_256_mont_tpl_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit "sbcs r10, r10, r12, lsr #31\n\t" "sbc r11, r11, r12\n\t" "stm %[r], {r4, r5, r6, r7, r8, r9, r10, r11}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r2", "r3", "r12" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } /* Subtract two Montgomery form numbers (r = a - b % m). @@ -72806,12 +74596,19 @@ static void sp_256_mont_tpl_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit * b Number to subtract with in Montgomery form. * m Modulus (prime). */ -static void sp_256_mont_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, - const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_256_mont_sub_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) +#else +static void sp_256_mont_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -72847,12 +74644,21 @@ static void sp_256_mont_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit "adcs r11, r11, lr, lsr #31\n\t" "adc r12, r12, lr\n\t" "stm %[r], {r5, r6, r7, r8, r9, r10, r11, r12}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } /* Divide the number by 2 mod the modulus (prime). (r = a / 2 % m) @@ -72861,11 +74667,19 @@ static void sp_256_mont_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit * a Number to divide. * m Modulus (prime). */ -static void sp_256_mont_div2_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_256_mont_div2_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) +#else +static void sp_256_mont_div2_8(sp_digit* r, const sp_digit* a, + const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* m asm ("r2") = (const sp_digit*)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r4, r5, r6, r7}\n\t" @@ -72925,8 +74739,13 @@ static void sp_256_mont_div2_8(sp_digit* r_p, const sp_digit* a_p, const sp_digi "orr r10, r10, r7, lsl #31\n\t" "orr r11, r11, r3, lsl #31\n\t" "stm %[r], {r8, r9, r10, r11}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3" ); @@ -76434,9 +78253,15 @@ int sp_ecc_mulmod_base_add_256(const mp_int* km, const ecc_point* am, * * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_256_add_one_8(sp_digit* a_p) +#else +static void sp_256_add_one_8(sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r1, r2, r3, r4}\n\t" @@ -76451,8 +78276,13 @@ static void sp_256_add_one_8(sp_digit* a_p) "adcs r3, r3, #0\n\t" "adcs r4, r4, #0\n\t" "stm %[a]!, {r1, r2, r3, r4}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a) : +#else + : + : [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r1", "r2", "r3", "r4" ); } @@ -76491,9 +78321,9 @@ static void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -76842,10 +78672,16 @@ int sp_ecc_secret_gen_256_nb(sp_ecc_ctx_t* sp_ctx, const mp_int* priv, * a A single precision integer. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_256_sub_in_place_8(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_256_sub_in_place_8(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -76864,8 +78700,13 @@ static sp_digit sp_256_sub_in_place_8(sp_digit* a_p, const sp_digit* b_p) "cmp %[a], lr\n\t" "bne L_sp_256_sub_in_pkace_8_word_%=\n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12", "lr" ); @@ -76878,10 +78719,16 @@ static sp_digit sp_256_sub_in_place_8(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer and result. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_256_sub_in_place_8(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_256_sub_in_place_8(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3, r4, r5}\n\t" @@ -76899,8 +78746,13 @@ static sp_digit sp_256_sub_in_place_8(sp_digit* a_p, const sp_digit* b_p) "sbcs r5, r5, r9\n\t" "stm %[a]!, {r2, r3, r4, r5}\n\t" "sbc %[a], r9, r9\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; @@ -76914,11 +78766,17 @@ static sp_digit sp_256_sub_in_place_8(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_256_mul_d_8(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_256_mul_d_8(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -76999,8 +78857,13 @@ static void sp_256_mul_d_8(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) "cmp r9, #32\n\t" "blt L_sp_256_mul_d_8_word_%=\n\t" "str r3, [%[r], #32]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -77012,11 +78875,17 @@ static void sp_256_mul_d_8(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_256_mul_d_8(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_256_mul_d_8(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -77272,8 +79141,13 @@ static void sp_256_mul_d_8(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) #endif "stm %[r]!, {r4}\n\t" "str r5, [%[r]]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -77289,11 +79163,17 @@ static void sp_256_mul_d_8(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_256_word_8(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_256_word_8(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr r6, %[div], #16\n\t" @@ -77331,8 +79211,13 @@ static sp_digit div_256_word_8(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "sub %[d0], %[d0], r3\n\t" "udiv r3, %[d0], %[div]\n\t" "add %[d1], r4, r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -77348,11 +79233,17 @@ static sp_digit div_256_word_8(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_256_word_8(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_256_word_8(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr lr, %[div], #1\n\t" @@ -77469,8 +79360,13 @@ static sp_digit div_256_word_8(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "subs r6, %[div], r7\n\t" "sbc r6, r6, r6\n\t" "sub %[d1], r3, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -78130,11 +80026,18 @@ int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_256_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_256_sub_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -78153,8 +80056,13 @@ static sp_digit sp_256_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* "cmp %[a], lr\n\t" "bne L_sp_256_sub_8_word_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "lr" ); @@ -78168,11 +80076,18 @@ static sp_digit sp_256_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_256_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_256_sub_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -78190,18 +80105,29 @@ static sp_digit sp_256_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* "sbcs r6, r6, r10\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } #endif /* WOLFSSL_SP_SMALL */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_256_rshift1_8(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_256_rshift1_8(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -78239,8 +80165,7 @@ static void sp_256_rshift1_8(sp_digit* r_p, const sp_digit* a_p) "strd r8, r9, [%[r], #24]\n\t" #endif #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "ldr r2, [%[a]]\n\t" - "ldr r3, [%[a], #4]\n\t" + "ldm r1, {r2, r3}\n\t" #else "ldrd r2, r3, [%[a]]\n\t" #endif @@ -78259,8 +80184,7 @@ static void sp_256_rshift1_8(sp_digit* r_p, const sp_digit* a_p) "orr r8, r8, r5, lsl #31\n\t" "orr r9, r9, r12, lsl #31\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "str r6, [%[r]]\n\t" - "str r7, [%[r], #4]\n\t" + "stm r0, {r6, r7}\n\t" #else "strd r6, r7, [%[r]]\n\t" #endif @@ -78270,8 +80194,13 @@ static void sp_256_rshift1_8(sp_digit* r_p, const sp_digit* a_p) #else "strd r8, r9, [%[r], #8]\n\t" #endif +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12", "lr", "r10" ); @@ -78283,11 +80212,18 @@ static void sp_256_rshift1_8(sp_digit* r_p, const sp_digit* a_p) * a Number to divide. * m Modulus. */ -static void sp_256_div2_mod_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_256_div2_mod_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) +#else +static void sp_256_div2_mod_8(sp_digit* r, const sp_digit* a, const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* m asm ("r2") = (const sp_digit*)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -78357,8 +80293,13 @@ static void sp_256_div2_mod_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit "orr r10, r10, r7, lsl #31\n\t" "orr r11, r11, r3, lsl #31\n\t" "stm %[r], {r8, r9, r10, r11}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); @@ -78400,11 +80341,21 @@ static const byte L_sp_256_num_bits_8_table[] = { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, }; +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static int sp_256_num_bits_8(const sp_digit* a_p) +#else +static int sp_256_num_bits_8(const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; register byte* L_sp_256_num_bits_8_table_c asm ("r1") = (byte*)&L_sp_256_num_bits_8_table; +#else + register byte* L_sp_256_num_bits_8_table_c = + (byte*)&L_sp_256_num_bits_8_table; + +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, %[L_sp_256_num_bits_8_table]\n\t" @@ -78716,30 +80667,36 @@ static int sp_256_num_bits_8(const sp_digit* a_p) "\n" "L_sp_256_num_bits_8_9_%=: \n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [L_sp_256_num_bits_8_table] "+r" (L_sp_256_num_bits_8_table_c) : +#else + : + : [a] "r" (a), + [L_sp_256_num_bits_8_table] "r" (L_sp_256_num_bits_8_table_c) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r12", "lr" ); return (word32)(size_t)a; } #else +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static int sp_256_num_bits_8(const sp_digit* a_p) +#else +static int sp_256_num_bits_8(const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldr r1, [%[a], #28]\n\t" "cmp r1, #0\n\t" "beq L_sp_256_num_bits_8_7_%=\n\t" -#if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x0\n\t" -#else "mov r2, #0x100\n\t" -#endif "clz r12, r1\n\t" "sub r12, r2, r12\n\t" "b L_sp_256_num_bits_8_9_%=\n\t" @@ -78806,8 +80763,13 @@ static int sp_256_num_bits_8(const sp_digit* a_p) "\n" "L_sp_256_num_bits_8_9_%=: \n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a) : +#else + : + : [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r1", "r2", "r3", "r12", "lr" ); return (word32)(size_t)a; @@ -79892,11 +81854,18 @@ static const sp_digit p384_b[12] = { * a A single precision integer. * b A single precision integer. */ -static void sp_384_mul_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_384_mul_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x60\n\t" @@ -80079,8 +82048,13 @@ static void sp_384_mul_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_384_mul_12_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -80093,11 +82067,18 @@ static void sp_384_mul_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ * a A single precision integer. * b A single precision integer. */ -static void sp_384_mul_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_384_mul_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #48\n\t" @@ -85577,8 +87558,13 @@ static void sp_384_mul_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ "stm %[r]!, {r3, r4, r5, r6}\n\t" "ldm sp!, {r3, r4, r5, r6}\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", "r12" ); @@ -85591,10 +87577,16 @@ static void sp_384_mul_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_384_sqr_12(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x60\n\t" @@ -85737,8 +87729,13 @@ static void sp_384_sqr_12(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_384_sqr_12_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -85750,10 +87747,16 @@ static void sp_384_sqr_12(sp_digit* r_p, const sp_digit* a_p) * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_384_sqr_12(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #48\n\t" @@ -88801,8 +90804,13 @@ static void sp_384_sqr_12(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r2, r3, r4, r8}\n\t" "ldm sp!, {r2, r3, r4, r8}\n\t" "stm %[r]!, {r2, r3, r4, r8}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12" ); @@ -88816,11 +90824,18 @@ static void sp_384_sqr_12(sp_digit* r_p, const sp_digit* a_p) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_384_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_384_add_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r3, #0\n\t" @@ -88840,8 +90855,13 @@ static sp_digit sp_384_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit "cmp %[a], r12\n\t" "bne L_sp_384_add_12_word_%=\n\t" "mov %[r], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); @@ -88855,11 +90875,18 @@ static sp_digit sp_384_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_384_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_384_add_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -88885,8 +90912,13 @@ static sp_digit sp_384_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit "stm %[r]!, {r3, r4, r5, r6}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -89198,13 +91230,20 @@ static int sp_384_point_to_ecc_point_12(const sp_point_384* p, ecc_point* pm) * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_384_cond_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_384_cond_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r6, #0\n\t" @@ -89223,8 +91262,13 @@ static sp_digit sp_384_cond_sub_12(sp_digit* r_p, const sp_digit* a_p, "cmp lr, #48\n\t" "blt L_sp_384_cond_sub_12_words_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -89239,13 +91283,20 @@ static sp_digit sp_384_cond_sub_12(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_384_cond_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_384_cond_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -89292,8 +91343,13 @@ static sp_digit sp_384_cond_sub_12(sp_digit* r_p, const sp_digit* a_p, "sbcs r5, r5, r7\n\t" "stm %[r]!, {r4, r5}\n\t" "sbc %[r], lr, lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7" ); return (word32)(size_t)r; @@ -89309,11 +91365,19 @@ static sp_digit sp_384_cond_sub_12(sp_digit* r_p, const sp_digit* a_p, * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( #if !(defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 4)) @@ -89695,8 +91759,13 @@ static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a_p, const sp_digit* m_p "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -89710,11 +91779,19 @@ static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a_p, const sp_digit* m_p * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldr r11, [%[m]]\n\t" @@ -89831,8 +91908,13 @@ static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a_p, const sp_digit* m_p "str r12, [%[a]]\n\t" "str lr, [%[a], #4]\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -89846,11 +91928,19 @@ static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a_p, const sp_digit* m_p * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* i = 0 */ @@ -89937,8 +92027,13 @@ static SP_NOINLINE void sp_384_mont_reduce_12(sp_digit* a_p, const sp_digit* m_p "str r7, [%[a], #12]\n\t" "str r8, [%[a], #16]\n\t" "mov %[mp], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -90095,10 +92190,16 @@ static void sp_384_mont_inv_12(sp_digit* r, const sp_digit* a, sp_digit* td) * return -ve, 0 or +ve if a is less than, equal to or greater than b * respectively. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_int32 sp_384_cmp_12(const sp_digit* a_p, const sp_digit* b_p) +#else +static sp_int32 sp_384_cmp_12(const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r2, #-1\n\t" @@ -90259,8 +92360,13 @@ static sp_int32 sp_384_cmp_12(const sp_digit* a_p, const sp_digit* b_p) "eor r2, r2, r3\n\t" #endif /*WOLFSSL_SP_SMALL */ "mov %[a], r2\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)a; @@ -90319,13 +92425,20 @@ static void sp_384_map_12(sp_point_384* r, const sp_point_384* p, * b Second number to add in Montgomery form. * m Modulus (prime). */ -static void sp_384_mont_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, - const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_384_mont_add_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) +#else +static void sp_384_mont_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register const sp_digit* m asm ("r3") = (const sp_digit*)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ sp_digit o; @@ -90339,11 +92452,19 @@ static void sp_384_mont_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a Number to double in Montgomery form. * m Modulus (prime). */ -static void sp_384_mont_dbl_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_384_mont_dbl_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) +#else +static void sp_384_mont_dbl_12(sp_digit* r, const sp_digit* a, + const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* m asm ("r2") = (const sp_digit*)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ sp_digit o; @@ -90357,11 +92478,19 @@ static void sp_384_mont_dbl_12(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a Number to triple in Montgomery form. * m Modulus (prime). */ -static void sp_384_mont_tpl_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_384_mont_tpl_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) +#else +static void sp_384_mont_tpl_12(sp_digit* r, const sp_digit* a, + const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* m asm ("r2") = (const sp_digit*)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ sp_digit o; @@ -90378,11 +92507,18 @@ static void sp_384_mont_tpl_12(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_384_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_384_sub_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -90401,8 +92537,13 @@ static sp_digit sp_384_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit "cmp %[a], lr\n\t" "bne L_sp_384_sub_12_word_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "lr" ); @@ -90416,11 +92557,18 @@ static sp_digit sp_384_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_384_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_384_sub_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -90445,8 +92593,13 @@ static sp_digit sp_384_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit "sbcs r6, r6, r10\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -90462,13 +92615,20 @@ static sp_digit sp_384_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit * b A single precision number to add. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_384_cond_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -90487,8 +92647,13 @@ static sp_digit sp_384_cond_add_12(sp_digit* r_p, const sp_digit* a_p, "cmp r12, #48\n\t" "blt L_sp_384_cond_add_12_words_%=\n\t" "mov %[r], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -90503,13 +92668,20 @@ static sp_digit sp_384_cond_add_12(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to add. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_384_cond_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r8, #0\n\t" @@ -90556,8 +92728,13 @@ static sp_digit sp_384_cond_add_12(sp_digit* r_p, const sp_digit* a_p, "adcs r5, r5, r7\n\t" "stm %[r]!, {r4, r5}\n\t" "adc %[r], r8, r8\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; @@ -90571,13 +92748,20 @@ static sp_digit sp_384_cond_add_12(sp_digit* r_p, const sp_digit* a_p, * b Number to subtract with in Montgomery form. * m Modulus (prime). */ -static void sp_384_mont_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, - const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_384_mont_sub_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) +#else +static void sp_384_mont_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register const sp_digit* m asm ("r3") = (const sp_digit*)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ sp_digit o; @@ -90588,10 +92772,16 @@ static void sp_384_mont_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digi #ifdef WOLFSSL_SP_SMALL #else #endif /* WOLFSSL_SP_SMALL */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_384_rshift1_12(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_384_rshift1_12(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3}\n\t" @@ -90640,8 +92830,13 @@ static void sp_384_rshift1_12(sp_digit* r_p, const sp_digit* a_p) "lsr r4, r4, #1\n\t" "str r3, [%[r], #40]\n\t" "str r4, [%[r], #44]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4" ); } @@ -94221,9 +96416,15 @@ int sp_ecc_mulmod_base_add_384(const mp_int* km, const ecc_point* am, * * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_384_add_one_12(sp_digit* a_p) +#else +static void sp_384_add_one_12(sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r1, r2, r3, r4}\n\t" @@ -94244,8 +96445,13 @@ static void sp_384_add_one_12(sp_digit* a_p) "adcs r3, r3, #0\n\t" "adcs r4, r4, #0\n\t" "stm %[a]!, {r1, r2, r3, r4}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a) : +#else + : + : [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r1", "r2", "r3", "r4" ); } @@ -94284,9 +96490,9 @@ static void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -94635,10 +96841,16 @@ int sp_ecc_secret_gen_384_nb(sp_ecc_ctx_t* sp_ctx, const mp_int* priv, * a A single precision integer. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_384_sub_in_place_12(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_384_sub_in_place_12(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -94657,8 +96869,13 @@ static sp_digit sp_384_sub_in_place_12(sp_digit* a_p, const sp_digit* b_p) "cmp %[a], lr\n\t" "bne L_sp_384_sub_in_pkace_12_word_%=\n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12", "lr" ); @@ -94671,10 +96888,16 @@ static sp_digit sp_384_sub_in_place_12(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer and result. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_384_sub_in_place_12(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_384_sub_in_place_12(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3, r4, r5}\n\t" @@ -94699,8 +96922,13 @@ static sp_digit sp_384_sub_in_place_12(sp_digit* a_p, const sp_digit* b_p) "sbcs r5, r5, r9\n\t" "stm %[a]!, {r2, r3, r4, r5}\n\t" "sbc %[a], r9, r9\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; @@ -94714,11 +96942,17 @@ static sp_digit sp_384_sub_in_place_12(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_384_mul_d_12(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_384_mul_d_12(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -94799,8 +97033,13 @@ static void sp_384_mul_d_12(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) "cmp r9, #48\n\t" "blt L_sp_384_mul_d_12_word_%=\n\t" "str r3, [%[r], #48]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -94812,11 +97051,17 @@ static void sp_384_mul_d_12(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_384_mul_d_12(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_384_mul_d_12(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -95200,8 +97445,13 @@ static void sp_384_mul_d_12(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) #endif "stm %[r]!, {r5}\n\t" "str r3, [%[r]]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -95217,11 +97467,17 @@ static void sp_384_mul_d_12(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_384_word_12(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_384_word_12(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr r6, %[div], #16\n\t" @@ -95259,8 +97515,13 @@ static sp_digit div_384_word_12(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "sub %[d0], %[d0], r3\n\t" "udiv r3, %[d0], %[div]\n\t" "add %[d1], r4, r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -95276,11 +97537,17 @@ static sp_digit div_384_word_12(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_384_word_12(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_384_word_12(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr lr, %[div], #1\n\t" @@ -95397,8 +97664,13 @@ static sp_digit div_384_word_12(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "subs r6, %[div], r7\n\t" "sbc r6, r6, r6\n\t" "sub %[d1], r3, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -96028,11 +98300,19 @@ int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W * a Number to divide. * m Modulus. */ -static void sp_384_div2_mod_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_384_div2_mod_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) +#else +static void sp_384_div2_mod_12(sp_digit* r, const sp_digit* a, + const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* m asm ("r2") = (const sp_digit*)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r4}\n\t" @@ -96074,8 +98354,7 @@ static void sp_384_div2_mod_12(sp_digit* r_p, const sp_digit* a_p, const sp_digi "L_sp_384_div2_mod_12_div2_%=: \n\t" "sub %[r], %[r], #48\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "ldr r8, [%[r]]\n\t" - "ldr r9, [%[r], #4]\n\t" + "ldm r0, {r8, r9}\n\t" #else "ldrd r8, r9, [%[r]]\n\t" #endif @@ -96125,8 +98404,13 @@ static void sp_384_div2_mod_12(sp_digit* r_p, const sp_digit* a_p, const sp_digi "orr r10, r10, r3, lsl #31\n\t" "str r9, [%[r], #40]\n\t" "str r10, [%[r], #44]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); @@ -96168,11 +98452,21 @@ static const byte L_sp_384_num_bits_12_table[] = { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, }; +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static int sp_384_num_bits_12(const sp_digit* a_p) +#else +static int sp_384_num_bits_12(const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; register byte* L_sp_384_num_bits_12_table_c asm ("r1") = (byte*)&L_sp_384_num_bits_12_table; +#else + register byte* L_sp_384_num_bits_12_table_c = + (byte*)&L_sp_384_num_bits_12_table; + +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, %[L_sp_384_num_bits_12_table]\n\t" @@ -96183,9 +98477,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_384_num_bits_12_11_3_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x78\n\t" + "mov r2, #0x78\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x178\n\t" #endif @@ -96199,9 +98492,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_384_num_bits_12_11_2_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x70\n\t" + "mov r2, #0x70\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x170\n\t" #endif @@ -96215,9 +98507,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_384_num_bits_12_11_1_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x68\n\t" + "mov r2, #0x68\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x168\n\t" #endif @@ -96228,9 +98519,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "L_sp_384_num_bits_12_11_1_%=: \n\t" "and r3, r1, #0xff\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x60\n\t" + "mov r2, #0x60\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x160\n\t" #endif @@ -96246,9 +98536,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_384_num_bits_12_10_3_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x58\n\t" + "mov r2, #0x58\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x158\n\t" #endif @@ -96262,9 +98551,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_384_num_bits_12_10_2_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x50\n\t" + "mov r2, #0x50\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x150\n\t" #endif @@ -96278,9 +98566,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_384_num_bits_12_10_1_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x48\n\t" + "mov r2, #0x48\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x148\n\t" #endif @@ -96291,9 +98578,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "L_sp_384_num_bits_12_10_1_%=: \n\t" "and r3, r1, #0xff\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x40\n\t" + "mov r2, #0x40\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x140\n\t" #endif @@ -96309,9 +98595,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_384_num_bits_12_9_3_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x38\n\t" + "mov r2, #0x38\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x138\n\t" #endif @@ -96325,9 +98610,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_384_num_bits_12_9_2_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x30\n\t" + "mov r2, #0x30\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x130\n\t" #endif @@ -96341,9 +98625,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_384_num_bits_12_9_1_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x28\n\t" + "mov r2, #0x28\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x128\n\t" #endif @@ -96354,9 +98637,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "L_sp_384_num_bits_12_9_1_%=: \n\t" "and r3, r1, #0xff\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x20\n\t" + "mov r2, #0x20\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x120\n\t" #endif @@ -96372,9 +98654,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_384_num_bits_12_8_3_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x18\n\t" + "mov r2, #0x18\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x118\n\t" #endif @@ -96388,9 +98669,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_384_num_bits_12_8_2_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x10\n\t" + "mov r2, #0x10\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x110\n\t" #endif @@ -96404,9 +98684,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_384_num_bits_12_8_1_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x8\n\t" + "mov r2, #0x8\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x108\n\t" #endif @@ -96416,13 +98695,7 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "\n" "L_sp_384_num_bits_12_8_1_%=: \n\t" "and r3, r1, #0xff\n\t" -#if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x0\n\t" -#else "mov r2, #0x100\n\t" -#endif "ldrb r12, [lr, r3]\n\t" "add r12, r2, r12\n\t" "b L_sp_384_num_bits_12_13_%=\n\t" @@ -96736,27 +99009,38 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "\n" "L_sp_384_num_bits_12_13_%=: \n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [L_sp_384_num_bits_12_table] "+r" (L_sp_384_num_bits_12_table_c) : +#else + : + : [a] "r" (a), + [L_sp_384_num_bits_12_table] "r" (L_sp_384_num_bits_12_table_c) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r12", "lr" ); return (word32)(size_t)a; } #else +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static int sp_384_num_bits_12(const sp_digit* a_p) +#else +static int sp_384_num_bits_12(const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldr r1, [%[a], #44]\n\t" "cmp r1, #0\n\t" "beq L_sp_384_num_bits_12_11_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x80\n\t" + "mov r2, #0x80\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x180\n\t" #endif @@ -96769,9 +99053,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r1, #0\n\t" "beq L_sp_384_num_bits_12_10_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x60\n\t" + "mov r2, #0x60\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x160\n\t" #endif @@ -96784,9 +99067,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r1, #0\n\t" "beq L_sp_384_num_bits_12_9_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x40\n\t" + "mov r2, #0x40\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x140\n\t" #endif @@ -96799,9 +99081,8 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "cmp r1, #0\n\t" "beq L_sp_384_num_bits_12_8_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x20\n\t" + "mov r2, #0x20\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x120\n\t" #endif @@ -96813,13 +99094,7 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "ldr r1, [%[a], #28]\n\t" "cmp r1, #0\n\t" "beq L_sp_384_num_bits_12_7_%=\n\t" -#if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x0\n\t" -#else "mov r2, #0x100\n\t" -#endif "clz r12, r1\n\t" "sub r12, r2, r12\n\t" "b L_sp_384_num_bits_12_13_%=\n\t" @@ -96886,8 +99161,13 @@ static int sp_384_num_bits_12(const sp_digit* a_p) "\n" "L_sp_384_num_bits_12_13_%=: \n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a) : +#else + : + : [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r1", "r2", "r3", "r12", "lr" ); return (word32)(size_t)a; @@ -98018,11 +100298,18 @@ static const sp_digit p521_b[17] = { * a A single precision integer. * b A single precision integer. */ -static void sp_521_mul_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_521_mul_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_521_mul_17(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x88\n\t" @@ -98208,8 +100495,13 @@ static void sp_521_mul_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_521_mul_17_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -98222,11 +100514,18 @@ static void sp_521_mul_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ * a A single precision integer. * b A single precision integer. */ -static void sp_521_mul_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_521_mul_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_521_mul_17(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x44\n\t" @@ -109225,8 +111524,13 @@ static void sp_521_mul_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ "stm %[r]!, {r3, r4, r5, r6}\n\t" "ldm sp!, {r3}\n\t" "stm %[r]!, {r3}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", "r12" ); @@ -109239,10 +111543,16 @@ static void sp_521_mul_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_ * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_521_sqr_17(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_521_sqr_17(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x88\n\t" @@ -109388,8 +111698,13 @@ static void sp_521_sqr_17(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_521_sqr_17_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -109401,10 +111716,16 @@ static void sp_521_sqr_17(sp_digit* r_p, const sp_digit* a_p) * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_521_sqr_17(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_521_sqr_17(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x44\n\t" @@ -115261,8 +117582,13 @@ static void sp_521_sqr_17(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r2, r3, r4, r8}\n\t" "ldm sp!, {r2}\n\t" "stm %[r]!, {r2}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12" ); @@ -115276,11 +117602,18 @@ static void sp_521_sqr_17(sp_digit* r_p, const sp_digit* a_p) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_521_add_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_521_add_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_521_add_17(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r3, #0\n\t" @@ -115306,8 +117639,13 @@ static sp_digit sp_521_add_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit "stm %[r]!, {r4}\n\t" "mov r4, #0\n\t" "adc %[r], r4, #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); @@ -115321,11 +117659,18 @@ static sp_digit sp_521_add_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_521_add_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_521_add_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_521_add_17(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -115362,8 +117707,13 @@ static sp_digit sp_521_add_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit "stm %[r]!, {r3}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -115592,13 +117942,20 @@ static int sp_521_point_to_ecc_point_17(const sp_point_521* p, ecc_point* pm) * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_521_cond_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_521_cond_sub_17(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r6, #0\n\t" @@ -115617,8 +117974,13 @@ static sp_digit sp_521_cond_sub_17(sp_digit* r_p, const sp_digit* a_p, "cmp lr, #0x44\n\t" "blt L_sp_521_cond_sub_17_words_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -115633,13 +117995,20 @@ static sp_digit sp_521_cond_sub_17(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_521_cond_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_521_cond_sub_17(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -115705,8 +118074,13 @@ static sp_digit sp_521_cond_sub_17(sp_digit* r_p, const sp_digit* a_p, "sbcs r4, r4, r6\n\t" "str r4, [%[r]]\n\t" "sbc %[r], lr, lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7" ); return (word32)(size_t)r; @@ -115719,9 +118093,17 @@ static sp_digit sp_521_cond_sub_17(sp_digit* r_p, const sp_digit* a_p, * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_521_mont_reduce_17(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_521_mont_reduce_17(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_521_mont_reduce_17(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x44\n\t" @@ -115793,9 +118175,8 @@ static SP_NOINLINE void sp_521_mont_reduce_17(sp_digit* a_p, const sp_digit* m_p "ldm %[a], {r1, r2, r3, r4, r5}\n\t" "ldm sp!, {r7, r8, r9, r10, r11}\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov lr, #0x1\n\t" - "lsl lr, lr, #8\n\t" - "add lr, lr, #0xff\n\t" + "mov lr, #0xff\n\t" + "orr lr, lr, #0x100\n\t" #else "mov lr, #0x1ff\n\t" #endif @@ -115833,13 +118214,26 @@ static SP_NOINLINE void sp_521_mont_reduce_17(sp_digit* a_p, const sp_digit* m_p "adcs r7, r7, #0\n\t" "adcs r8, r8, #0\n\t" "stm %[a]!, {r1, r2, r3, r4, r5, r6, r7, r8}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a) : +#else + : + : [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)mp_p; +#else + (void)mp; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 4) @@ -115849,12 +118243,19 @@ static SP_NOINLINE void sp_521_mont_reduce_17(sp_digit* a_p, const sp_digit* m_p * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, const sp_digit* m_p, - sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a, + const sp_digit* m, sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( #if !(defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 4)) @@ -115872,9 +118273,8 @@ static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, const sp_digi "cmp r9, #0x40\n\t" "bne L_sp_521_mont_reduce_order_17_nomask_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r7, #0x1\n\t" - "lsl r7, r7, #8\n\t" - "add r7, r7, #0xff\n\t" + "mov r7, #0xff\n\t" + "orr r7, r7, #0x100\n\t" #else "mov r7, #0x1ff\n\t" #endif @@ -116464,8 +118864,13 @@ static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, const sp_digi "lsr r3, r4, #9\n\t" "add %[a], %[a], #4\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -116479,12 +118884,19 @@ static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, const sp_digi * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, const sp_digit* m_p, - sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a, + const sp_digit* m, sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldr r11, [%[m]]\n\t" @@ -116500,9 +118912,8 @@ static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, const sp_digi "cmp r9, #0x40\n\t" "bne L_sp_521_mont_reduce_order_17_nomask_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r7, #0x1\n\t" - "lsl r7, r7, #8\n\t" - "add r7, r7, #0xff\n\t" + "mov r7, #0xff\n\t" + "orr r7, r7, #0x100\n\t" #else "mov r7, #0x1ff\n\t" #endif @@ -116724,8 +119135,13 @@ static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, const sp_digi "lsr r3, r4, #9\n\t" "add %[a], %[a], #4\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -116739,12 +119155,19 @@ static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, const sp_digi * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, const sp_digit* m_p, - sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a, + const sp_digit* m, sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* i = 0 */ @@ -116762,9 +119185,8 @@ static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, const sp_digi "cmp r12, #0x40\n\t" "bne L_sp_521_mont_reduce_order_17_nomask_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r10, #0x1\n\t" - "lsl r10, r10, #8\n\t" - "add r10, r10, #0xff\n\t" + "mov r10, #0xff\n\t" + "orr r10, r10, #0x100\n\t" #else "mov r10, #0x1ff\n\t" #endif @@ -116939,8 +119361,13 @@ static SP_NOINLINE void sp_521_mont_reduce_order_17(sp_digit* a_p, const sp_digi "lsr lr, r10, #9\n\t" "add %[a], %[a], #4\n\t" "mov %[mp], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -117094,10 +119521,16 @@ static void sp_521_mont_inv_17(sp_digit* r, const sp_digit* a, sp_digit* td) * return -ve, 0 or +ve if a is less than, equal to or greater than b * respectively. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_int32 sp_521_cmp_17(const sp_digit* a_p, const sp_digit* b_p) +#else +static sp_int32 sp_521_cmp_17(const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r2, #-1\n\t" @@ -117313,8 +119746,13 @@ static sp_int32 sp_521_cmp_17(const sp_digit* a_p, const sp_digit* b_p) "eor r2, r2, r3\n\t" #endif /*WOLFSSL_SP_SMALL */ "mov %[a], r2\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)a; @@ -117373,12 +119811,19 @@ static void sp_521_map_17(sp_point_521* r, const sp_point_521* p, * b Second number to add in Montgomery form. * m Modulus (prime). */ -static void sp_521_mont_add_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, - const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_521_mont_add_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) +#else +static void sp_521_mont_add_17(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r3, #0\n\t" @@ -117414,9 +119859,8 @@ static void sp_521_mont_add_17(sp_digit* r_p, const sp_digit* a_p, const sp_digi "ldm %[b]!, {r4}\n\t" "adcs r8, r8, r4\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r12, #0x1\n\t" - "lsl r12, r12, #8\n\t" - "add r12, r12, #0xff\n\t" + "mov r12, #0xff\n\t" + "orr r12, r12, #0x100\n\t" #else "mov r12, #0x1ff\n\t" #endif @@ -117447,12 +119891,21 @@ static void sp_521_mont_add_17(sp_digit* r_p, const sp_digit* a_p, const sp_digi "ldm %[r], {r4}\n\t" "adcs r4, r4, #0\n\t" "stm %[r]!, {r4}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } /* Double a Montgomery form number (r = a + a % m). @@ -117461,10 +119914,18 @@ static void sp_521_mont_add_17(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a Number to double in Montgomery form. * m Modulus (prime). */ -static void sp_521_mont_dbl_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_521_mont_dbl_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) +#else +static void sp_521_mont_dbl_17(sp_digit* r, const sp_digit* a, + const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r2, #0\n\t" @@ -117491,9 +119952,8 @@ static void sp_521_mont_dbl_17(sp_digit* r_p, const sp_digit* a_p, const sp_digi "ldm %[a]!, {r4}\n\t" "adcs r4, r4, r4\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r3, #0x1\n\t" - "lsl r3, r3, #8\n\t" - "add r3, r3, #0xff\n\t" + "mov r3, #0xff\n\t" + "orr r3, r3, #0x100\n\t" #else "mov r3, #0x1ff\n\t" #endif @@ -117524,12 +119984,21 @@ static void sp_521_mont_dbl_17(sp_digit* r_p, const sp_digit* a_p, const sp_digi "ldm %[r], {r4}\n\t" "adcs r4, r4, #0\n\t" "stm %[r]!, {r4}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r2", "r3" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } /* Triple a Montgomery form number (r = a + a + a % m). @@ -117538,10 +120007,18 @@ static void sp_521_mont_dbl_17(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a Number to triple in Montgomery form. * m Modulus (prime). */ -static void sp_521_mont_tpl_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_521_mont_tpl_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) +#else +static void sp_521_mont_tpl_17(sp_digit* r, const sp_digit* a, + const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r2, #0\n\t" @@ -117602,9 +120079,8 @@ static void sp_521_mont_tpl_17(sp_digit* r_p, const sp_digit* a_p, const sp_digi "ldm %[a]!, {r8}\n\t" "adcs r4, r4, r8\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r3, #0x1\n\t" - "lsl r3, r3, #8\n\t" - "add r3, r3, #0xff\n\t" + "mov r3, #0xff\n\t" + "orr r3, r3, #0x100\n\t" #else "mov r3, #0x1ff\n\t" #endif @@ -117621,12 +120097,21 @@ static void sp_521_mont_tpl_17(sp_digit* r_p, const sp_digit* a_p, const sp_digi "ldm %[r], {r4}\n\t" "adcs r4, r4, #0\n\t" "stm %[r]!, {r4}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r2", "r3" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } /* Subtract two Montgomery form numbers (r = a - b % m). @@ -117636,12 +120121,19 @@ static void sp_521_mont_tpl_17(sp_digit* r_p, const sp_digit* a_p, const sp_digi * b Number to subtract with in Montgomery form. * m Modulus (prime). */ -static void sp_521_mont_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, - const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_521_mont_sub_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) +#else +static void sp_521_mont_sub_17(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r3, #0\n\t" @@ -117677,9 +120169,8 @@ static void sp_521_mont_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digi "ldm %[b]!, {r4}\n\t" "sbcs r8, r8, r4\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r12, #0x1\n\t" - "lsl r12, r12, #8\n\t" - "add r12, r12, #0xff\n\t" + "mov r12, #0xff\n\t" + "orr r12, r12, #0x100\n\t" #else "mov r12, #0x1ff\n\t" #endif @@ -117711,18 +120202,33 @@ static void sp_521_mont_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digi "ldm %[r], {r4}\n\t" "sbcs r4, r4, #0\n\t" "stm %[r]!, {r4}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; +#else + (void)m; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ } +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_521_rshift1_17(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_521_rshift1_17(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3}\n\t" @@ -117791,8 +120297,13 @@ static void sp_521_rshift1_17(sp_digit* r_p, const sp_digit* a_p) "lsr r3, r3, #1\n\t" "str r2, [%[r], #60]\n\t" "str r3, [%[r], #64]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4" ); } @@ -121994,9 +124505,15 @@ int sp_ecc_mulmod_base_add_521(const mp_int* km, const ecc_point* am, * * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_521_add_one_17(sp_digit* a_p) +#else +static void sp_521_add_one_17(sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r1, r2, r3, r4}\n\t" @@ -122026,8 +124543,13 @@ static void sp_521_add_one_17(sp_digit* a_p) "ldm %[a], {r1}\n\t" "adcs r1, r1, #0\n\t" "stm %[a]!, {r1}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a) : +#else + : + : [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r1", "r2", "r3", "r4" ); } @@ -122066,9 +124588,9 @@ static void sp_521_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -122410,17 +124932,22 @@ int sp_ecc_secret_gen_521_nb(sp_ecc_ctx_t* sp_ctx, const mp_int* priv, #endif /* HAVE_ECC_DHE */ #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_521_rshift_17(sp_digit* r_p, const sp_digit* a_p, byte n_p) +#else +static void sp_521_rshift_17(sp_digit* r, const sp_digit* a, byte n) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register byte n asm ("r2") = (byte)n_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "rsb r12, %[n], #32\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "ldr r4, [%[a]]\n\t" - "ldr r5, [%[a], #4]\n\t" + "ldm r1, {r4, r5}\n\t" #else "ldrd r4, r5, [%[a]]\n\t" #endif @@ -122509,8 +125036,13 @@ static void sp_521_rshift_17(sp_digit* r_p, const sp_digit* a_p, byte n_p) #else "strd r4, r5, [%[r], #60]\n\t" #endif +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [n] "+r" (n) : +#else + : + : [r] "r" (r), [a] "r" (a), [n] "r" (n) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r3", "r12" ); } @@ -122519,11 +125051,17 @@ static void sp_521_rshift_17(sp_digit* r_p, const sp_digit* a_p, byte n_p) #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) #endif #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_521_lshift_17(sp_digit* r_p, const sp_digit* a_p, byte n_p) +#else +static void sp_521_lshift_17(sp_digit* r, const sp_digit* a, byte n) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register byte n asm ("r2") = (byte)n_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "rsb r12, %[n], #31\n\t" @@ -122629,17 +125167,28 @@ static void sp_521_lshift_17(sp_digit* r_p, const sp_digit* a_p, byte n_p) "orr r5, r5, r3\n\t" "str r4, [%[r]]\n\t" "str r5, [%[r], #4]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [n] "+r" (n) : +#else + : + : [r] "r" (r), [a] "r" (a), [n] "r" (n) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r3", "r12" ); } +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_521_lshift_34(sp_digit* r_p, const sp_digit* a_p, byte n_p) +#else +static void sp_521_lshift_34(sp_digit* r, const sp_digit* a, byte n) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register byte n asm ("r2") = (byte)n_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "rsb r12, %[n], #31\n\t" @@ -122847,8 +125396,13 @@ static void sp_521_lshift_34(sp_digit* r_p, const sp_digit* a_p, byte n_p) "orr r6, r6, r3\n\t" "str r5, [%[r]]\n\t" "str r6, [%[r], #4]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [n] "+r" (n) : +#else + : + : [r] "r" (r), [a] "r" (a), [n] "r" (n) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r3", "r12" ); } @@ -122859,10 +125413,16 @@ static void sp_521_lshift_34(sp_digit* r_p, const sp_digit* a_p, byte n_p) * a A single precision integer. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_521_sub_in_place_17(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_521_sub_in_place_17(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -122886,8 +125446,13 @@ static sp_digit sp_521_sub_in_place_17(sp_digit* a_p, const sp_digit* b_p) "sbcs r2, r2, r6\n\t" "stm %[a]!, {r2}\n\t" "sbc %[a], %[a], %[a]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12", "lr" ); @@ -122900,10 +125465,16 @@ static sp_digit sp_521_sub_in_place_17(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer and result. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_521_sub_in_place_17(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_521_sub_in_place_17(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3, r4, r5}\n\t" @@ -122939,8 +125510,13 @@ static sp_digit sp_521_sub_in_place_17(sp_digit* a_p, const sp_digit* b_p) "sbcs r2, r2, r6\n\t" "stm %[a]!, {r2}\n\t" "sbc %[a], r9, r9\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; @@ -122954,11 +125530,17 @@ static sp_digit sp_521_sub_in_place_17(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_521_mul_d_17(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_521_mul_d_17(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -123039,8 +125621,13 @@ static void sp_521_mul_d_17(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) "cmp r9, #0x44\n\t" "blt L_sp_521_mul_d_17_word_%=\n\t" "str r3, [%[r], #68]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -123052,11 +125639,17 @@ static void sp_521_mul_d_17(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_521_mul_d_17(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_521_mul_d_17(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -123600,8 +126193,13 @@ static void sp_521_mul_d_17(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) #endif "stm %[r]!, {r4}\n\t" "str r5, [%[r]]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -123617,11 +126215,17 @@ static void sp_521_mul_d_17(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_521_word_17(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_521_word_17(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr r6, %[div], #16\n\t" @@ -123659,8 +126263,13 @@ static sp_digit div_521_word_17(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "sub %[d0], %[d0], r3\n\t" "udiv r3, %[d0], %[div]\n\t" "add %[d1], r4, r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -123676,11 +126285,17 @@ static sp_digit div_521_word_17(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_521_word_17(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_521_word_17(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr lr, %[div], #1\n\t" @@ -123797,8 +126412,13 @@ static sp_digit div_521_word_17(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "subs r6, %[div], r7\n\t" "sbc r6, r6, r6\n\t" "sub %[d1], r3, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -124459,11 +127079,18 @@ int sp_ecc_sign_521_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_521_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_521_sub_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_521_sub_17(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -124487,8 +127114,13 @@ static sp_digit sp_521_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit "sbcs r3, r3, r7\n\t" "stm %[r]!, {r3}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "lr" ); @@ -124502,11 +127134,18 @@ static sp_digit sp_521_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_521_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_521_sub_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_521_sub_17(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -124542,8 +127181,13 @@ static sp_digit sp_521_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit "sbcs r3, r3, r7\n\t" "stm %[r]!, {r3}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -124556,11 +127200,19 @@ static sp_digit sp_521_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit * a Number to divide. * m Modulus. */ -static void sp_521_div2_mod_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_521_div2_mod_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) +#else +static void sp_521_div2_mod_17(sp_digit* r, const sp_digit* a, + const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* m asm ("r2") = (const sp_digit*)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r4}\n\t" @@ -124617,8 +127269,7 @@ static void sp_521_div2_mod_17(sp_digit* r_p, const sp_digit* a_p, const sp_digi "L_sp_521_div2_mod_17_div2_%=: \n\t" "sub %[r], %[r], #0x44\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "ldr r8, [%[r]]\n\t" - "ldr r9, [%[r], #4]\n\t" + "ldm r0, {r8, r9}\n\t" #else "ldrd r8, r9, [%[r]]\n\t" #endif @@ -124688,8 +127339,13 @@ static void sp_521_div2_mod_17(sp_digit* r_p, const sp_digit* a_p, const sp_digi "orr r9, r9, r3, lsl #31\n\t" "str r8, [%[r], #60]\n\t" "str r9, [%[r], #64]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); @@ -124731,11 +127387,21 @@ static const byte L_sp_521_num_bits_17_table[] = { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, }; +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static int sp_521_num_bits_17(const sp_digit* a_p) +#else +static int sp_521_num_bits_17(const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; register byte* L_sp_521_num_bits_17_table_c asm ("r1") = (byte*)&L_sp_521_num_bits_17_table; +#else + register byte* L_sp_521_num_bits_17_table_c = + (byte*)&L_sp_521_num_bits_17_table; + +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, %[L_sp_521_num_bits_17_table]\n\t" @@ -124746,9 +127412,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_16_3_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x2\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x18\n\t" + "mov r2, #0x18\n\t" + "orr r2, r2, #0x200\n\t" #else "mov r2, #0x218\n\t" #endif @@ -124762,9 +127427,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_16_2_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x2\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x10\n\t" + "mov r2, #0x10\n\t" + "orr r2, r2, #0x200\n\t" #else "mov r2, #0x210\n\t" #endif @@ -124778,9 +127442,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_16_1_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x2\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x8\n\t" + "mov r2, #0x8\n\t" + "orr r2, r2, #0x200\n\t" #else "mov r2, #0x208\n\t" #endif @@ -124790,13 +127453,7 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "\n" "L_sp_521_num_bits_17_16_1_%=: \n\t" "and r3, r1, #0xff\n\t" -#if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x2\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x0\n\t" -#else "mov r2, #0x200\n\t" -#endif "ldrb r12, [lr, r3]\n\t" "add r12, r2, r12\n\t" "b L_sp_521_num_bits_17_18_%=\n\t" @@ -124809,9 +127466,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_15_3_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xf8\n\t" + "mov r2, #0xf8\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1f8\n\t" #endif @@ -124825,9 +127481,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_15_2_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xf0\n\t" + "mov r2, #0xf0\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1f0\n\t" #endif @@ -124841,9 +127496,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_15_1_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xe8\n\t" + "mov r2, #0xe8\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1e8\n\t" #endif @@ -124854,9 +127508,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "L_sp_521_num_bits_17_15_1_%=: \n\t" "and r3, r1, #0xff\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xe0\n\t" + "mov r2, #0xe0\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1e0\n\t" #endif @@ -124872,9 +127525,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_14_3_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xd8\n\t" + "mov r2, #0xd8\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1d8\n\t" #endif @@ -124888,9 +127540,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_14_2_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xd0\n\t" + "mov r2, #0xd0\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1d0\n\t" #endif @@ -124904,9 +127555,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_14_1_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xc8\n\t" + "mov r2, #0xc8\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1c8\n\t" #endif @@ -124917,9 +127567,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "L_sp_521_num_bits_17_14_1_%=: \n\t" "and r3, r1, #0xff\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xc0\n\t" + "mov r2, #0xc0\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1c0\n\t" #endif @@ -124935,9 +127584,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_13_3_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xb8\n\t" + "mov r2, #0xb8\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1b8\n\t" #endif @@ -124951,9 +127599,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_13_2_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xb0\n\t" + "mov r2, #0xb0\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1b0\n\t" #endif @@ -124967,9 +127614,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_13_1_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xa8\n\t" + "mov r2, #0xa8\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1a8\n\t" #endif @@ -124980,9 +127626,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "L_sp_521_num_bits_17_13_1_%=: \n\t" "and r3, r1, #0xff\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xa0\n\t" + "mov r2, #0xa0\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1a0\n\t" #endif @@ -124998,9 +127643,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_12_3_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x98\n\t" + "mov r2, #0x98\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x198\n\t" #endif @@ -125014,9 +127658,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_12_2_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x90\n\t" + "mov r2, #0x90\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x190\n\t" #endif @@ -125030,9 +127673,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_12_1_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x88\n\t" + "mov r2, #0x88\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x188\n\t" #endif @@ -125043,9 +127685,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "L_sp_521_num_bits_17_12_1_%=: \n\t" "and r3, r1, #0xff\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x80\n\t" + "mov r2, #0x80\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x180\n\t" #endif @@ -125061,9 +127702,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_11_3_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x78\n\t" + "mov r2, #0x78\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x178\n\t" #endif @@ -125077,9 +127717,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_11_2_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x70\n\t" + "mov r2, #0x70\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x170\n\t" #endif @@ -125093,9 +127732,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_11_1_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x68\n\t" + "mov r2, #0x68\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x168\n\t" #endif @@ -125106,9 +127744,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "L_sp_521_num_bits_17_11_1_%=: \n\t" "and r3, r1, #0xff\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x60\n\t" + "mov r2, #0x60\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x160\n\t" #endif @@ -125124,9 +127761,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_10_3_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x58\n\t" + "mov r2, #0x58\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x158\n\t" #endif @@ -125140,9 +127776,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_10_2_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x50\n\t" + "mov r2, #0x50\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x150\n\t" #endif @@ -125156,9 +127791,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_10_1_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x48\n\t" + "mov r2, #0x48\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x148\n\t" #endif @@ -125169,9 +127803,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "L_sp_521_num_bits_17_10_1_%=: \n\t" "and r3, r1, #0xff\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x40\n\t" + "mov r2, #0x40\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x140\n\t" #endif @@ -125187,9 +127820,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_9_3_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x38\n\t" + "mov r2, #0x38\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x138\n\t" #endif @@ -125203,9 +127835,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_9_2_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x30\n\t" + "mov r2, #0x30\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x130\n\t" #endif @@ -125219,9 +127850,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_9_1_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x28\n\t" + "mov r2, #0x28\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x128\n\t" #endif @@ -125232,9 +127862,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "L_sp_521_num_bits_17_9_1_%=: \n\t" "and r3, r1, #0xff\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x20\n\t" + "mov r2, #0x20\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x120\n\t" #endif @@ -125250,9 +127879,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_8_3_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x18\n\t" + "mov r2, #0x18\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x118\n\t" #endif @@ -125266,9 +127894,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_8_2_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x10\n\t" + "mov r2, #0x10\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x110\n\t" #endif @@ -125282,9 +127909,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r3, #0\n\t" "beq L_sp_521_num_bits_17_8_1_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x8\n\t" + "mov r2, #0x8\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x108\n\t" #endif @@ -125294,13 +127920,7 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "\n" "L_sp_521_num_bits_17_8_1_%=: \n\t" "and r3, r1, #0xff\n\t" -#if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x0\n\t" -#else "mov r2, #0x100\n\t" -#endif "ldrb r12, [lr, r3]\n\t" "add r12, r2, r12\n\t" "b L_sp_521_num_bits_17_18_%=\n\t" @@ -125614,27 +128234,38 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "\n" "L_sp_521_num_bits_17_18_%=: \n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [L_sp_521_num_bits_17_table] "+r" (L_sp_521_num_bits_17_table_c) : +#else + : + : [a] "r" (a), + [L_sp_521_num_bits_17_table] "r" (L_sp_521_num_bits_17_table_c) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r12", "lr" ); return (word32)(size_t)a; } #else +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static int sp_521_num_bits_17(const sp_digit* a_p) +#else +static int sp_521_num_bits_17(const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldr r1, [%[a], #64]\n\t" "cmp r1, #0\n\t" "beq L_sp_521_num_bits_17_16_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x2\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x20\n\t" + "mov r2, #0x20\n\t" + "orr r2, r2, #0x200\n\t" #else "mov r2, #0x220\n\t" #endif @@ -125646,13 +128277,7 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "ldr r1, [%[a], #60]\n\t" "cmp r1, #0\n\t" "beq L_sp_521_num_bits_17_15_%=\n\t" -#if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x2\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x0\n\t" -#else "mov r2, #0x200\n\t" -#endif "clz r12, r1\n\t" "sub r12, r2, r12\n\t" "b L_sp_521_num_bits_17_18_%=\n\t" @@ -125662,9 +128287,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r1, #0\n\t" "beq L_sp_521_num_bits_17_14_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xe0\n\t" + "mov r2, #0xe0\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1e0\n\t" #endif @@ -125677,9 +128301,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r1, #0\n\t" "beq L_sp_521_num_bits_17_13_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xc0\n\t" + "mov r2, #0xc0\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1c0\n\t" #endif @@ -125692,9 +128315,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r1, #0\n\t" "beq L_sp_521_num_bits_17_12_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0xa0\n\t" + "mov r2, #0xa0\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x1a0\n\t" #endif @@ -125707,9 +128329,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r1, #0\n\t" "beq L_sp_521_num_bits_17_11_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x80\n\t" + "mov r2, #0x80\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x180\n\t" #endif @@ -125722,9 +128343,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r1, #0\n\t" "beq L_sp_521_num_bits_17_10_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x60\n\t" + "mov r2, #0x60\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x160\n\t" #endif @@ -125737,9 +128357,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r1, #0\n\t" "beq L_sp_521_num_bits_17_9_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x40\n\t" + "mov r2, #0x40\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x140\n\t" #endif @@ -125752,9 +128371,8 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "cmp r1, #0\n\t" "beq L_sp_521_num_bits_17_8_%=\n\t" #if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x20\n\t" + "mov r2, #0x20\n\t" + "orr r2, r2, #0x100\n\t" #else "mov r2, #0x120\n\t" #endif @@ -125766,13 +128384,7 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "ldr r1, [%[a], #28]\n\t" "cmp r1, #0\n\t" "beq L_sp_521_num_bits_17_7_%=\n\t" -#if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 7) - "mov r2, #0x1\n\t" - "lsl r2, r2, #8\n\t" - "add r2, r2, #0x0\n\t" -#else "mov r2, #0x100\n\t" -#endif "clz r12, r1\n\t" "sub r12, r2, r12\n\t" "b L_sp_521_num_bits_17_18_%=\n\t" @@ -125839,8 +128451,13 @@ static int sp_521_num_bits_17(const sp_digit* a_p) "\n" "L_sp_521_num_bits_17_18_%=: \n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a) : +#else + : + : [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r1", "r2", "r3", "r12", "lr" ); return (word32)(size_t)a; @@ -126854,11 +129471,18 @@ typedef struct sp_point_1024 { * a A single precision integer. * b A single precision integer. */ -static void sp_1024_mul_16(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_1024_mul_16(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_1024_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x40\n\t" @@ -136600,8 +139224,13 @@ static void sp_1024_mul_16(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b "stm %[r]!, {r3, r4, r5, r6}\n\t" "ldm sp!, {r3, r4, r5, r6}\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", "r12" ); @@ -136612,10 +139241,16 @@ static void sp_1024_mul_16(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_1024_sqr_16(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_1024_sqr_16(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x40\n\t" @@ -141833,8 +144468,13 @@ static void sp_1024_sqr_16(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r2, r3, r4, r8}\n\t" "ldm sp!, {r2, r3, r4, r8}\n\t" "stm %[r]!, {r2, r3, r4, r8}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12" ); @@ -141846,11 +144486,19 @@ static void sp_1024_sqr_16(sp_digit* r_p, const sp_digit* a_p) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_1024_add_16(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_1024_add_16(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_1024_add_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -141883,8 +144531,13 @@ static sp_digit sp_1024_add_16(sp_digit* r_p, const sp_digit* a_p, const sp_digi "stm %[r]!, {r3, r4, r5, r6}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -141895,10 +144548,16 @@ static sp_digit sp_1024_add_16(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a A single precision integer and result. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_1024_sub_in_place_32(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_1024_sub_in_place_32(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3, r4, r5}\n\t" @@ -141958,8 +144617,13 @@ static sp_digit sp_1024_sub_in_place_32(sp_digit* a_p, const sp_digit* b_p) "sbcs r5, r5, r9\n\t" "stm %[a]!, {r2, r3, r4, r5}\n\t" "sbc %[a], r9, r9\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; @@ -141971,11 +144635,19 @@ static sp_digit sp_1024_sub_in_place_32(sp_digit* a_p, const sp_digit* b_p) * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_1024_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_1024_add_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -142036,8 +144708,13 @@ static sp_digit sp_1024_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digi "stm %[r]!, {r3, r4, r5, r6}\n\t" "mov %[r], #0\n\t" "adc %[r], %[r], #0\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -142118,11 +144795,19 @@ SP_NOINLINE static void sp_1024_mul_32(sp_digit* r, const sp_digit* a, * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_1024_sub_16(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_1024_sub_16(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_1024_sub_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r3, r4, r5, r6}\n\t" @@ -142154,8 +144839,13 @@ static sp_digit sp_1024_sub_16(sp_digit* r_p, const sp_digit* a_p, const sp_digi "sbcs r6, r6, r10\n\t" "stm %[r]!, {r3, r4, r5, r6}\n\t" "sbc %[r], r6, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; @@ -142204,11 +144894,18 @@ SP_NOINLINE static void sp_1024_sqr_32(sp_digit* r, const sp_digit* a) * a A single precision integer. * b A single precision integer. */ -static void sp_1024_mul_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static void sp_1024_mul_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static void sp_1024_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x100\n\t" @@ -142391,8 +145088,13 @@ static void sp_1024_mul_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_1024_mul_32_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -142403,10 +145105,16 @@ static void sp_1024_mul_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b * r A single precision integer. * a A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_1024_sqr_32(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_1024_sqr_32(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "sub sp, sp, #0x100\n\t" @@ -142549,8 +145257,13 @@ static void sp_1024_sqr_32(sp_digit* r_p, const sp_digit* a_p) "stm %[r]!, {r3, r4, r6, r7, r8, r9, r10, r11}\n\t" "subs r5, r5, #32\n\t" "bgt L_sp_1024_sqr_32_store_%=\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11" ); @@ -142648,10 +145361,16 @@ static const sp_point_1024 p1024_base = { * a A single precision integer. * b A single precision integer. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_1024_sub_in_place_32(sp_digit* a_p, const sp_digit* b_p) +#else +static sp_digit sp_1024_sub_in_place_32(sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -142670,8 +145389,13 @@ static sp_digit sp_1024_sub_in_place_32(sp_digit* a_p, const sp_digit* b_p) "cmp %[a], lr\n\t" "bne L_sp_1024_sub_in_pkace_32_word_%=\n\t" "mov %[a], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r12", "lr" ); @@ -142688,13 +145412,20 @@ static sp_digit sp_1024_sub_in_place_32(sp_digit* a_p, const sp_digit* b_p) * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_1024_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_1024_cond_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r6, #0\n\t" @@ -142713,8 +145444,13 @@ static sp_digit sp_1024_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, "cmp lr, #0x80\n\t" "blt L_sp_1024_cond_sub_32_words_%=\n\t" "mov %[r], r12\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -142729,13 +145465,20 @@ static sp_digit sp_1024_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to subtract. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_1024_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_1024_cond_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -142852,8 +145595,13 @@ static sp_digit sp_1024_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, "sbcs r5, r5, r7\n\t" "stm %[r]!, {r4, r5}\n\t" "sbc %[r], lr, lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7" ); return (word32)(size_t)r; @@ -142867,11 +145615,19 @@ static sp_digit sp_1024_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, * a A single precision integer. * b A single precision integer. */ -static sp_digit sp_1024_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static sp_digit sp_1024_add_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) +#else +static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r3, #0\n\t" @@ -142891,8 +145647,13 @@ static sp_digit sp_1024_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digi "cmp %[a], r12\n\t" "bne L_sp_1024_add_32_word_%=\n\t" "mov %[r], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12" ); @@ -142907,11 +145668,17 @@ static sp_digit sp_1024_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digi * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_1024_mul_d_32(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_1024_mul_d_32(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -142992,8 +145759,13 @@ static void sp_1024_mul_d_32(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) "cmp r9, #0x80\n\t" "blt L_sp_1024_mul_d_32_word_%=\n\t" "str r3, [%[r], #128]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -143005,11 +145777,17 @@ static void sp_1024_mul_d_32(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * a A single precision integer. * b A single precision digit. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_1024_mul_d_32(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) +#else +static void sp_1024_mul_d_32(sp_digit* r, const sp_digit* a, sp_digit b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register sp_digit b asm ("r2") = (sp_digit)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* A[0] * B */ @@ -144033,8 +146811,13 @@ static void sp_1024_mul_d_32(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) #endif "stm %[r]!, {r4}\n\t" "str r5, [%[r]]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -144050,11 +146833,17 @@ static void sp_1024_mul_d_32(sp_digit* r_p, const sp_digit* a_p, sp_digit b_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_1024_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_1024_word_32(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr r6, %[div], #16\n\t" @@ -144092,8 +146881,13 @@ static sp_digit div_1024_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "sub %[d0], %[d0], r3\n\t" "udiv r3, %[d0], %[div]\n\t" "add %[d1], r4, r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -144109,11 +146903,17 @@ static sp_digit div_1024_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) * * Note that this is an approximate div. It may give an answer 1 larger. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit div_1024_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +#else +static sp_digit div_1024_word_32(sp_digit d1, sp_digit d0, sp_digit div) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit d1 asm ("r0") = (sp_digit)d1_p; register sp_digit d0 asm ("r1") = (sp_digit)d0_p; register sp_digit div asm ("r2") = (sp_digit)div_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "lsr lr, %[div], #1\n\t" @@ -144230,8 +147030,13 @@ static sp_digit div_1024_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) "subs r6, %[div], r7\n\t" "sbc r6, r6, r6\n\t" "sub %[d1], r3, r6\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : +#else + : + : [d1] "r" (d1), [d0] "r" (d0), [div] "r" (div) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)d1; @@ -144275,10 +147080,16 @@ static void sp_1024_mask_32(sp_digit* r, const sp_digit* a, sp_digit m) * return -ve, 0 or +ve if a is less than, equal to or greater than b * respectively. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_int32 sp_1024_cmp_32(const sp_digit* a_p, const sp_digit* b_p) +#else +static sp_int32 sp_1024_cmp_32(const sp_digit* a, const sp_digit* b) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register const sp_digit* a asm ("r0") = (const sp_digit*)a_p; register const sp_digit* b asm ("r1") = (const sp_digit*)b_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r2, #-1\n\t" @@ -144659,8 +147470,13 @@ static sp_int32 sp_1024_cmp_32(const sp_digit* a_p, const sp_digit* b_p) "eor r2, r2, r3\n\t" #endif /*WOLFSSL_SP_SMALL */ "mov %[a], r2\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [b] "+r" (b) : +#else + : + : [a] "r" (a), [b] "r" (b) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)a; @@ -145002,11 +147818,19 @@ static int sp_1024_point_to_ecc_point_32(const sp_point_1024* p, ecc_point* pm) * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( #if !(defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 4)) @@ -145973,8 +148797,13 @@ static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a_p, const sp_digit* m_ "sbc r10, r10, r10\n\t" "orr r3, r3, r10\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -145988,11 +148817,19 @@ static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a_p, const sp_digit* m_ * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldr r11, [%[m]]\n\t" @@ -146274,8 +149111,13 @@ static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a_p, const sp_digit* m_ "sbc r10, r10, r10\n\t" "orr r3, r3, r10\n\t" "mov %[mp], r3\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -146289,11 +149131,19 @@ static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a_p, const sp_digit* m_ * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG +static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) +#else +static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* a asm ("r0") = (sp_digit*)a_p; register const sp_digit* m asm ("r1") = (const sp_digit*)m_p; register sp_digit mp asm ("r2") = (sp_digit)mp_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( /* i = 0 */ @@ -146485,8 +149335,13 @@ static SP_NOINLINE void sp_1024_mont_reduce_32(sp_digit* a_p, const sp_digit* m_ "sbc r3, r3, r3\n\t" "orr lr, lr, r3\n\t" "mov %[mp], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : +#else + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r3", "r12", "lr", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11" ); @@ -146638,13 +149493,20 @@ static void sp_1024_map_32(sp_point_1024* r, const sp_point_1024* p, * b Second number to add in Montgomery form. * m Modulus (prime). */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_1024_mont_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, const sp_digit* m_p) +#else +static void sp_1024_mont_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register const sp_digit* m asm ("r3") = (const sp_digit*)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -146799,8 +149661,13 @@ static void sp_1024_mont_add_32(sp_digit* r_p, const sp_digit* a_p, "sbcs r6, r6, r10\n\t" "sbc r7, r7, r11\n\t" "stm %[r]!, {r4, r5, r6, r7}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); @@ -146812,12 +149679,19 @@ static void sp_1024_mont_add_32(sp_digit* r_p, const sp_digit* a_p, * a Number to double in Montgomery form. * m Modulus (prime). */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_1024_mont_dbl_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +#else +static void sp_1024_mont_dbl_32(sp_digit* r, const sp_digit* a, + const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* m asm ("r2") = (const sp_digit*)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -146956,8 +149830,13 @@ static void sp_1024_mont_dbl_32(sp_digit* r_p, const sp_digit* a_p, "sbcs r6, r6, r10\n\t" "sbc r7, r7, r11\n\t" "stm %[r]!, {r4, r5, r6, r7}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r8", "r9", "r10", "r11", "r4", "r5", "r6", "r7", "r12" ); @@ -146969,12 +149848,19 @@ static void sp_1024_mont_dbl_32(sp_digit* r_p, const sp_digit* a_p, * a Number to triple in Montgomery form. * m Modulus (prime). */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_1024_mont_tpl_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +#else +static void sp_1024_mont_tpl_32(sp_digit* r, const sp_digit* a, + const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* m asm ("r2") = (const sp_digit*)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r12, #0\n\t" @@ -147268,8 +150154,13 @@ static void sp_1024_mont_tpl_32(sp_digit* r_p, const sp_digit* a_p, "sbcs r6, r6, r10\n\t" "sbc r7, r7, r11\n\t" "stm %[r]!, {r4, r5, r6, r7}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r8", "r9", "r10", "r11", "r4", "r5", "r6", "r7", "r12" ); @@ -147282,13 +150173,20 @@ static void sp_1024_mont_tpl_32(sp_digit* r_p, const sp_digit* a_p, * b Number to subtract with in Montgomery form. * m Modulus (prime). */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_1024_mont_sub_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, const sp_digit* m_p) +#else +static void sp_1024_mont_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register const sp_digit* m asm ("r3") = (const sp_digit*)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a]!, {r4, r5, r6, r7}\n\t" @@ -147437,8 +150335,13 @@ static void sp_1024_mont_sub_32(sp_digit* r_p, const sp_digit* a_p, "adcs r6, r6, r10\n\t" "adc r7, r7, r11\n\t" "stm %[r]!, {r4, r5, r6, r7}\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); @@ -147453,13 +150356,20 @@ static void sp_1024_mont_sub_32(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to add. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_1024_cond_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_1024_cond_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov lr, #0\n\t" @@ -147478,8 +150388,13 @@ static sp_digit sp_1024_cond_add_32(sp_digit* r_p, const sp_digit* a_p, "cmp r12, #0x80\n\t" "blt L_sp_1024_cond_add_32_words_%=\n\t" "mov %[r], lr\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6" ); return (word32)(size_t)r; @@ -147494,13 +150409,20 @@ static sp_digit sp_1024_cond_add_32(sp_digit* r_p, const sp_digit* a_p, * b A single precision number to add. * m Mask value to apply. */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static sp_digit sp_1024_cond_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +#else +static sp_digit sp_1024_cond_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; register const sp_digit* b asm ("r2") = (const sp_digit*)b_p; register sp_digit m asm ("r3") = (sp_digit)m_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "mov r8, #0\n\t" @@ -147617,18 +150539,29 @@ static sp_digit sp_1024_cond_add_32(sp_digit* r_p, const sp_digit* a_p, "adcs r5, r5, r7\n\t" "stm %[r]!, {r4, r5}\n\t" "adc %[r], r8, r8\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : +#else + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r12", "lr", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } #endif /* WOLFSSL_SP_SMALL */ +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG static void sp_1024_rshift1_32(sp_digit* r_p, const sp_digit* a_p) +#else +static void sp_1024_rshift1_32(sp_digit* r, const sp_digit* a) +#endif /* WOLFSSL_NO_VAR_ASSIGN_REG */ { +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG register sp_digit* r asm ("r0") = (sp_digit*)r_p; register const sp_digit* a asm ("r1") = (const sp_digit*)a_p; +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ __asm__ __volatile__ ( "ldm %[a], {r2, r3}\n\t" @@ -147757,8 +150690,13 @@ static void sp_1024_rshift1_32(sp_digit* r_p, const sp_digit* a_p) "lsr r3, r3, #1\n\t" "str r2, [%[r], #120]\n\t" "str r3, [%[r], #124]\n\t" +#ifndef WOLFSSL_NO_VAR_ASSIGN_REG : [r] "+r" (r), [a] "+r" (a) : +#else + : + : [r] "r" (r), [a] "r" (a) +#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ : "memory", "cc", "r2", "r3", "r4" ); } @@ -156725,9 +159663,9 @@ static void sp_1024_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; diff --git a/src/wolfcrypt/src/sp_arm64.c b/src/wolfcrypt/src/sp_arm64.c index 2825042..3b9bc25 100644 --- a/src/wolfcrypt/src/sp_arm64.c +++ b/src/wolfcrypt/src/sp_arm64.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -21,16 +21,11 @@ /* Implementation by Sean Parkinson. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \ defined(WOLFSSL_HAVE_SP_ECC) -#include #include #ifdef NO_INLINE #include diff --git a/src/wolfcrypt/src/sp_armthumb.c b/src/wolfcrypt/src/sp_armthumb.c index 894000e..4868f7f 100644 --- a/src/wolfcrypt/src/sp_armthumb.c +++ b/src/wolfcrypt/src/sp_armthumb.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -21,16 +21,11 @@ /* Implementation by Sean Parkinson. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \ defined(WOLFSSL_HAVE_SP_ECC) -#include #include #ifdef NO_INLINE #include @@ -114,9 +109,9 @@ static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -30305,9 +30300,9 @@ static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -83399,9 +83394,9 @@ static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -103943,9 +103938,9 @@ static void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -114852,9 +114847,9 @@ static void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -129094,9 +129089,9 @@ static void sp_521_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -218537,9 +218532,9 @@ static void sp_1024_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; diff --git a/src/wolfcrypt/src/sp_c32.c b/src/wolfcrypt/src/sp_c32.c index a1f0eb2..10d646a 100644 --- a/src/wolfcrypt/src/sp_c32.c +++ b/src/wolfcrypt/src/sp_c32.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -21,16 +21,11 @@ /* Implementation by Sean Parkinson. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \ defined(WOLFSSL_HAVE_SP_ECC) -#include #include #ifdef NO_INLINE #include diff --git a/src/wolfcrypt/src/sp_c64.c b/src/wolfcrypt/src/sp_c64.c index 0a77db8..06dc0bd 100644 --- a/src/wolfcrypt/src/sp_c64.c +++ b/src/wolfcrypt/src/sp_c64.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -21,16 +21,11 @@ /* Implementation by Sean Parkinson. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \ defined(WOLFSSL_HAVE_SP_ECC) -#include #include #ifdef NO_INLINE #include diff --git a/src/wolfcrypt/src/sp_cortexm.c b/src/wolfcrypt/src/sp_cortexm.c index ada8bbf..fc756ff 100644 --- a/src/wolfcrypt/src/sp_cortexm.c +++ b/src/wolfcrypt/src/sp_cortexm.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -21,16 +21,11 @@ /* Implementation by Sean Parkinson. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \ defined(WOLFSSL_HAVE_SP_ECC) -#include #include #ifdef NO_INLINE #include @@ -114,9 +109,9 @@ static void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -257,9 +252,11 @@ static void sp_2048_to_bin_64(sp_digit* r, byte* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +SP_NOINLINE static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -SP_NOINLINE static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +SP_NOINLINE static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -604,7 +601,8 @@ SP_NOINLINE static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_d "ADD sp, sp, #0x24\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); } @@ -616,9 +614,11 @@ SP_NOINLINE static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_d * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +SP_NOINLINE static void sp_2048_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -SP_NOINLINE static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +SP_NOINLINE static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -741,7 +741,8 @@ SP_NOINLINE static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_d "ADD sp, sp, #0x2c\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r10", "r11", "r12", "r7", "r8", "r9", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r10", "r11", "r12", "r7", + "r8", "r9", "lr" ); } @@ -753,7 +754,8 @@ SP_NOINLINE static void sp_2048_mul_8(sp_digit* r, const sp_digit* a, const sp_d * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_2048_add_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_2048_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -783,7 +785,7 @@ static sp_digit sp_2048_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -836,7 +838,7 @@ static sp_digit sp_2048_sub_in_place_16(sp_digit* a, const sp_digit* b) "SBC %[a], r9, r9\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; } @@ -848,9 +850,11 @@ static sp_digit sp_2048_sub_in_place_16(sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_add_16(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_2048_add_16(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_2048_add_16(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_2048_add_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -892,7 +896,7 @@ static sp_digit sp_2048_add_16(sp_digit* r, const sp_digit* a, const sp_digit* b "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -1038,7 +1042,7 @@ static sp_digit sp_2048_sub_in_place_32(sp_digit* a, const sp_digit* b) "SBC %[a], r9, r9\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; } @@ -1050,9 +1054,11 @@ static sp_digit sp_2048_sub_in_place_32(sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_2048_add_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -1122,7 +1128,7 @@ static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -1328,7 +1334,7 @@ static sp_digit sp_2048_sub_in_place_64(sp_digit* a, const sp_digit* b) "SBC %[a], r9, r9\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; } @@ -1340,9 +1346,11 @@ static sp_digit sp_2048_sub_in_place_64(sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_add_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_2048_add_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -1468,7 +1476,7 @@ static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a, const sp_digit* b "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -1787,7 +1795,8 @@ SP_NOINLINE static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "ADD sp, sp, #0x44\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); } @@ -1904,7 +1913,8 @@ SP_NOINLINE static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) "ADD sp, sp, #0x20\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); } @@ -1916,7 +1926,8 @@ SP_NOINLINE static void sp_2048_sqr_8(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_2048_sub_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_2048_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -1945,7 +1956,7 @@ static sp_digit sp_2048_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -1993,9 +2004,11 @@ SP_NOINLINE static void sp_2048_sqr_16(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_sub_16(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_2048_sub_16(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_2048_sub_16(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_2048_sub_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -2036,7 +2049,7 @@ static sp_digit sp_2048_sub_16(sp_digit* r, const sp_digit* a, const sp_digit* b "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -2084,9 +2097,11 @@ SP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_sub_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_2048_sub_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_2048_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_2048_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -2155,7 +2170,7 @@ static sp_digit sp_2048_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -2205,9 +2220,11 @@ SP_NOINLINE static void sp_2048_sqr_64(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_add_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_2048_add_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -2246,7 +2263,8 @@ static sp_digit sp_2048_add_64(sp_digit* r, const sp_digit* a, const sp_digit* b "MOV %[r], r3\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); return (word32)(size_t)r; } @@ -2298,7 +2316,8 @@ static sp_digit sp_2048_sub_in_place_64(sp_digit* a, const sp_digit* b) "MOV %[a], r10\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11" ); return (word32)(size_t)a; } @@ -2312,7 +2331,8 @@ static sp_digit sp_2048_sub_in_place_64(sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_2048_mul_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static void sp_2048_mul_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static void sp_2048_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -2426,7 +2446,8 @@ static void sp_2048_mul_64(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -2543,7 +2564,8 @@ static void sp_2048_sqr_64(sp_digit* r, const sp_digit* a) #endif : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -2574,9 +2596,11 @@ static void sp_2048_mask_32(sp_digit* r, const sp_digit* a, sp_digit m) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_2048_add_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -2615,7 +2639,8 @@ static sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b "MOV %[r], r3\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); return (word32)(size_t)r; } @@ -2667,7 +2692,8 @@ static sp_digit sp_2048_sub_in_place_32(sp_digit* a, const sp_digit* b) "MOV %[a], r10\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11" ); return (word32)(size_t)a; } @@ -2681,7 +2707,8 @@ static sp_digit sp_2048_sub_in_place_32(sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_2048_mul_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static void sp_2048_mul_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static void sp_2048_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -2795,7 +2822,8 @@ static void sp_2048_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -2912,7 +2940,8 @@ static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a) #endif : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -2994,7 +3023,7 @@ static void sp_2048_mul_d_64(sp_digit* r, const sp_digit* a, sp_digit b) "STR r3, [%[r], #256]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -3340,7 +3369,7 @@ static void sp_2048_mul_d_64(sp_digit* r, const sp_digit* a, sp_digit b) "STR r4, [%[r]]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -3370,9 +3399,11 @@ static void sp_2048_mont_norm_32(sp_digit* r, const sp_digit* m) * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_2048_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -3411,7 +3442,7 @@ static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_dig "MOV %[r], r4\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -3426,9 +3457,11 @@ static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_dig * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_2048_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -3555,7 +3588,7 @@ static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_dig "SBC %[r], r5, r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)r; } @@ -3570,9 +3603,11 @@ static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_dig * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -3868,7 +3903,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, s "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_2048_cond_sub_32(a - 32, a, m, (sp_digit)0 - mp); } @@ -3881,9 +3917,11 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, s * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -3986,7 +4024,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, s "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); sp_2048_cond_sub_32(a - 32, a, m, (sp_digit)0 - mp); } @@ -4001,9 +4040,11 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, s * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -4209,7 +4250,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, s "MOV %[mp], r5\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_2048_cond_sub_32(a - 32, a, m, (sp_digit)0 - mp); } @@ -4222,9 +4264,11 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, s * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -4315,7 +4359,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_32(sp_digit* a, const sp_digit* m, s "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); sp_2048_cond_sub_32(a - 32, a, m, (sp_digit)0 - mp); } @@ -4407,7 +4452,7 @@ static void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a, sp_digit b) "STR r3, [%[r], #128]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -4593,7 +4638,7 @@ static void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a, sp_digit b) "STR r5, [%[r]]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -4609,9 +4654,11 @@ static void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a, sp_digit b) * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -4658,7 +4705,7 @@ SP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1, sp_digit d0, sp_digit "ADD %[d1], r6, r3\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -4674,9 +4721,11 @@ SP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1, sp_digit d0, sp_digit * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -4740,7 +4789,7 @@ SP_NOINLINE static sp_digit div_2048_word_32(sp_digit d1, sp_digit d0, sp_digit "SUB %[d1], r3, r8\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -5153,7 +5202,7 @@ static sp_int32 sp_2048_cmp_32(const sp_digit* a, const sp_digit* b) "MOV %[a], r2\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)a; } @@ -5562,9 +5611,11 @@ static void sp_2048_mont_norm_64(sp_digit* r, const sp_digit* m) * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_cond_sub_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_2048_cond_sub_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -5603,7 +5654,7 @@ static sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a, const sp_dig "MOV %[r], r4\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -5618,9 +5669,11 @@ static sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a, const sp_dig * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_cond_sub_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_2048_cond_sub_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -5859,7 +5912,7 @@ static sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a, const sp_dig "SBC %[r], r5, r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)r; } @@ -5874,9 +5927,11 @@ static sp_digit sp_2048_cond_sub_64(sp_digit* r, const sp_digit* a, const sp_dig * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -6428,7 +6483,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, s "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_2048_cond_sub_64(a - 64, a, m, (sp_digit)0 - mp); } @@ -6441,9 +6497,11 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, s * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -6546,7 +6604,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, s "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); sp_2048_cond_sub_64(a - 64, a, m, (sp_digit)0 - mp); } @@ -6561,9 +6620,11 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, s * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -6929,7 +6990,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, s "MOV %[mp], r5\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_2048_cond_sub_64(a - 64, a, m, (sp_digit)0 - mp); } @@ -6942,9 +7004,11 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, s * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -7035,7 +7099,8 @@ SP_NOINLINE static void sp_2048_mont_reduce_64(sp_digit* a, const sp_digit* m, s "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); sp_2048_cond_sub_64(a - 64, a, m, (sp_digit)0 - mp); } @@ -7080,9 +7145,11 @@ SP_NOINLINE static void sp_2048_mont_sqr_64(sp_digit* r, const sp_digit* a, * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_sub_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_2048_sub_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_2048_sub_64(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_2048_sub_64(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -7120,7 +7187,8 @@ static sp_digit sp_2048_sub_64(sp_digit* r, const sp_digit* a, const sp_digit* b "MOV %[r], r11\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); return (word32)(size_t)r; } @@ -7133,9 +7201,11 @@ static sp_digit sp_2048_sub_64(sp_digit* r, const sp_digit* a, const sp_digit* b * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_sub_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_2048_sub_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_2048_sub_64(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_2048_sub_64(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -7260,7 +7330,7 @@ static sp_digit sp_2048_sub_64(sp_digit* r, const sp_digit* a, const sp_digit* b "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -7277,9 +7347,11 @@ static sp_digit sp_2048_sub_64(sp_digit* r, const sp_digit* a, const sp_digit* b * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -7326,7 +7398,7 @@ SP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1, sp_digit d0, sp_digit "ADD %[d1], r6, r3\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -7342,9 +7414,11 @@ SP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1, sp_digit d0, sp_digit * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -7408,7 +7482,7 @@ SP_NOINLINE static sp_digit div_2048_word_64(sp_digit d1, sp_digit d0, sp_digit "SUB %[d1], r3, r8\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -8276,7 +8350,7 @@ static sp_int32 sp_2048_cmp_64(const sp_digit* a, const sp_digit* b) "MOV %[a], r2\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)a; } @@ -8807,9 +8881,11 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, const mp_int* em, * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_cond_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_2048_cond_add_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_2048_cond_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_2048_cond_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -8848,7 +8924,7 @@ static sp_digit sp_2048_cond_add_32(sp_digit* r, const sp_digit* a, const sp_dig "MOV %[r], r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -8863,9 +8939,11 @@ static sp_digit sp_2048_cond_add_32(sp_digit* r, const sp_digit* a, const sp_dig * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_2048_cond_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_2048_cond_add_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_2048_cond_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_2048_cond_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -8992,7 +9070,7 @@ static sp_digit sp_2048_cond_add_32(sp_digit* r, const sp_digit* a, const sp_dig "ADC %[r], r10, r10\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -9712,7 +9790,7 @@ static void sp_2048_lshift_64(sp_digit* r, const sp_digit* a, byte n) "STR r6, [%[r], #4]\n\t" : [r] "+r" (r), [a] "+r" (a), [n] "+r" (n) : - : "memory", "r4", "r5", "r6", "r3", "r7", "cc" + : "memory", "cc", "r4", "r5", "r6", "r3", "r7" ); } @@ -9999,9 +10077,9 @@ static void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -10141,7 +10219,8 @@ static void sp_3072_to_bin_96(sp_digit* r, byte* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_3072_mul_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static void sp_3072_mul_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -11157,7 +11236,8 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "STM %[r]!, {r3, r4, r5, r6}\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", + "r12" ); } @@ -11168,9 +11248,11 @@ static void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_3072_add_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_3072_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_3072_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -11205,7 +11287,7 @@ static sp_digit sp_3072_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -11272,7 +11354,7 @@ static sp_digit sp_3072_sub_in_place_24(sp_digit* a, const sp_digit* b) "SBC %[a], r9, r9\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; } @@ -11284,9 +11366,11 @@ static sp_digit sp_3072_sub_in_place_24(sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_add_24(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_3072_add_24(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_3072_add_24(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_3072_add_24(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -11342,7 +11426,7 @@ static sp_digit sp_3072_add_24(sp_digit* r, const sp_digit* a, const sp_digit* b "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -11520,7 +11604,7 @@ static sp_digit sp_3072_sub_in_place_48(sp_digit* a, const sp_digit* b) "SBC %[a], r9, r9\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; } @@ -11532,9 +11616,11 @@ static sp_digit sp_3072_sub_in_place_48(sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_add_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_3072_add_48(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -11632,7 +11718,7 @@ static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a, const sp_digit* b "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -11894,7 +11980,7 @@ static sp_digit sp_3072_sub_in_place_96(sp_digit* a, const sp_digit* b) "SBC %[a], r9, r9\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; } @@ -11906,9 +11992,11 @@ static sp_digit sp_3072_sub_in_place_96(sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_add_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_3072_add_96(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -12090,7 +12178,7 @@ static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a, const sp_digit* b "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -12860,7 +12948,8 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) "STM %[r]!, {r2, r3, r4, r8}\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r12" ); } @@ -12871,9 +12960,11 @@ static void sp_3072_sqr_12(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_3072_sub_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_3072_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_3072_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -12907,7 +12998,7 @@ static sp_digit sp_3072_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -12955,9 +13046,11 @@ SP_NOINLINE static void sp_3072_sqr_24(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_sub_24(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_3072_sub_24(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_3072_sub_24(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_3072_sub_24(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -13012,7 +13105,7 @@ static sp_digit sp_3072_sub_24(sp_digit* r, const sp_digit* a, const sp_digit* b "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -13060,9 +13153,11 @@ SP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_sub_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_3072_sub_48(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_3072_sub_48(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_3072_sub_48(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -13159,7 +13254,7 @@ static sp_digit sp_3072_sub_48(sp_digit* r, const sp_digit* a, const sp_digit* b "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -13209,9 +13304,11 @@ SP_NOINLINE static void sp_3072_sqr_96(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_add_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_3072_add_96(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -13250,7 +13347,8 @@ static sp_digit sp_3072_add_96(sp_digit* r, const sp_digit* a, const sp_digit* b "MOV %[r], r3\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); return (word32)(size_t)r; } @@ -13302,7 +13400,8 @@ static sp_digit sp_3072_sub_in_place_96(sp_digit* a, const sp_digit* b) "MOV %[a], r10\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11" ); return (word32)(size_t)a; } @@ -13316,7 +13415,8 @@ static sp_digit sp_3072_sub_in_place_96(sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_3072_mul_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static void sp_3072_mul_96(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static void sp_3072_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -13430,7 +13530,8 @@ static void sp_3072_mul_96(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -13547,7 +13648,8 @@ static void sp_3072_sqr_96(sp_digit* r, const sp_digit* a) #endif : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -13578,9 +13680,11 @@ static void sp_3072_mask_48(sp_digit* r, const sp_digit* a, sp_digit m) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_add_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_3072_add_48(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -13619,7 +13723,8 @@ static sp_digit sp_3072_add_48(sp_digit* r, const sp_digit* a, const sp_digit* b "MOV %[r], r3\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); return (word32)(size_t)r; } @@ -13671,7 +13776,8 @@ static sp_digit sp_3072_sub_in_place_48(sp_digit* a, const sp_digit* b) "MOV %[a], r10\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11" ); return (word32)(size_t)a; } @@ -13685,7 +13791,8 @@ static sp_digit sp_3072_sub_in_place_48(sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_3072_mul_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static void sp_3072_mul_48(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static void sp_3072_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -13799,7 +13906,8 @@ static void sp_3072_mul_48(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -13916,7 +14024,8 @@ static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a) #endif : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -13998,7 +14107,7 @@ static void sp_3072_mul_d_96(sp_digit* r, const sp_digit* a, sp_digit b) "STR r3, [%[r], #384]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -14504,7 +14613,7 @@ static void sp_3072_mul_d_96(sp_digit* r, const sp_digit* a, sp_digit b) "STR r3, [%[r]]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -14534,9 +14643,11 @@ static void sp_3072_mont_norm_48(sp_digit* r, const sp_digit* m) * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_cond_sub_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_3072_cond_sub_48(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -14575,7 +14686,7 @@ static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, const sp_dig "MOV %[r], r4\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -14590,9 +14701,11 @@ static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, const sp_dig * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_cond_sub_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_3072_cond_sub_48(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -14775,7 +14888,7 @@ static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, const sp_dig "SBC %[r], r5, r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)r; } @@ -14790,9 +14903,11 @@ static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, const sp_dig * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -15216,7 +15331,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, s "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_3072_cond_sub_48(a - 48, a, m, (sp_digit)0 - mp); } @@ -15229,9 +15345,11 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, s * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -15334,7 +15452,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, s "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); sp_3072_cond_sub_48(a - 48, a, m, (sp_digit)0 - mp); } @@ -15349,9 +15468,11 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, s * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -15637,7 +15758,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, s "MOV %[mp], r5\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_3072_cond_sub_48(a - 48, a, m, (sp_digit)0 - mp); } @@ -15650,9 +15772,11 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, s * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -15743,7 +15867,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_48(sp_digit* a, const sp_digit* m, s "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); sp_3072_cond_sub_48(a - 48, a, m, (sp_digit)0 - mp); } @@ -15835,7 +15960,7 @@ static void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a, sp_digit b) "STR r3, [%[r], #192]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -16101,7 +16226,7 @@ static void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a, sp_digit b) "STR r3, [%[r]]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -16117,9 +16242,11 @@ static void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a, sp_digit b) * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -16166,7 +16293,7 @@ SP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1, sp_digit d0, sp_digit "ADD %[d1], r6, r3\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -16182,9 +16309,11 @@ SP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1, sp_digit d0, sp_digit * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -16248,7 +16377,7 @@ SP_NOINLINE static sp_digit div_3072_word_48(sp_digit d1, sp_digit d0, sp_digit "SUB %[d1], r3, r8\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -16837,7 +16966,7 @@ static sp_int32 sp_3072_cmp_48(const sp_digit* a, const sp_digit* b) "MOV %[a], r2\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)a; } @@ -17246,9 +17375,11 @@ static void sp_3072_mont_norm_96(sp_digit* r, const sp_digit* m) * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_cond_sub_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_3072_cond_sub_96(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -17287,7 +17418,7 @@ static sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a, const sp_dig "MOV %[r], r4\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -17302,9 +17433,11 @@ static sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a, const sp_dig * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_cond_sub_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_3072_cond_sub_96(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -17655,7 +17788,7 @@ static sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a, const sp_dig "SBC %[r], r5, r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)r; } @@ -17670,9 +17803,11 @@ static sp_digit sp_3072_cond_sub_96(sp_digit* r, const sp_digit* a, const sp_dig * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -18480,7 +18615,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, s "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_3072_cond_sub_96(a - 96, a, m, (sp_digit)0 - mp); } @@ -18493,9 +18629,11 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, s * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -18598,7 +18736,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, s "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); sp_3072_cond_sub_96(a - 96, a, m, (sp_digit)0 - mp); } @@ -18613,9 +18752,11 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, s * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -19141,7 +19282,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, s "MOV %[mp], r5\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_3072_cond_sub_96(a - 96, a, m, (sp_digit)0 - mp); } @@ -19154,9 +19296,11 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, s * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -19247,7 +19391,8 @@ SP_NOINLINE static void sp_3072_mont_reduce_96(sp_digit* a, const sp_digit* m, s "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); sp_3072_cond_sub_96(a - 96, a, m, (sp_digit)0 - mp); } @@ -19292,9 +19437,11 @@ SP_NOINLINE static void sp_3072_mont_sqr_96(sp_digit* r, const sp_digit* a, * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_sub_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_3072_sub_96(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_3072_sub_96(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_3072_sub_96(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -19332,7 +19479,8 @@ static sp_digit sp_3072_sub_96(sp_digit* r, const sp_digit* a, const sp_digit* b "MOV %[r], r11\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); return (word32)(size_t)r; } @@ -19345,9 +19493,11 @@ static sp_digit sp_3072_sub_96(sp_digit* r, const sp_digit* a, const sp_digit* b * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_sub_96(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_3072_sub_96(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_3072_sub_96(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_3072_sub_96(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -19528,7 +19678,7 @@ static sp_digit sp_3072_sub_96(sp_digit* r, const sp_digit* a, const sp_digit* b "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -19545,9 +19695,11 @@ static sp_digit sp_3072_sub_96(sp_digit* r, const sp_digit* a, const sp_digit* b * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -19594,7 +19746,7 @@ SP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1, sp_digit d0, sp_digit "ADD %[d1], r6, r3\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -19610,9 +19762,11 @@ SP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1, sp_digit d0, sp_digit * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -19676,7 +19830,7 @@ SP_NOINLINE static sp_digit div_3072_word_96(sp_digit d1, sp_digit d0, sp_digit "SUB %[d1], r3, r8\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -20896,7 +21050,7 @@ static sp_int32 sp_3072_cmp_96(const sp_digit* a, const sp_digit* b) "MOV %[a], r2\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)a; } @@ -21427,9 +21581,11 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, const mp_int* em, * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_cond_add_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_3072_cond_add_48(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_3072_cond_add_48(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_3072_cond_add_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -21468,7 +21624,7 @@ static sp_digit sp_3072_cond_add_48(sp_digit* r, const sp_digit* a, const sp_dig "MOV %[r], r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -21483,9 +21639,11 @@ static sp_digit sp_3072_cond_add_48(sp_digit* r, const sp_digit* a, const sp_dig * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_3072_cond_add_48(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_3072_cond_add_48(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_3072_cond_add_48(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_3072_cond_add_48(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -21668,7 +21826,7 @@ static sp_digit sp_3072_cond_add_48(sp_digit* r, const sp_digit* a, const sp_dig "ADC %[r], r10, r10\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -22580,7 +22738,7 @@ static void sp_3072_lshift_96(sp_digit* r, const sp_digit* a, byte n) "STR r4, [%[r], #4]\n\t" : [r] "+r" (r), [a] "+r" (a), [n] "+r" (n) : - : "memory", "r4", "r5", "r6", "r3", "r7", "cc" + : "memory", "cc", "r4", "r5", "r6", "r3", "r7" ); } @@ -22867,9 +23025,9 @@ static void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -23246,7 +23404,7 @@ static sp_digit sp_4096_sub_in_place_128(sp_digit* a, const sp_digit* b) "SBC %[a], r9, r9\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; } @@ -23258,9 +23416,11 @@ static sp_digit sp_4096_sub_in_place_128(sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_4096_add_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_4096_add_128(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -23498,7 +23658,7 @@ static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a, const sp_digit* "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -23587,9 +23747,11 @@ SP_NOINLINE static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_4096_add_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_4096_add_128(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -23628,7 +23790,8 @@ static sp_digit sp_4096_add_128(sp_digit* r, const sp_digit* a, const sp_digit* "MOV %[r], r3\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); return (word32)(size_t)r; } @@ -23680,7 +23843,8 @@ static sp_digit sp_4096_sub_in_place_128(sp_digit* a, const sp_digit* b) "MOV %[a], r10\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11" ); return (word32)(size_t)a; } @@ -23694,7 +23858,8 @@ static sp_digit sp_4096_sub_in_place_128(sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_4096_mul_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static void sp_4096_mul_128(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static void sp_4096_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -23808,7 +23973,8 @@ static void sp_4096_mul_128(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -23925,7 +24091,8 @@ static void sp_4096_sqr_128(sp_digit* r, const sp_digit* a) #endif : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -24005,7 +24172,7 @@ static void sp_4096_mul_d_128(sp_digit* r, const sp_digit* a, sp_digit b) "STR r3, [%[r], #512]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -24671,7 +24838,7 @@ static void sp_4096_mul_d_128(sp_digit* r, const sp_digit* a, sp_digit b) "STR r5, [%[r]]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -24702,9 +24869,11 @@ static void sp_4096_mont_norm_128(sp_digit* r, const sp_digit* m) * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_4096_cond_sub_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_4096_cond_sub_128(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -24743,7 +24912,7 @@ static sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a, const sp_di "MOV %[r], r4\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -24758,9 +24927,11 @@ static sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a, const sp_di * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_4096_cond_sub_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_4096_cond_sub_128(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -25223,7 +25394,7 @@ static sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a, const sp_di "SBC %[r], r5, r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)r; } @@ -25238,9 +25409,11 @@ static sp_digit sp_4096_cond_sub_128(sp_digit* r, const sp_digit* a, const sp_di * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -26304,7 +26477,8 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_4096_cond_sub_128(a - 128, a, m, (sp_digit)0 - mp); } @@ -26317,9 +26491,11 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -26422,7 +26598,8 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); sp_4096_cond_sub_128(a - 128, a, m, (sp_digit)0 - mp); } @@ -26437,9 +26614,11 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -27125,7 +27304,8 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "MOV %[mp], r5\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_4096_cond_sub_128(a - 128, a, m, (sp_digit)0 - mp); } @@ -27138,9 +27318,11 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -27231,7 +27413,8 @@ SP_NOINLINE static void sp_4096_mont_reduce_128(sp_digit* a, const sp_digit* m, "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); sp_4096_cond_sub_128(a - 128, a, m, (sp_digit)0 - mp); } @@ -27276,9 +27459,11 @@ SP_NOINLINE static void sp_4096_mont_sqr_128(sp_digit* r, const sp_digit* a, * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_4096_sub_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_4096_sub_128(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_4096_sub_128(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_4096_sub_128(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -27316,7 +27501,8 @@ static sp_digit sp_4096_sub_128(sp_digit* r, const sp_digit* a, const sp_digit* "MOV %[r], r11\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); return (word32)(size_t)r; } @@ -27329,9 +27515,11 @@ static sp_digit sp_4096_sub_128(sp_digit* r, const sp_digit* a, const sp_digit* * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_4096_sub_128(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_4096_sub_128(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_4096_sub_128(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_4096_sub_128(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -27568,7 +27756,7 @@ static sp_digit sp_4096_sub_128(sp_digit* r, const sp_digit* a, const sp_digit* "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -27585,9 +27773,11 @@ static sp_digit sp_4096_sub_128(sp_digit* r, const sp_digit* a, const sp_digit* * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -27634,7 +27824,7 @@ SP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1, sp_digit d0, sp_digit "ADD %[d1], r6, r3\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -27650,9 +27840,11 @@ SP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1, sp_digit d0, sp_digit * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -27716,7 +27908,7 @@ SP_NOINLINE static sp_digit div_4096_word_128(sp_digit d1, sp_digit d0, sp_digit "SUB %[d1], r3, r8\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -29288,7 +29480,7 @@ static sp_int32 sp_4096_cmp_128(const sp_digit* a, const sp_digit* b) "MOV %[a], r2\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)a; } @@ -29819,9 +30011,11 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, const mp_int* em, * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_4096_cond_add_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_4096_cond_add_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_4096_cond_add_64(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_4096_cond_add_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -29860,7 +30054,7 @@ static sp_digit sp_4096_cond_add_64(sp_digit* r, const sp_digit* a, const sp_dig "MOV %[r], r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -29875,9 +30069,11 @@ static sp_digit sp_4096_cond_add_64(sp_digit* r, const sp_digit* a, const sp_dig * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_4096_cond_add_64(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_4096_cond_add_64(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_4096_cond_add_64(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_4096_cond_add_64(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -30116,7 +30312,7 @@ static sp_digit sp_4096_cond_add_64(sp_digit* r, const sp_digit* a, const sp_dig "ADC %[r], r10, r10\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -31220,7 +31416,7 @@ static void sp_4096_lshift_128(sp_digit* r, const sp_digit* a, byte n) "STR r5, [%[r], #4]\n\t" : [r] "+r" (r), [a] "+r" (a), [n] "+r" (n) : - : "memory", "r4", "r5", "r6", "r3", "r7", "cc" + : "memory", "cc", "r4", "r5", "r6", "r3", "r7" ); } @@ -31513,7 +31709,8 @@ static const sp_digit p256_b[8] = { * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -31627,7 +31824,8 @@ static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -31640,9 +31838,11 @@ static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +SP_NOINLINE static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -SP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +SP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -31987,7 +32187,8 @@ SP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_di "ADD sp, sp, #0x24\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); } @@ -31999,9 +32200,11 @@ SP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_di * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +SP_NOINLINE static void sp_256_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -SP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b) +SP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -32124,7 +32327,8 @@ SP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a, const sp_di "ADD sp, sp, #0x2c\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r10", "r11", "r12", "r7", "r8", "r9", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r10", "r11", "r12", "r7", + "r8", "r9", "lr" ); } @@ -32244,7 +32448,8 @@ static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) #endif : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -32494,7 +32699,8 @@ SP_NOINLINE static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) "ADD sp, sp, #0x44\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); } @@ -32611,7 +32817,8 @@ SP_NOINLINE static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) "ADD sp, sp, #0x20\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); } @@ -32625,7 +32832,8 @@ SP_NOINLINE static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_256_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_256_add_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -32666,7 +32874,8 @@ static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "MOV %[r], r3\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); return (word32)(size_t)r; } @@ -32679,7 +32888,8 @@ static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_256_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_256_add_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -32709,7 +32919,7 @@ static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -32722,9 +32932,11 @@ static sp_digit sp_256_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b) * m The modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static int sp_256_mod_mul_norm_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +static int sp_256_mod_mul_norm_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) #else -static int sp_256_mod_mul_norm_8(sp_digit* r, const sp_digit* a, const sp_digit* m) +static int sp_256_mod_mul_norm_8(sp_digit* r, const sp_digit* a, + const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -32951,7 +33163,8 @@ static int sp_256_mod_mul_norm_8(sp_digit* r, const sp_digit* a, const sp_digit* "ADD sp, sp, #0x18\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -33167,9 +33380,11 @@ static int sp_256_point_to_ecc_point_8(const sp_point_256* p, ecc_point* pm) * mp Montgomery multiplier. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -33633,7 +33848,8 @@ SP_NOINLINE static void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, const "ADD sp, sp, #0x44\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -33658,9 +33874,11 @@ SP_NOINLINE static void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, const * mp Montgomery multiplier. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_256_mont_mul_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m, sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -33902,7 +34120,8 @@ SP_NOINLINE static void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, const "ADD sp, sp, #0x4c\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r10", "r11", "r12", "r7", "r8", "r9", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r10", "r11", "r12", "r7", + "r8", "r9", "lr" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -33926,9 +34145,11 @@ SP_NOINLINE static void sp_256_mont_mul_8(sp_digit* r, const sp_digit* a, const * mp Montgomery multiplier. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -34283,7 +34504,8 @@ SP_NOINLINE static void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, const "ADD sp, sp, #0x44\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -34306,9 +34528,11 @@ SP_NOINLINE static void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, const * mp Montgomery multiplier. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_256_mont_sqr_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, + const sp_digit* m, sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -34532,7 +34756,8 @@ SP_NOINLINE static void sp_256_mont_sqr_8(sp_digit* r, const sp_digit* a, const "ADD sp, sp, #0x44\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -34786,7 +35011,7 @@ static sp_int32 sp_256_cmp_8(const sp_digit* a, const sp_digit* b) "MOV %[a], r2\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)a; } @@ -34807,9 +35032,11 @@ static sp_int32 sp_256_cmp_8(const sp_digit* a, const sp_digit* b) * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_256_cond_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_256_cond_sub_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -34848,7 +35075,7 @@ static sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a, const sp_digit "MOV %[r], r4\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -34863,9 +35090,11 @@ static sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a, const sp_digit * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_256_cond_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_256_cond_sub_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -34908,7 +35137,7 @@ static sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a, const sp_digit "SBC %[r], r5, r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)r; } @@ -34925,9 +35154,11 @@ static sp_digit sp_256_cond_sub_8(sp_digit* r, const sp_digit* a, const sp_digit * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, + sp_digit mp_p) #else -SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -35031,7 +35262,8 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, sp_ "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - mp); } @@ -35044,9 +35276,11 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, sp_ * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, + sp_digit mp_p) #else -SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -35132,7 +35366,8 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, sp_ "MOV %[mp], r5\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - mp); } @@ -35146,9 +35381,11 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, sp_ * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a_p, const sp_digit* m_p, + sp_digit mp_p) #else -SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -35289,7 +35526,8 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, sp_ "ADD sp, sp, #0x44\n\t" : [a] "+r" (a) : - : "memory", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "lr" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -35311,9 +35549,11 @@ SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, sp_ * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a, + const sp_digit* m, sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -35417,7 +35657,8 @@ SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a, const sp_digit* "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - mp); } @@ -35430,9 +35671,11 @@ SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a, const sp_digit* * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a, + const sp_digit* m, sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -35518,7 +35761,8 @@ SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a, const sp_digit* "MOV %[mp], r5\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - mp); } @@ -35573,9 +35817,11 @@ static void sp_256_map_8(sp_point_256* r, const sp_point_256* p, * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_add_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, const sp_digit* m_p) +SP_NOINLINE static void sp_256_mont_add_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) #else -SP_NOINLINE static void sp_256_mont_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m) +SP_NOINLINE static void sp_256_mont_add_8(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -35622,7 +35868,8 @@ SP_NOINLINE static void sp_256_mont_add_8(sp_digit* r, const sp_digit* a, const "STM %[r], {r5, r6, r7, r8, r9, r10, r11, r12}\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -35638,9 +35885,11 @@ SP_NOINLINE static void sp_256_mont_add_8(sp_digit* r, const sp_digit* a, const * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_dbl_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +SP_NOINLINE static void sp_256_mont_dbl_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) #else -SP_NOINLINE static void sp_256_mont_dbl_8(sp_digit* r, const sp_digit* a, const sp_digit* m) +SP_NOINLINE static void sp_256_mont_dbl_8(sp_digit* r, const sp_digit* a, + const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -35682,7 +35931,8 @@ SP_NOINLINE static void sp_256_mont_dbl_8(sp_digit* r, const sp_digit* a, const "STM %[r], {r4, r5, r6, r7, r8, r9, r10, r11}\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r2", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r2" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -35698,9 +35948,11 @@ SP_NOINLINE static void sp_256_mont_dbl_8(sp_digit* r, const sp_digit* a, const * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_tpl_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +SP_NOINLINE static void sp_256_mont_tpl_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) #else -SP_NOINLINE static void sp_256_mont_tpl_8(sp_digit* r, const sp_digit* a, const sp_digit* m) +SP_NOINLINE static void sp_256_mont_tpl_8(sp_digit* r, const sp_digit* a, + const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -35774,7 +36026,8 @@ SP_NOINLINE static void sp_256_mont_tpl_8(sp_digit* r, const sp_digit* a, const "STM %[r], {r4, r5, r6, r7, r8, r9, r10, r11}\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r2", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r2", "r3", "r12" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -35791,9 +36044,11 @@ SP_NOINLINE static void sp_256_mont_tpl_8(sp_digit* r, const sp_digit* a, const * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, const sp_digit* m_p) +SP_NOINLINE static void sp_256_mont_sub_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) #else -SP_NOINLINE static void sp_256_mont_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m) +SP_NOINLINE static void sp_256_mont_sub_8(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -35838,7 +36093,8 @@ SP_NOINLINE static void sp_256_mont_sub_8(sp_digit* r, const sp_digit* a, const "STM %[r], {r5, r6, r7, r8, r9, r10, r11, r12}\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -35854,9 +36110,11 @@ SP_NOINLINE static void sp_256_mont_sub_8(sp_digit* r, const sp_digit* a, const * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_256_mont_div2_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +SP_NOINLINE static void sp_256_mont_div2_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) #else -SP_NOINLINE static void sp_256_mont_div2_8(sp_digit* r, const sp_digit* a, const sp_digit* m) +SP_NOINLINE static void sp_256_mont_div2_8(sp_digit* r, const sp_digit* a, + const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -35905,7 +36163,8 @@ SP_NOINLINE static void sp_256_mont_div2_8(sp_digit* r, const sp_digit* a, const "STM %[r], {r8, r9, r10, r11}\n\t" : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3" ); } @@ -39436,7 +39695,7 @@ static void sp_256_add_one_8(sp_digit* a) "STM %[a]!, {r1, r2, r3, r4}\n\t" : [a] "+r" (a) : - : "memory", "r1", "r2", "r3", "r4", "cc" + : "memory", "cc", "r1", "r2", "r3", "r4" ); } @@ -39474,9 +39733,9 @@ static void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -39865,7 +40124,8 @@ static sp_digit sp_256_sub_in_place_8(sp_digit* a, const sp_digit* b) "MOV %[a], r10\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11" ); return (word32)(size_t)a; } @@ -39905,7 +40165,7 @@ static sp_digit sp_256_sub_in_place_8(sp_digit* a, const sp_digit* b) "SBC %[a], r9, r9\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; } @@ -39966,7 +40226,7 @@ static void sp_256_mul_d_8(sp_digit* r, const sp_digit* a, sp_digit b) "STR r3, [%[r], #32]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -40032,7 +40292,7 @@ static void sp_256_mul_d_8(sp_digit* r, const sp_digit* a, sp_digit b) "STR r5, [%[r]]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -40048,9 +40308,11 @@ static void sp_256_mul_d_8(sp_digit* r, const sp_digit* a, sp_digit b) * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_256_word_8(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_256_word_8(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_256_word_8(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_256_word_8(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -40097,7 +40359,7 @@ SP_NOINLINE static sp_digit div_256_word_8(sp_digit d1, sp_digit d0, sp_digit di "ADD %[d1], r6, r3\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -40113,9 +40375,11 @@ SP_NOINLINE static sp_digit div_256_word_8(sp_digit d1, sp_digit d0, sp_digit di * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_256_word_8(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_256_word_8(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_256_word_8(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_256_word_8(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -40179,7 +40443,7 @@ SP_NOINLINE static sp_digit div_256_word_8(sp_digit d1, sp_digit d0, sp_digit di "SUB %[d1], r3, r8\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -40838,7 +41102,8 @@ int sp_ecc_sign_256_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_256_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_256_sub_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -40878,7 +41143,8 @@ static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "MOV %[r], r11\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); return (word32)(size_t)r; } @@ -40891,7 +41157,8 @@ static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_256_sub_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_256_sub_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -40920,7 +41187,7 @@ static sp_digit sp_256_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b) "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -40966,7 +41233,8 @@ static void sp_256_rshift1_8(sp_digit* r, const sp_digit* a) "STRD r8, r9, [%[r], #8]\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); } @@ -40977,7 +41245,8 @@ static void sp_256_rshift1_8(sp_digit* r, const sp_digit* a) * m Modulus. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_256_div2_mod_8(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +static void sp_256_div2_mod_8(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) #else static void sp_256_div2_mod_8(sp_digit* r, const sp_digit* a, const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -41058,7 +41327,8 @@ static void sp_256_div2_mod_8(sp_digit* r, const sp_digit* a, const sp_digit* m) "STM %[r], {r8, r9, r10, r11}\n\t" : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); } @@ -41261,7 +41531,7 @@ static int sp_256_num_bits_8(const sp_digit* a) "MOV %[a], r4\n\t" : [a] "+r" (a) : - : "memory", "r1", "r2", "r3", "r4", "r5", "cc" + : "memory", "cc", "r1", "r2", "r3", "r4", "r5" ); return (word32)(size_t)a; } @@ -42345,7 +42615,8 @@ static const sp_digit p384_b[12] = { * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_384_mul_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static void sp_384_mul_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -42459,7 +42730,8 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -42471,7 +42743,8 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_384_mul_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static void sp_384_mul_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -43487,7 +43760,8 @@ static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "STM %[r]!, {r3, r4, r5, r6}\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", + "r12" ); } @@ -43606,7 +43880,8 @@ static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) #endif : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -44307,7 +44582,8 @@ static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) "STM %[r]!, {r2, r3, r4, r8}\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r12" ); } @@ -44320,7 +44596,8 @@ static void sp_384_sqr_12(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_384_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_384_add_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -44361,7 +44638,8 @@ static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "MOV %[r], r3\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); return (word32)(size_t)r; } @@ -44374,7 +44652,8 @@ static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_384_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_384_add_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -44411,7 +44690,7 @@ static sp_digit sp_384_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -44723,9 +45002,11 @@ static int sp_384_point_to_ecc_point_12(const sp_point_384* p, ecc_point* pm) * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_384_cond_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_384_cond_sub_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_384_cond_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_384_cond_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -44764,7 +45045,7 @@ static sp_digit sp_384_cond_sub_12(sp_digit* r, const sp_digit* a, const sp_digi "MOV %[r], r4\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -44779,9 +45060,11 @@ static sp_digit sp_384_cond_sub_12(sp_digit* r, const sp_digit* a, const sp_digi * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_384_cond_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_384_cond_sub_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_384_cond_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_384_cond_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -44838,7 +45121,7 @@ static sp_digit sp_384_cond_sub_12(sp_digit* r, const sp_digit* a, const sp_digi "SBC %[r], r5, r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)r; } @@ -44854,9 +45137,11 @@ static sp_digit sp_384_cond_sub_12(sp_digit* r, const sp_digit* a, const sp_digi * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -44992,7 +45277,8 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, sp "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_384_cond_sub_12(a - 12, a, m, (sp_digit)0 - mp); } @@ -45005,9 +45291,11 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, sp * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -45113,7 +45401,8 @@ SP_NOINLINE static void sp_384_mont_reduce_12(sp_digit* a, const sp_digit* m, sp "MOV %[mp], r5\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_384_cond_sub_12(a - 12, a, m, (sp_digit)0 - mp); } @@ -45448,7 +45737,7 @@ static sp_int32 sp_384_cmp_12(const sp_digit* a, const sp_digit* b) "MOV %[a], r2\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)a; } @@ -45507,9 +45796,11 @@ static void sp_384_map_12(sp_point_384* r, const sp_point_384* p, * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_384_mont_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, const sp_digit* m_p) +SP_NOINLINE static void sp_384_mont_add_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) #else -SP_NOINLINE static void sp_384_mont_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m) +SP_NOINLINE static void sp_384_mont_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -45532,9 +45823,11 @@ SP_NOINLINE static void sp_384_mont_add_12(sp_digit* r, const sp_digit* a, const * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_384_mont_dbl_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +SP_NOINLINE static void sp_384_mont_dbl_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) #else -SP_NOINLINE static void sp_384_mont_dbl_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +SP_NOINLINE static void sp_384_mont_dbl_12(sp_digit* r, const sp_digit* a, + const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -45556,9 +45849,11 @@ SP_NOINLINE static void sp_384_mont_dbl_12(sp_digit* r, const sp_digit* a, const * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_384_mont_tpl_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +SP_NOINLINE static void sp_384_mont_tpl_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) #else -SP_NOINLINE static void sp_384_mont_tpl_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +SP_NOINLINE static void sp_384_mont_tpl_12(sp_digit* r, const sp_digit* a, + const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -45583,7 +45878,8 @@ SP_NOINLINE static void sp_384_mont_tpl_12(sp_digit* r, const sp_digit* a, const * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_384_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_384_sub_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -45623,7 +45919,8 @@ static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "MOV %[r], r11\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); return (word32)(size_t)r; } @@ -45636,7 +45933,8 @@ static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_384_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_384_sub_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -45672,7 +45970,7 @@ static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b) "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -45688,9 +45986,11 @@ static sp_digit sp_384_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b) * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_384_cond_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_384_cond_add_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -45729,7 +46029,7 @@ static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, const sp_digi "MOV %[r], r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -45744,9 +46044,11 @@ static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, const sp_digi * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_384_cond_add_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_384_cond_add_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -45803,7 +46105,7 @@ static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, const sp_digi "ADC %[r], r10, r10\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -45817,9 +46119,11 @@ static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, const sp_digi * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_384_mont_sub_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, const sp_digit* m_p) +SP_NOINLINE static void sp_384_mont_sub_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) #else -SP_NOINLINE static void sp_384_mont_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m) +SP_NOINLINE static void sp_384_mont_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -45898,7 +46202,7 @@ static void sp_384_rshift1_12(sp_digit* r, const sp_digit* a) "STR r4, [%[r], #44]\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r2", "r3", "r4", "cc" + : "memory", "cc", "r2", "r3", "r4" ); } @@ -49508,7 +49812,7 @@ static void sp_384_add_one_12(sp_digit* a) "STM %[a]!, {r1, r2, r3, r4}\n\t" : [a] "+r" (a) : - : "memory", "r1", "r2", "r3", "r4", "cc" + : "memory", "cc", "r1", "r2", "r3", "r4" ); } @@ -49546,9 +49850,9 @@ static void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -49937,7 +50241,8 @@ static sp_digit sp_384_sub_in_place_12(sp_digit* a, const sp_digit* b) "MOV %[a], r10\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11" ); return (word32)(size_t)a; } @@ -49984,7 +50289,7 @@ static sp_digit sp_384_sub_in_place_12(sp_digit* a, const sp_digit* b) "SBC %[a], r9, r9\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; } @@ -50045,7 +50350,7 @@ static void sp_384_mul_d_12(sp_digit* r, const sp_digit* a, sp_digit b) "STR r3, [%[r], #48]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -50131,7 +50436,7 @@ static void sp_384_mul_d_12(sp_digit* r, const sp_digit* a, sp_digit b) "STR r3, [%[r]]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -50147,9 +50452,11 @@ static void sp_384_mul_d_12(sp_digit* r, const sp_digit* a, sp_digit b) * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_384_word_12(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_384_word_12(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_384_word_12(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_384_word_12(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -50196,7 +50503,7 @@ SP_NOINLINE static sp_digit div_384_word_12(sp_digit d1, sp_digit d0, sp_digit d "ADD %[d1], r6, r3\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -50212,9 +50519,11 @@ SP_NOINLINE static sp_digit div_384_word_12(sp_digit d1, sp_digit d0, sp_digit d * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_384_word_12(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_384_word_12(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_384_word_12(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_384_word_12(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -50278,7 +50587,7 @@ SP_NOINLINE static sp_digit div_384_word_12(sp_digit d1, sp_digit d0, sp_digit d "SUB %[d1], r3, r8\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -50907,9 +51216,11 @@ int sp_ecc_sign_384_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W * m Modulus. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_384_div2_mod_12(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +static void sp_384_div2_mod_12(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) #else -static void sp_384_div2_mod_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +static void sp_384_div2_mod_12(sp_digit* r, const sp_digit* a, + const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -51026,7 +51337,8 @@ static void sp_384_div2_mod_12(sp_digit* r, const sp_digit* a, const sp_digit* m "STR r10, [%[r], #44]\n\t" : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); } @@ -51329,7 +51641,7 @@ static int sp_384_num_bits_12(const sp_digit* a) "MOV %[a], r4\n\t" : [a] "+r" (a) : - : "memory", "r1", "r2", "r3", "r4", "r5", "cc" + : "memory", "cc", "r1", "r2", "r3", "r4", "r5" ); return (word32)(size_t)a; } @@ -52459,7 +52771,8 @@ static const sp_digit p521_b[17] = { * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_521_mul_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static void sp_521_mul_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static void sp_521_mul_17(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -52576,7 +52889,8 @@ static void sp_521_mul_17(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -52588,7 +52902,8 @@ static void sp_521_mul_17(sp_digit* r, const sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_521_mul_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static void sp_521_mul_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static void sp_521_mul_17(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -54618,7 +54933,8 @@ static void sp_521_mul_17(sp_digit* r, const sp_digit* a, const sp_digit* b) "STM %[r]!, {r3}\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", + "r12" ); } @@ -54740,7 +55056,8 @@ static void sp_521_sqr_17(sp_digit* r, const sp_digit* a) #endif : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -56025,7 +56342,8 @@ static void sp_521_sqr_17(sp_digit* r, const sp_digit* a) "STM %[r]!, {r2}\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r12" ); } @@ -56038,7 +56356,8 @@ static void sp_521_sqr_17(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_521_add_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_521_add_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_521_add_17(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -56085,7 +56404,8 @@ static sp_digit sp_521_add_17(sp_digit* r, const sp_digit* a, const sp_digit* b) "ADC %[r], r4, #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); return (word32)(size_t)r; } @@ -56098,7 +56418,8 @@ static sp_digit sp_521_add_17(sp_digit* r, const sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_521_add_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_521_add_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_521_add_17(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -56146,7 +56467,7 @@ static sp_digit sp_521_add_17(sp_digit* r, const sp_digit* a, const sp_digit* b) "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -56375,9 +56696,11 @@ static int sp_521_point_to_ecc_point_17(const sp_point_521* p, ecc_point* pm) * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_521_cond_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_521_cond_sub_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_521_cond_sub_17(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_521_cond_sub_17(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -56416,7 +56739,7 @@ static sp_digit sp_521_cond_sub_17(sp_digit* r, const sp_digit* a, const sp_digi "MOV %[r], r4\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -56431,9 +56754,11 @@ static sp_digit sp_521_cond_sub_17(sp_digit* r, const sp_digit* a, const sp_digi * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_521_cond_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_521_cond_sub_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_521_cond_sub_17(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_521_cond_sub_17(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -56509,7 +56834,7 @@ static sp_digit sp_521_cond_sub_17(sp_digit* r, const sp_digit* a, const sp_digi "SBC %[r], r5, r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)r; } @@ -56522,9 +56847,11 @@ static sp_digit sp_521_cond_sub_17(sp_digit* r, const sp_digit* a, const sp_digi * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_521_mont_reduce_17(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_521_mont_reduce_17(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_521_mont_reduce_17(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_521_mont_reduce_17(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -56637,7 +56964,8 @@ SP_NOINLINE static void sp_521_mont_reduce_17(sp_digit* a, const sp_digit* m, sp "STM %[a]!, {r1, r2, r3, r4, r5, r6, r7, r8}\n\t" : [a] "+r" (a) : - : "memory", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", + "r10", "r11", "r12", "lr" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -56659,9 +56987,11 @@ SP_NOINLINE static void sp_521_mont_reduce_17(sp_digit* a, const sp_digit* m, sp * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_521_mont_reduce_order_17(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_521_mont_reduce_order_17(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_521_mont_reduce_order_17(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_521_mont_reduce_order_17(sp_digit* a, + const sp_digit* m, sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -56924,7 +57254,8 @@ SP_NOINLINE static void sp_521_mont_reduce_order_17(sp_digit* a, const sp_digit* "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_521_cond_sub_17(a - 17, a, m, (sp_digit)0 - mp); } @@ -56937,9 +57268,11 @@ SP_NOINLINE static void sp_521_mont_reduce_order_17(sp_digit* a, const sp_digit* * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_521_mont_reduce_order_17(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_521_mont_reduce_order_17(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_521_mont_reduce_order_17(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_521_mont_reduce_order_17(sp_digit* a, + const sp_digit* m, sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -57157,7 +57490,8 @@ SP_NOINLINE static void sp_521_mont_reduce_order_17(sp_digit* a, const sp_digit* "MOV %[mp], r5\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_521_cond_sub_17(a - 17, a, m, (sp_digit)0 - mp); } @@ -57544,7 +57878,7 @@ static sp_int32 sp_521_cmp_17(const sp_digit* a, const sp_digit* b) "MOV %[a], r2\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)a; } @@ -57603,9 +57937,11 @@ static void sp_521_map_17(sp_point_521* r, const sp_point_521* p, * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_521_mont_add_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, const sp_digit* m_p) +SP_NOINLINE static void sp_521_mont_add_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) #else -SP_NOINLINE static void sp_521_mont_add_17(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m) +SP_NOINLINE static void sp_521_mont_add_17(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -57677,7 +58013,8 @@ SP_NOINLINE static void sp_521_mont_add_17(sp_digit* r, const sp_digit* a, const "STM %[r]!, {r4}\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -57693,9 +58030,11 @@ SP_NOINLINE static void sp_521_mont_add_17(sp_digit* r, const sp_digit* a, const * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_521_mont_dbl_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +SP_NOINLINE static void sp_521_mont_dbl_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) #else -SP_NOINLINE static void sp_521_mont_dbl_17(sp_digit* r, const sp_digit* a, const sp_digit* m) +SP_NOINLINE static void sp_521_mont_dbl_17(sp_digit* r, const sp_digit* a, + const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -57757,7 +58096,8 @@ SP_NOINLINE static void sp_521_mont_dbl_17(sp_digit* r, const sp_digit* a, const "STM %[r]!, {r4}\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r2", "r3", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r2", "r3" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -57773,9 +58113,11 @@ SP_NOINLINE static void sp_521_mont_dbl_17(sp_digit* r, const sp_digit* a, const * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_521_mont_tpl_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +SP_NOINLINE static void sp_521_mont_tpl_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) #else -SP_NOINLINE static void sp_521_mont_tpl_17(sp_digit* r, const sp_digit* a, const sp_digit* m) +SP_NOINLINE static void sp_521_mont_tpl_17(sp_digit* r, const sp_digit* a, + const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -57857,7 +58199,8 @@ SP_NOINLINE static void sp_521_mont_tpl_17(sp_digit* r, const sp_digit* a, const "STM %[r]!, {r4}\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r2", "r3", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r2", "r3" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -57874,9 +58217,11 @@ SP_NOINLINE static void sp_521_mont_tpl_17(sp_digit* r, const sp_digit* a, const * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_521_mont_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, const sp_digit* m_p) +SP_NOINLINE static void sp_521_mont_sub_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) #else -SP_NOINLINE static void sp_521_mont_sub_17(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m) +SP_NOINLINE static void sp_521_mont_sub_17(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -57949,7 +58294,8 @@ SP_NOINLINE static void sp_521_mont_sub_17(sp_digit* r, const sp_digit* a, const "STM %[r]!, {r4}\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); #ifndef WOLFSSL_NO_VAR_ASSIGN_REG (void)m_p; @@ -58038,7 +58384,7 @@ static void sp_521_rshift1_17(sp_digit* r, const sp_digit* a) "STR r3, [%[r], #64]\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r2", "r3", "r4", "cc" + : "memory", "cc", "r2", "r3", "r4" ); } @@ -62279,7 +62625,7 @@ static void sp_521_add_one_17(sp_digit* a) "STM %[a]!, {r1}\n\t" : [a] "+r" (a) : - : "memory", "r1", "r2", "r3", "r4", "cc" + : "memory", "cc", "r1", "r2", "r3", "r4" ); } @@ -62317,9 +62663,9 @@ static void sp_521_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; @@ -62758,7 +63104,7 @@ static void sp_521_rshift_17(sp_digit* r, const sp_digit* a, byte n) "STRD r4, r5, [%[r], #60]\n\t" : [r] "+r" (r), [a] "+r" (a), [n] "+r" (n) : - : "memory", "r4", "r5", "r6", "r3", "r7", "cc" + : "memory", "cc", "r4", "r5", "r6", "r3", "r7" ); } @@ -62884,7 +63230,7 @@ static void sp_521_lshift_17(sp_digit* r, const sp_digit* a, byte n) "STR r5, [%[r], #4]\n\t" : [r] "+r" (r), [a] "+r" (a), [n] "+r" (n) : - : "memory", "r4", "r5", "r6", "r3", "r7", "cc" + : "memory", "cc", "r4", "r5", "r6", "r3", "r7" ); } @@ -63108,7 +63454,7 @@ static void sp_521_lshift_34(sp_digit* r, const sp_digit* a, byte n) "STR r6, [%[r], #4]\n\t" : [r] "+r" (r), [a] "+r" (a), [n] "+r" (n) : - : "memory", "r4", "r5", "r6", "r3", "r7", "cc" + : "memory", "cc", "r4", "r5", "r6", "r3", "r7" ); } @@ -63163,7 +63509,8 @@ static sp_digit sp_521_sub_in_place_17(sp_digit* a, const sp_digit* b) "SBC %[a], %[a], %[a]\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11" ); return (word32)(size_t)a; } @@ -63221,7 +63568,7 @@ static sp_digit sp_521_sub_in_place_17(sp_digit* a, const sp_digit* b) "SBC %[a], r9, r9\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; } @@ -63282,7 +63629,7 @@ static void sp_521_mul_d_17(sp_digit* r, const sp_digit* a, sp_digit b) "STR r3, [%[r], #68]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -63393,7 +63740,7 @@ static void sp_521_mul_d_17(sp_digit* r, const sp_digit* a, sp_digit b) "STR r5, [%[r]]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -63409,9 +63756,11 @@ static void sp_521_mul_d_17(sp_digit* r, const sp_digit* a, sp_digit b) * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_521_word_17(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_521_word_17(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_521_word_17(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_521_word_17(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -63458,7 +63807,7 @@ SP_NOINLINE static sp_digit div_521_word_17(sp_digit d1, sp_digit d0, sp_digit d "ADD %[d1], r6, r3\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -63474,9 +63823,11 @@ SP_NOINLINE static sp_digit div_521_word_17(sp_digit d1, sp_digit d0, sp_digit d * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_521_word_17(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_521_word_17(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_521_word_17(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_521_word_17(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -63540,7 +63891,7 @@ SP_NOINLINE static sp_digit div_521_word_17(sp_digit d1, sp_digit d0, sp_digit d "SUB %[d1], r3, r8\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -64200,7 +64551,8 @@ int sp_ecc_sign_521_nb(sp_ecc_ctx_t* sp_ctx, const byte* hash, word32 hashLen, W * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_521_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_521_sub_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_521_sub_17(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -64245,7 +64597,8 @@ static sp_digit sp_521_sub_17(sp_digit* r, const sp_digit* a, const sp_digit* b) "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12" ); return (word32)(size_t)r; } @@ -64258,7 +64611,8 @@ static sp_digit sp_521_sub_17(sp_digit* r, const sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_521_sub_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_521_sub_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static sp_digit sp_521_sub_17(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -64305,7 +64659,7 @@ static sp_digit sp_521_sub_17(sp_digit* r, const sp_digit* a, const sp_digit* b) "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -64318,9 +64672,11 @@ static sp_digit sp_521_sub_17(sp_digit* r, const sp_digit* a, const sp_digit* b) * m Modulus. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_521_div2_mod_17(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +static void sp_521_div2_mod_17(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) #else -static void sp_521_div2_mod_17(sp_digit* r, const sp_digit* a, const sp_digit* m) +static void sp_521_div2_mod_17(sp_digit* r, const sp_digit* a, + const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -64472,7 +64828,8 @@ static void sp_521_div2_mod_17(sp_digit* r, const sp_digit* a, const sp_digit* m "STR r9, [%[r], #64]\n\t" : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); } @@ -64900,7 +65257,7 @@ static int sp_521_num_bits_17(const sp_digit* a) "MOV %[a], r4\n\t" : [a] "+r" (a) : - : "memory", "r1", "r2", "r3", "r4", "r5", "cc" + : "memory", "cc", "r1", "r2", "r3", "r4", "r5" ); return (word32)(size_t)a; } @@ -65913,7 +66270,8 @@ typedef struct sp_point_1024 { * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_1024_mul_16(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static void sp_1024_mul_16(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static void sp_1024_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -67711,7 +68069,8 @@ static void sp_1024_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* b) "STM %[r]!, {r3, r4, r5, r6}\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", "r12", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r11", + "r12" ); } @@ -68863,7 +69222,8 @@ static void sp_1024_sqr_16(sp_digit* r, const sp_digit* a) "STM %[r]!, {r2, r3, r4, r8}\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r12", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r12" ); } @@ -68874,9 +69234,11 @@ static void sp_1024_sqr_16(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_1024_add_16(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_1024_add_16(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_1024_add_16(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_1024_add_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -68918,7 +69280,7 @@ static sp_digit sp_1024_add_16(sp_digit* r, const sp_digit* a, const sp_digit* b "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -68999,7 +69361,7 @@ static sp_digit sp_1024_sub_in_place_32(sp_digit* a, const sp_digit* b) "SBC %[a], r9, r9\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)a; } @@ -69011,9 +69373,11 @@ static sp_digit sp_1024_sub_in_place_32(sp_digit* a, const sp_digit* b) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_1024_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_1024_add_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -69083,7 +69447,7 @@ static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b "ADC %[r], %[r], #0x0\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -69164,9 +69528,11 @@ SP_NOINLINE static void sp_1024_mul_32(sp_digit* r, const sp_digit* a, * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_1024_sub_16(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_1024_sub_16(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_1024_sub_16(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_1024_sub_16(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -69207,7 +69573,7 @@ static sp_digit sp_1024_sub_16(sp_digit* r, const sp_digit* a, const sp_digit* b "SBC %[r], r6, r6\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -69256,7 +69622,8 @@ SP_NOINLINE static void sp_1024_sqr_32(sp_digit* r, const sp_digit* a) * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static void sp_1024_mul_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static void sp_1024_mul_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else static void sp_1024_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ @@ -69370,7 +69737,8 @@ static void sp_1024_mul_32(sp_digit* r, const sp_digit* a, const sp_digit* b) #endif : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -69487,7 +69855,8 @@ static void sp_1024_sqr_32(sp_digit* r, const sp_digit* a) #endif : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", "r11", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "lr", + "r11" ); } @@ -69623,7 +69992,8 @@ static sp_digit sp_1024_sub_in_place_32(sp_digit* a, const sp_digit* b) "MOV %[a], r10\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11" ); return (word32)(size_t)a; } @@ -69639,9 +70009,11 @@ static sp_digit sp_1024_sub_in_place_32(sp_digit* a, const sp_digit* b) * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_1024_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_1024_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_1024_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_1024_cond_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -69680,7 +70052,7 @@ static sp_digit sp_1024_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_dig "MOV %[r], r4\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -69695,9 +70067,11 @@ static sp_digit sp_1024_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_dig * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_1024_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_1024_cond_sub_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_1024_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_1024_cond_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -69824,7 +70198,7 @@ static sp_digit sp_1024_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_dig "SBC %[r], r5, r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9" ); return (word32)(size_t)r; } @@ -69838,9 +70212,11 @@ static sp_digit sp_1024_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_dig * b A single precision integer. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_1024_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p) +static sp_digit sp_1024_add_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p) #else -static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b) +static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -69879,7 +70255,8 @@ static sp_digit sp_1024_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b "MOV %[r], r3\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r3", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r3", "r12" ); return (word32)(size_t)r; } @@ -69940,7 +70317,7 @@ static void sp_1024_mul_d_32(sp_digit* r, const sp_digit* a, sp_digit b) "STR r3, [%[r], #128]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9" ); } @@ -70126,7 +70503,7 @@ static void sp_1024_mul_d_32(sp_digit* r, const sp_digit* a, sp_digit b) "STR r5, [%[r]]\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8" ); } @@ -70142,9 +70519,11 @@ static void sp_1024_mul_d_32(sp_digit* r, const sp_digit* a, sp_digit b) * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_1024_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_1024_word_32(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_1024_word_32(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_1024_word_32(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -70191,7 +70570,7 @@ SP_NOINLINE static sp_digit div_1024_word_32(sp_digit d1, sp_digit d0, sp_digit "ADD %[d1], r6, r3\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -70207,9 +70586,11 @@ SP_NOINLINE static sp_digit div_1024_word_32(sp_digit d1, sp_digit d0, sp_digit * Note that this is an approximate div. It may give an answer 1 larger. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static sp_digit div_1024_word_32(sp_digit d1_p, sp_digit d0_p, sp_digit div_p) +SP_NOINLINE static sp_digit div_1024_word_32(sp_digit d1_p, sp_digit d0_p, + sp_digit div_p) #else -SP_NOINLINE static sp_digit div_1024_word_32(sp_digit d1, sp_digit d0, sp_digit div) +SP_NOINLINE static sp_digit div_1024_word_32(sp_digit d1, sp_digit d0, + sp_digit div) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -70273,7 +70654,7 @@ SP_NOINLINE static sp_digit div_1024_word_32(sp_digit d1, sp_digit d0, sp_digit "SUB %[d1], r3, r8\n\t" : [d1] "+r" (d1), [d0] "+r" (d0), [div] "+r" (div) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)d1; } @@ -70716,7 +71097,7 @@ static sp_int32 sp_1024_cmp_32(const sp_digit* a, const sp_digit* b) "MOV %[a], r2\n\t" : [a] "+r" (a), [b] "+r" (b) : - : "memory", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r2", "r3", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)a; } @@ -71057,9 +71438,11 @@ static int sp_1024_point_to_ecc_point_32(const sp_point_1024* p, ecc_point* pm) * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -71360,7 +71743,8 @@ SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a, const sp_digit* m, s "MOV %[mp], r3\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_1024_cond_sub_32(a - 32, a, m, mp); } @@ -71373,9 +71757,11 @@ SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a, const sp_digit* m, s * mp The digit representing the negative inverse of m mod 2^n. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a_p, const sp_digit* m_p, sp_digit mp_p) +SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a_p, + const sp_digit* m_p, sp_digit mp_p) #else -SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a, const sp_digit* m, sp_digit mp) +SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a, const sp_digit* m, + sp_digit mp) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -71586,7 +71972,8 @@ SP_NOINLINE static void sp_1024_mont_reduce_32(sp_digit* a, const sp_digit* m, s "MOV %[mp], r5\n\t" : [a] "+r" (a), [m] "+r" (m), [mp] "+r" (mp) : - : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "lr", "cc" + : "memory", "cc", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "r11", "r12", "lr" ); sp_1024_cond_sub_32(a - 32, a, m, mp); } @@ -71737,9 +72124,11 @@ static void sp_1024_map_32(sp_point_1024* r, const sp_point_1024* p, * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_1024_mont_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, const sp_digit* m_p) +SP_NOINLINE static void sp_1024_mont_add_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) #else -SP_NOINLINE static void sp_1024_mont_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m) +SP_NOINLINE static void sp_1024_mont_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -71904,7 +72293,8 @@ SP_NOINLINE static void sp_1024_mont_add_32(sp_digit* r, const sp_digit* a, cons "STM %[r]!, {r4, r5, r6, r7}\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r12" ); } @@ -71915,9 +72305,11 @@ SP_NOINLINE static void sp_1024_mont_add_32(sp_digit* r, const sp_digit* a, cons * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_1024_mont_dbl_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +SP_NOINLINE static void sp_1024_mont_dbl_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) #else -SP_NOINLINE static void sp_1024_mont_dbl_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +SP_NOINLINE static void sp_1024_mont_dbl_32(sp_digit* r, const sp_digit* a, + const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -72065,7 +72457,8 @@ SP_NOINLINE static void sp_1024_mont_dbl_32(sp_digit* r, const sp_digit* a, cons "STM %[r]!, {r4, r5, r6, r7}\n\t" : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) : - : "memory", "r8", "r9", "r10", "r11", "r4", "r5", "r6", "r7", "r12", "cc" + : "memory", "cc", "r8", "r9", "r10", "r11", "r4", "r5", "r6", "r7", + "r12" ); } @@ -72076,9 +72469,11 @@ SP_NOINLINE static void sp_1024_mont_dbl_32(sp_digit* r, const sp_digit* a, cons * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_1024_mont_tpl_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* m_p) +SP_NOINLINE static void sp_1024_mont_tpl_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* m_p) #else -SP_NOINLINE static void sp_1024_mont_tpl_32(sp_digit* r, const sp_digit* a, const sp_digit* m) +SP_NOINLINE static void sp_1024_mont_tpl_32(sp_digit* r, const sp_digit* a, + const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -72381,7 +72776,8 @@ SP_NOINLINE static void sp_1024_mont_tpl_32(sp_digit* r, const sp_digit* a, cons "STM %[r]!, {r4, r5, r6, r7}\n\t" : [r] "+r" (r), [a] "+r" (a), [m] "+r" (m) : - : "memory", "r8", "r9", "r10", "r11", "r4", "r5", "r6", "r7", "r12", "cc" + : "memory", "cc", "r8", "r9", "r10", "r11", "r4", "r5", "r6", "r7", + "r12" ); } @@ -72393,9 +72789,11 @@ SP_NOINLINE static void sp_1024_mont_tpl_32(sp_digit* r, const sp_digit* a, cons * m Modulus (prime). */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -SP_NOINLINE static void sp_1024_mont_sub_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, const sp_digit* m_p) +SP_NOINLINE static void sp_1024_mont_sub_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, const sp_digit* m_p) #else -SP_NOINLINE static void sp_1024_mont_sub_32(sp_digit* r, const sp_digit* a, const sp_digit* b, const sp_digit* m) +SP_NOINLINE static void sp_1024_mont_sub_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, const sp_digit* m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -72554,7 +72952,8 @@ SP_NOINLINE static void sp_1024_mont_sub_32(sp_digit* r, const sp_digit* a, cons "STM %[r]!, {r4, r5, r6, r7}\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", + "r12" ); } @@ -72568,9 +72967,11 @@ SP_NOINLINE static void sp_1024_mont_sub_32(sp_digit* r, const sp_digit* a, cons * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_1024_cond_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_1024_cond_add_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_1024_cond_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_1024_cond_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -72609,7 +73010,7 @@ static sp_digit sp_1024_cond_add_32(sp_digit* r, const sp_digit* a, const sp_dig "MOV %[r], r5\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8" ); return (word32)(size_t)r; } @@ -72624,9 +73025,11 @@ static sp_digit sp_1024_cond_add_32(sp_digit* r, const sp_digit* a, const sp_dig * m Mask value to apply. */ #ifndef WOLFSSL_NO_VAR_ASSIGN_REG -static sp_digit sp_1024_cond_add_32(sp_digit* r_p, const sp_digit* a_p, const sp_digit* b_p, sp_digit m_p) +static sp_digit sp_1024_cond_add_32(sp_digit* r_p, const sp_digit* a_p, + const sp_digit* b_p, sp_digit m_p) #else -static sp_digit sp_1024_cond_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m) +static sp_digit sp_1024_cond_add_32(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) #endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */ { #ifndef WOLFSSL_NO_VAR_ASSIGN_REG @@ -72753,7 +73156,7 @@ static sp_digit sp_1024_cond_add_32(sp_digit* r, const sp_digit* a, const sp_dig "ADC %[r], r10, r10\n\t" : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [m] "+r" (m) : - : "memory", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "cc" + : "memory", "cc", "r4", "r5", "r6", "r7", "r8", "r9", "r10" ); return (word32)(size_t)r; } @@ -72899,7 +73302,7 @@ static void sp_1024_rshift1_32(sp_digit* r, const sp_digit* a) "STR r3, [%[r], #124]\n\t" : [r] "+r" (r), [a] "+r" (a) : - : "memory", "r2", "r3", "r4", "cc" + : "memory", "cc", "r2", "r3", "r4" ); } @@ -81865,9 +82268,9 @@ static void sp_1024_from_bin(sp_digit* r, int size, const byte* a, int n) } #else switch (i) { - case 2: d[2] = a[2]; //fallthrough - case 1: d[1] = a[1]; //fallthrough - case 0: d[0] = a[0]; //fallthrough + case 2: d[i-2] = a[2]; //fallthrough + case 1: d[i-1] = a[1]; //fallthrough + case 0: d[i-0] = a[0]; //fallthrough } #endif j++; diff --git a/src/wolfcrypt/src/sp_dsp32.c b/src/wolfcrypt/src/sp_dsp32.c index e65862d..f218860 100644 --- a/src/wolfcrypt/src/sp_dsp32.c +++ b/src/wolfcrypt/src/sp_dsp32.c @@ -1,6 +1,6 @@ /* sp_cdsp_signed.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,14 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -/* from wolfcrypt/src/sp_c32.c */ +#include -#ifdef HAVE_CONFIG_H - #include -#endif +/* from wolfcrypt/src/sp_c32.c */ -#include -#include #include #ifdef NO_INLINE #include diff --git a/src/wolfcrypt/src/sp_int.c b/src/wolfcrypt/src/sp_int.c index 00b3607..1769840 100644 --- a/src/wolfcrypt/src/sp_int.c +++ b/src/wolfcrypt/src/sp_int.c @@ -1,6 +1,6 @@ /* sp_int.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -26,12 +26,8 @@ DESCRIPTION This library provides single precision (SP) integer math functions. */ -#ifdef HAVE_CONFIG_H - #include -#endif -#include -#include +#include #if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL) @@ -39,12 +35,12 @@ This library provides single precision (SP) integer math functions. defined(WOLFSSL_SP_NO_MALLOC) #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ !defined(WOLFSSL_SP_NO_DYN_STACK) -#pragma GCC diagnostic push +PRAGMA_GCC_DIAG_PUSH /* We are statically declaring a variable smaller than sp_int. * We track available memory in the 'size' field. * Disable warnings of sp_int being partly outside array bounds of variable. */ -#pragma GCC diagnostic ignored "-Warray-bounds" +PRAGMA_GCC("GCC diagnostic ignored \"-Warray-bounds\"") #endif #endif @@ -353,8 +349,8 @@ while (0) "movq %%rax, %[l] \n\t" \ "movq %%rdx, %[h] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ - : [a] "m" (va), [b] "m" (vb) \ - : "memory", "%rax", "%rdx", "cc" \ + : [a] "rm" (va), [b] "rm" (vb) \ + : "%rax", "%rdx", "cc" \ ) /* Multiply va by vb and store double size result in: vo | vh | vl */ #define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ @@ -377,7 +373,7 @@ while (0) "adcq %%rdx, %[h] \n\t" \ "adcq $0 , %[o] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ - : [a] "m" (va), [b] "m" (vb) \ + : [a] "rm" (va), [b] "rm" (vb) \ : "%rax", "%rdx", "cc" \ ) /* Multiply va by vb and add double size result into: vh | vl */ @@ -388,7 +384,7 @@ while (0) "addq %%rax, %[l] \n\t" \ "adcq %%rdx, %[h] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh) \ - : [a] "m" (va), [b] "m" (vb) \ + : [a] "rm" (va), [b] "rm" (vb) \ : "%rax", "%rdx", "cc" \ ) /* Multiply va by vb and add double size result twice into: vo | vh | vl */ @@ -403,7 +399,7 @@ while (0) "adcq %%rdx, %[h] \n\t" \ "adcq $0 , %[o] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ - : [a] "m" (va), [b] "m" (vb) \ + : [a] "rm" (va), [b] "rm" (vb) \ : "%rax", "%rdx", "cc" \ ) /* Multiply va by vb and add double size result twice into: vo | vh | vl @@ -419,7 +415,7 @@ while (0) "adcq %%rdx, %[h] \n\t" \ "adcq $0 , %[o] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ - : [a] "m" (va), [b] "m" (vb) \ + : [a] "rm" (va), [b] "rm" (vb) \ : "%rax", "%rdx", "cc" \ ) /* Square va and store double size result in: vh | vl */ @@ -430,8 +426,8 @@ while (0) "movq %%rax, %[l] \n\t" \ "movq %%rdx, %[h] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ - : [a] "m" (va) \ - : "memory", "%rax", "%rdx", "cc" \ + : [a] "rm" (va) \ + : "%rax", "%rdx", "cc" \ ) /* Square va and add double size result into: vo | vh | vl */ #define SP_ASM_SQR_ADD(vl, vh, vo, va) \ @@ -442,7 +438,7 @@ while (0) "adcq %%rdx, %[h] \n\t" \ "adcq $0 , %[o] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ - : [a] "m" (va) \ + : [a] "rm" (va) \ : "%rax", "%rdx", "cc" \ ) /* Square va and add double size result into: vh | vl */ @@ -453,7 +449,7 @@ while (0) "addq %%rax, %[l] \n\t" \ "adcq %%rdx, %[h] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh) \ - : [a] "m" (va) \ + : [a] "rm" (va) \ : "%rax", "%rdx", "cc" \ ) /* Add va into: vh | vl */ @@ -462,10 +458,9 @@ while (0) "addq %[a], %[l] \n\t" \ "adcq $0 , %[h] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh) \ - : [a] "m" (va) \ + : [a] "rm" (va) \ : "cc" \ ) -/* Add va, variable in a register, into: vh | vl */ #define SP_ASM_ADDC_REG(vl, vh, va) \ __asm__ __volatile__ ( \ "addq %[a], %[l] \n\t" \ @@ -480,7 +475,7 @@ while (0) "subq %[a], %[l] \n\t" \ "sbbq $0 , %[h] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh) \ - : [a] "m" (va) \ + : [a] "rm" (va) \ : "cc" \ ) /* Sub va from: vh | vl */ @@ -703,8 +698,8 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "movl %%eax, %[l] \n\t" \ "movl %%edx, %[h] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ - : [a] "m" (va), [b] "m" (vb) \ - : "memory", "eax", "edx", "cc" \ + : [a] "rm" (va), [b] "rm" (vb) \ + : "eax", "edx", "cc" \ ) /* Multiply va by vb and store double size result in: vo | vh | vl */ #define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ @@ -726,8 +721,8 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "addl %%eax, %[l] \n\t" \ "adcl %%edx, %[h] \n\t" \ "adcl $0 , %[o] \n\t" \ - : [l] "+rm" (vl), [h] "+rm" (vh), [o] "+rm" (vo) \ - : [a] "r" (va), [b] "r" (vb) \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "rm" (va), [b] "rm" (vb) \ : "eax", "edx", "cc" \ ) /* Multiply va by vb and add double size result into: vh | vl */ @@ -738,7 +733,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "addl %%eax, %[l] \n\t" \ "adcl %%edx, %[h] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh) \ - : [a] "m" (va), [b] "m" (vb) \ + : [a] "rm" (va), [b] "rm" (vb) \ : "eax", "edx", "cc" \ ) /* Multiply va by vb and add double size result twice into: vo | vh | vl */ @@ -752,8 +747,8 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "addl %%eax, %[l] \n\t" \ "adcl %%edx, %[h] \n\t" \ "adcl $0 , %[o] \n\t" \ - : [l] "+rm" (vl), [h] "+rm" (vh), [o] "+rm" (vo) \ - : [a] "r" (va), [b] "r" (vb) \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "rm" (va), [b] "rm" (vb) \ : "eax", "edx", "cc" \ ) /* Multiply va by vb and add double size result twice into: vo | vh | vl @@ -769,7 +764,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "adcl %%edx, %[h] \n\t" \ "adcl $0 , %[o] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ - : [a] "m" (va), [b] "m" (vb) \ + : [a] "rm" (va), [b] "rm" (vb) \ : "eax", "edx", "cc" \ ) /* Square va and store double size result in: vh | vl */ @@ -780,8 +775,8 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "movl %%eax, %[l] \n\t" \ "movl %%edx, %[h] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ - : [a] "m" (va) \ - : "memory", "eax", "edx", "cc" \ + : [a] "rm" (va) \ + : "eax", "edx", "cc" \ ) /* Square va and add double size result into: vo | vh | vl */ #define SP_ASM_SQR_ADD(vl, vh, vo, va) \ @@ -791,8 +786,8 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "addl %%eax, %[l] \n\t" \ "adcl %%edx, %[h] \n\t" \ "adcl $0 , %[o] \n\t" \ - : [l] "+rm" (vl), [h] "+rm" (vh), [o] "+rm" (vo) \ - : [a] "m" (va) \ + : [l] "+r" (vl), [h] "+r" (vh), [o] "+r" (vo) \ + : [a] "rm" (va) \ : "eax", "edx", "cc" \ ) /* Square va and add double size result into: vh | vl */ @@ -803,7 +798,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "addl %%eax, %[l] \n\t" \ "adcl %%edx, %[h] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh) \ - : [a] "m" (va) \ + : [a] "rm" (va) \ : "eax", "edx", "cc" \ ) /* Add va into: vh | vl */ @@ -812,10 +807,9 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "addl %[a], %[l] \n\t" \ "adcl $0 , %[h] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh) \ - : [a] "m" (va) \ + : [a] "rm" (va) \ : "cc" \ ) -/* Add va, variable in a register, into: vh | vl */ #define SP_ASM_ADDC_REG(vl, vh, va) \ __asm__ __volatile__ ( \ "addl %[a], %[l] \n\t" \ @@ -830,7 +824,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "subl %[a], %[l] \n\t" \ "sbbl $0 , %[h] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh) \ - : [a] "m" (va) \ + : [a] "rm" (va) \ : "cc" \ ) /* Sub va from: vh | vl */ @@ -904,7 +898,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "umulh %[h], %[a], %[b] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va), [b] "r" (vb) \ - : "memory", "cc" \ + : "cc" \ ) /* Multiply va by vb and store double size result in: vo | vh | vl */ #define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ @@ -915,7 +909,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mov %[o], xzr \n\t" \ : [l] "+r" (vl), [h] "+r" (vh), [o] "=r" (vo) \ : [a] "r" (va), [b] "r" (vb) \ - : "x8" \ + : "x8", "cc" \ ) /* Multiply va by vb and add double size result into: vo | vh | vl */ #define SP_ASM_MUL_ADD(vl, vh, vo, va, vb) \ @@ -978,7 +972,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "umulh %[h], %[a], %[a] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va) \ - : "memory" \ + : "cc" \ ) /* Square va and add double size result into: vo | vh | vl */ #define SP_ASM_SQR_ADD(vl, vh, vo, va) \ @@ -1135,7 +1129,6 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "umull %[l], %[h], %[a], %[b] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va), [b] "r" (vb) \ - : "memory" \ ) /* Multiply va by vb and store double size result in: vo | vh | vl */ #define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ @@ -1144,7 +1137,6 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mov %[o], #0 \n\t" \ : [l] "+r" (vl), [h] "+r" (vh), [o] "=r" (vo) \ : [a] "r" (va), [b] "r" (vb) \ - : \ ) /* Multiply va by vb and add double size result into: vo | vh | vl */ #define SP_ASM_MUL_ADD(vl, vh, vo, va, vb) \ @@ -1163,7 +1155,6 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "umlal %[l], %[h], %[a], %[b] \n\t" \ : [l] "+r" (vl), [h] "+r" (vh) \ : [a] "r" (va), [b] "r" (vb) \ - : \ ) /* Multiply va by vb and add double size result twice into: vo | vh | vl */ #define SP_ASM_MUL_ADD2(vl, vh, vo, va, vb) \ @@ -1200,7 +1191,6 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "umull %[l], %[h], %[a], %[a] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va) \ - : "memory" \ ) /* Square va and add double size result into: vo | vh | vl */ #define SP_ASM_SQR_ADD(vl, vh, vo, va) \ @@ -1259,7 +1249,6 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "clz %[n], %[a] \n\t" \ : [n] "=r" (vn) \ : [a] "r" (va) \ - : \ ) #endif @@ -3482,7 +3471,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mulhdu %[h], %[a], %[b] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va), [b] "r" (vb) \ - : "memory" \ + : \ ) /* Multiply va by vb and store double size result in: vo | vh | vl */ #define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ @@ -3555,7 +3544,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mulhdu %[h], %[a], %[a] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va) \ - : "memory" \ + : \ ) /* Square va and add double size result into: vo | vh | vl */ #define SP_ASM_SQR_ADD(vl, vh, vo, va) \ @@ -3630,7 +3619,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mulhdu %[h], %[a], %[b] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va), [b] "r" (vb) \ - : "memory" \ + : \ ) /* Multiply va by vb and store double size result in: vo | vh | vl */ #define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ @@ -3703,7 +3692,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mulhdu %[h], %[a], %[a] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va) \ - : "memory" \ + : \ ) /* Square va and add double size result into: vo | vh | vl */ #define SP_ASM_SQR_ADD(vl, vh, vo, va) \ @@ -3789,7 +3778,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mulhwu %[h], %[a], %[b] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va), [b] "r" (vb) \ - : "memory" \ + : \ ) /* Multiply va by vb and store double size result in: vo | vh | vl */ #define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ @@ -3861,7 +3850,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mulhwu %[h], %[a], %[a] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va) \ - : "memory" \ + : \ ) /* Square va and add double size result into: vo | vh | vl */ #define SP_ASM_SQR_ADD(vl, vh, vo, va) \ @@ -3935,7 +3924,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mulhwu %[h], %[a], %[b] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va), [b] "r" (vb) \ - : "memory" \ + : \ ) /* Multiply va by vb and store double size result in: vo | vh | vl */ #define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ @@ -4007,7 +3996,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mulhwu %[h], %[a], %[a] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va) \ - : "memory" \ + : \ ) /* Square va and add double size result into: vo | vh | vl */ #define SP_ASM_SQR_ADD(vl, vh, vo, va) \ @@ -4091,7 +4080,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mfhi %[h] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va), [b] "r" (vb) \ - : "memory", "$lo", "$hi" \ + : "$lo", "$hi" \ ) /* Multiply va by vb and store double size result in: vo | vh | vl */ #define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ @@ -4194,7 +4183,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mfhi %[h] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va) \ - : "memory", "$lo", "$hi" \ + : "$lo", "$hi" \ ) /* Square va and add double size result into: vo | vh | vl */ #define SP_ASM_SQR_ADD(vl, vh, vo, va) \ @@ -4292,7 +4281,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mfhi %[h] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va), [b] "r" (vb) \ - : "memory", "%lo", "%hi" \ + : "%lo", "%hi" \ ) /* Multiply va by vb and store double size result in: vo | vh | vl */ #define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ @@ -4395,7 +4384,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mfhi %[h] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va) \ - : "memory", "%lo", "%hi" \ + : "%lo", "%hi" \ ) /* Square va and add double size result into: vo | vh | vl */ #define SP_ASM_SQR_ADD(vl, vh, vo, va) \ @@ -4492,7 +4481,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mulhu %[h], %[a], %[b] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va), [b] "r" (vb) \ - : "memory" \ + : \ ) /* Multiply va by vb and store double size result in: vo | vh | vl */ #define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ @@ -4589,7 +4578,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mulhu %[h], %[a], %[a] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va) \ - : "memory" \ + : \ ) /* Square va and add double size result into: vo | vh | vl */ #define SP_ASM_SQR_ADD(vl, vh, vo, va) \ @@ -4684,7 +4673,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mulhu %[h], %[a], %[b] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va), [b] "r" (vb) \ - : "memory" \ + : \ ) /* Multiply va by vb and store double size result in: vo | vh | vl */ #define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ @@ -4781,7 +4770,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "mulhu %[h], %[a], %[a] \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va) \ - : "memory" \ + : \ ) /* Square va and add double size result into: vo | vh | vl */ #define SP_ASM_SQR_ADD(vl, vh, vo, va) \ @@ -4878,7 +4867,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "lgr %[h], %%r0 \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va), [b] "r" (vb) \ - : "memory", "r0", "r1" \ + : "r0", "r1" \ ) /* Multiply va by vb and store double size result in: vo | vh | vl */ #define SP_ASM_MUL_SET(vl, vh, vo, va, vb) \ @@ -4958,7 +4947,7 @@ static WC_INLINE sp_int_digit sp_div_word(sp_int_digit hi, sp_int_digit lo, "lgr %[h], %%r0 \n\t" \ : [h] "+r" (vh), [l] "+r" (vl) \ : [a] "r" (va) \ - : "memory", "r0", "r1" \ + : "r0", "r1" \ ) /* Square va and add double size result into: vo | vh | vl */ #define SP_ASM_SQR_ADD(vl, vh, vo, va) \ @@ -5136,7 +5125,7 @@ int sp_init_size(sp_int* a, unsigned int size) int err = MP_OKAY; /* Validate parameters. Don't use size more than max compiled. */ - if ((a == NULL) || ((size <= 0) || (size > SP_INT_DIGITS))) { + if ((a == NULL) || ((size == 0) || (size > SP_INT_DIGITS))) { err = MP_VAL; } @@ -5279,6 +5268,9 @@ void sp_zero(sp_int* a) */ void sp_clear(sp_int* a) { +#ifdef HAVE_FIPS + sp_forcezero(a); +#else /* Clear when valid pointer passed in. */ if (a != NULL) { unsigned int i; @@ -5291,6 +5283,7 @@ void sp_clear(sp_int* a) _sp_zero(a); sp_free(a); } +#endif } #if !defined(NO_RSA) || !defined(NO_DH) || defined(HAVE_ECC) || \ @@ -8016,7 +8009,7 @@ int sp_submod(const sp_int* a, const sp_int* b, const sp_int* m, sp_int* r) } #endif /* WOLFSSL_SP_MATH_ALL */ -/* Constant time clamping/ +/* Constant time clamping. * * @param [in, out] a SP integer to clamp. */ @@ -8027,8 +8020,20 @@ static void sp_clamp_ct(sp_int* a) sp_size_t mask = (sp_size_t)-1; for (i = (int)a->used - 1; i >= 0; i--) { - used = (sp_size_t)(used - ((a->dp[i] == 0) & mask)); - mask &= (sp_size_t)(0 - (a->dp[i] == 0)); +#if ((SP_WORD_SIZE == 64) && \ + (defined(_WIN64) || !defined(WOLFSSL_UINT128_T_DEFINED))) || \ + ((SP_WORD_SIZE == 32) && defined(NO_64BIT)) + sp_int_digit negVal = ~a->dp[i]; + sp_int_digit minusOne = a->dp[i] - 1; + sp_int_digit zeroMask = + (sp_int_digit)((sp_int_sdigit)(negVal & minusOne) >> + (SP_WORD_SIZE - 1)); +#else + sp_int_digit zeroMask = + (sp_int_digit)((((sp_int_sword)a->dp[i]) - 1) >> SP_WORD_SIZE); +#endif + mask &= (sp_size_t)zeroMask; + used = (sp_size_t)(used + mask); } a->used = used; } @@ -8216,7 +8221,7 @@ int sp_addmod_ct(const sp_int* a, const sp_int* b, const sp_int* m, sp_int* r) * @return MP_OKAY on success. */ static void _sp_submod_ct(const sp_int* a, const sp_int* b, const sp_int* m, - unsigned int max, sp_int* r) + unsigned int max_size, sp_int* r) { #ifndef SQR_MUL_ASM sp_int_sword w; @@ -8237,7 +8242,7 @@ static void _sp_submod_ct(const sp_int* a, const sp_int* b, const sp_int* m, l = 0; h = 0; #endif - for (i = 0; i < max; i++) { + for (i = 0; i < max_size; i++) { /* Values past 'used' are not initialized. */ mask_a += (i == a->used); mask_b += (i == b->used); @@ -8527,13 +8532,13 @@ int sp_rshb(const sp_int* a, int n, sp_int* r) { int err = MP_OKAY; /* Number of digits to shift down. */ - sp_size_t i = (sp_size_t)(n >> SP_WORD_SHIFT); + sp_size_t i; if ((a == NULL) || (n < 0)) { err = MP_VAL; } /* Handle case where shifting out all digits. */ - if ((err == MP_OKAY) && (i >= a->used)) { + else if ((i = (sp_size_t)(n >> SP_WORD_SHIFT)) >= a->used) { _sp_zero(r); } /* Change callers when more error cases returned. */ @@ -8876,7 +8881,7 @@ static int _sp_div(const sp_int* a, const sp_int* d, sp_int* r, sp_int* rem, if ((!done) && (err == MP_OKAY)) { #if (defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)) && \ !defined(WOLFSSL_SP_NO_MALLOC) - int cnt = 4; + unsigned int cnt = 4; /* Reuse remainder sp_int where possible. */ if ((rem != NULL) && (rem != d) && (rem->size > a->used)) { sa = rem; @@ -8905,7 +8910,7 @@ static int _sp_div(const sp_int* a, const sp_int* d, sp_int* r, sp_int* rem, } if (tr == NULL) { tr = td[i]; - _sp_init_size(tr, a->used - d->used + 2); + _sp_init_size(tr, (unsigned int)(a->used - d->used + 2)); } #else sa = td[2]; @@ -9252,8 +9257,9 @@ static int _sp_mul(const sp_int* a, const sp_int* b, sp_int* r) #endif #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) - t = (sp_int_digit*)XMALLOC(sizeof(sp_int_digit) * (a->used + b->used), NULL, - DYNAMIC_TYPE_BIGINT); + t = (sp_int_digit*)XMALLOC(sizeof(sp_int_digit) * + (size_t)(a->used + b->used), NULL, + DYNAMIC_TYPE_BIGINT); if (t == NULL) { err = MP_MEM; } @@ -9328,8 +9334,9 @@ static int _sp_mul(const sp_int* a, const sp_int* b, sp_int* r) #endif #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) - t = (sp_int_digit*)XMALLOC(sizeof(sp_int_digit) * (a->used + b->used), NULL, - DYNAMIC_TYPE_BIGINT); + t = (sp_int_digit*)XMALLOC(sizeof(sp_int_digit) * + (size_t)(a->used + b->used), NULL, + DYNAMIC_TYPE_BIGINT); if (t == NULL) { err = MP_MEM; } @@ -12003,9 +12010,14 @@ int sp_mul(const sp_int* a, const sp_int* b, sp_int* r) } /* Need extra digit during calculation. */ + /* NOLINTBEGIN(clang-analyzer-core.UndefinedBinaryOperatorResult) */ + /* clang-tidy falsely believes that r->size was corrupted by the _sp_copy() + * to "Copy base into working variable" in _sp_exptmod_ex(). + */ if ((err == MP_OKAY) && (a->used + b->used > r->size)) { err = MP_VAL; } + /* NOLINTEND(clang-analyzer-core.UndefinedBinaryOperatorResult) */ #if 0 if (err == MP_OKAY) { @@ -14873,7 +14885,7 @@ static int _sp_sqr(const sp_int* a, sp_int* r) #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) t = (sp_int_digit*)XMALLOC( - sizeof(sp_int_digit) * (((a->used + 1) / 2) * 2 + 1), NULL, + sizeof(sp_int_digit) * (size_t)(((a->used + 1) / 2) * 2 + 1), NULL, DYNAMIC_TYPE_BIGINT); if (t == NULL) { err = MP_MEM; @@ -14987,8 +14999,9 @@ static int _sp_sqr(const sp_int* a, sp_int* r) #endif #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SP_NO_MALLOC) - t = (sp_int_digit*)XMALLOC(sizeof(sp_int_digit) * (a->used * 2), NULL, - DYNAMIC_TYPE_BIGINT); + t = (sp_int_digit*)XMALLOC(sizeof(sp_int_digit) * + (size_t)(a->used * 2), NULL, + DYNAMIC_TYPE_BIGINT); if (t == NULL) { err = MP_MEM; } @@ -17613,10 +17626,9 @@ static int _sp_mont_red(sp_int* a, const sp_int* m, sp_int_digit mp, int ct) h = 0; } /* Handle overflow. */ - h = o2; - SP_ASM_ADDC(l, h, a->dp[7]); + SP_ASM_ADDC(l, o2, a->dp[7]); a->dp[3] = l; - a->dp[4] = h; + a->dp[4] = o2; a->used = 5; /* Remove leading zeros. */ @@ -17679,10 +17691,9 @@ static int _sp_mont_red(sp_int* a, const sp_int* m, sp_int_digit mp, int ct) h = 0; } /* Handle overflow. */ - h = o2; - SP_ASM_ADDC(l, h, a->dp[11]); + SP_ASM_ADDC(l, o2, a->dp[11]); a->dp[5] = l; - a->dp[6] = h; + a->dp[6] = o2; a->used = 7; /* Remove leading zeros. */ @@ -17718,7 +17729,7 @@ static int _sp_mont_red(sp_int* a, const sp_int* m, sp_int_digit mp, int ct) h = 0; SP_ASM_MUL_ADD_NO(l, h, mu, *(md++)); l = h; - for (j = 1; j + 1 < (unsigned int)m->used - 1; j += 2) { + for (j = 1; j < (unsigned int)m->used - 2; j += 2) { h = 0; SP_ASM_ADDC(l, h, ad[j]); SP_ASM_MUL_ADD_NO(l, h, mu, *(md++)); @@ -17744,11 +17755,9 @@ static int _sp_mont_red(sp_int* a, const sp_int* m, sp_int_digit mp, int ct) o = h; } /* Handle overflow. */ - l = o; - h = o2; - SP_ASM_ADDC(l, h, a->dp[m->used * 2 - 1]); - a->dp[m->used - 1] = l; - a->dp[m->used] = h; + SP_ASM_ADDC(o, o2, a->dp[m->used * 2 - 1]); + a->dp[m->used - 1] = o; + a->dp[m->used] = o2; a->used = m->used + 1; /* Remove leading zeros. */ @@ -17789,8 +17798,8 @@ static int _sp_mont_red(sp_int* a, const sp_int* m, sp_int_digit mp, int ct) SP_ASM_MUL_ADD_NO(l, h, mu, *(md++)); ad[0] = l; l = h; - /* 2.4. If i == NumDigits(m)-1 and mask != 0 then mu & = mask */ - for (j = 1; j + 1 < (unsigned int)m->used - 1; j += 2) { + /* 2.4. For j = 1 up to NumDigits(m)-2 */ + for (j = 1; j < (unsigned int)m->used - 2; j += 2) { h = 0; /* 2.4.1. a += mu * DigitMask(m, j) */ SP_ASM_ADDC(l, h, ad[j + 0]); @@ -17820,11 +17829,9 @@ static int _sp_mont_red(sp_int* a, const sp_int* m, sp_int_digit mp, int ct) o = h; } /* Handle overflow. */ - l = o; - h = o2; - SP_ASM_ADDC(l, h, a->dp[m->used * 2 - 1]); - a->dp[m->used * 2 - 1] = l; - a->dp[m->used * 2] = h; + SP_ASM_ADDC(o, o2, a->dp[m->used * 2 - 1]); + a->dp[m->used * 2 - 1] = o; + a->dp[m->used * 2] = o2; a->used = (sp_size_t)(m->used * 2 + 1); } @@ -17977,9 +17984,14 @@ int sp_mont_norm(sp_int* norm, const sp_int* m) if (err == MP_OKAY) { /* Find top bit and ensure norm has enough space. */ bits = (unsigned int)sp_count_bits(m); + /* NOLINTBEGIN(clang-analyzer-core.UndefinedBinaryOperatorResult) */ + /* clang-tidy falsely believes that norm->size was corrupted by the + * _sp_copy() to "Set real working value to base." in _sp_exptmod_ex(). + */ if (bits >= (unsigned int)norm->size * SP_WORD_SIZE) { err = MP_VAL; } + /* NOLINTEND(clang-analyzer-core.UndefinedBinaryOperatorResult) */ } if (err == MP_OKAY) { /* Round up for case when m is less than a word - no advantage in using @@ -19880,7 +19892,7 @@ void sp_memzero_check(sp_int* sp) defined(WOLFSSL_SP_NO_MALLOC) #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ !defined(WOLFSSL_SP_NO_DYN_STACK) -#pragma GCC diagnostic pop +PRAGMA_GCC_DIAG_POP #endif #endif diff --git a/src/wolfcrypt/src/sp_sm2_arm32.c b/src/wolfcrypt/src/sp_sm2_arm32.c index 4dc5377..0a458bd 100644 --- a/src/wolfcrypt/src/sp_sm2_arm32.c +++ b/src/wolfcrypt/src/sp_sm2_arm32.c @@ -1,6 +1,6 @@ /* sp_sm2_arm32.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLFSSL_SM2 diff --git a/src/wolfcrypt/src/sp_sm2_arm64.c b/src/wolfcrypt/src/sp_sm2_arm64.c index 8f87711..db67898 100644 --- a/src/wolfcrypt/src/sp_sm2_arm64.c +++ b/src/wolfcrypt/src/sp_sm2_arm64.c @@ -1,6 +1,6 @@ /* sp_sm2_arm64.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLFSSL_SM2 diff --git a/src/wolfcrypt/src/sp_sm2_armthumb.c b/src/wolfcrypt/src/sp_sm2_armthumb.c index 0be6685..21e49dc 100644 --- a/src/wolfcrypt/src/sp_sm2_armthumb.c +++ b/src/wolfcrypt/src/sp_sm2_armthumb.c @@ -1,6 +1,6 @@ /* sp_sm2_armthumb.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLFSSL_SM2 diff --git a/src/wolfcrypt/src/sp_sm2_c32.c b/src/wolfcrypt/src/sp_sm2_c32.c index 754b80a..5aae8d2 100644 --- a/src/wolfcrypt/src/sp_sm2_c32.c +++ b/src/wolfcrypt/src/sp_sm2_c32.c @@ -1,6 +1,6 @@ /* sp_sm2_c32.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLFSSL_SM2 diff --git a/src/wolfcrypt/src/sp_sm2_c64.c b/src/wolfcrypt/src/sp_sm2_c64.c index 861bfe3..d848104 100644 --- a/src/wolfcrypt/src/sp_sm2_c64.c +++ b/src/wolfcrypt/src/sp_sm2_c64.c @@ -1,6 +1,6 @@ /* sp_sm2_c64.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLFSSL_SM2 diff --git a/src/wolfcrypt/src/sp_sm2_cortexm.c b/src/wolfcrypt/src/sp_sm2_cortexm.c index 4b1083f..4ea4b8f 100644 --- a/src/wolfcrypt/src/sp_sm2_cortexm.c +++ b/src/wolfcrypt/src/sp_sm2_cortexm.c @@ -1,6 +1,6 @@ /* sp_sm2_cortexm.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLFSSL_SM2 diff --git a/src/wolfcrypt/src/sp_sm2_x86_64.c b/src/wolfcrypt/src/sp_sm2_x86_64.c index 24a5b9e..fd6f0d2 100644 --- a/src/wolfcrypt/src/sp_sm2_x86_64.c +++ b/src/wolfcrypt/src/sp_sm2_x86_64.c @@ -1,6 +1,6 @@ /* sp_sm2_x86_64.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLFSSL_SM2 diff --git a/src/wolfcrypt/src/sp_x86_64.c b/src/wolfcrypt/src/sp_x86_64.c index 039820d..298ec47 100644 --- a/src/wolfcrypt/src/sp_x86_64.c +++ b/src/wolfcrypt/src/sp_x86_64.c @@ -1,6 +1,6 @@ /* sp.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -21,16 +21,11 @@ /* Implementation by Sean Parkinson. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \ defined(WOLFSSL_HAVE_SP_ECC) -#include #include #ifdef NO_INLINE #include diff --git a/src/wolfcrypt/src/sphincs.c b/src/wolfcrypt/src/sphincs.c index 5fc054d..94be4ac 100644 --- a/src/wolfcrypt/src/sphincs.c +++ b/src/wolfcrypt/src/sphincs.c @@ -1,6 +1,6 @@ /* sphincs.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,14 +19,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -/* Based on dilithium.c and Reworked for Sphincs by Anthony Hu. */ - -#ifdef HAVE_CONFIG_H - #include -#endif +#include -/* in case user set HAVE_PQC there */ -#include +/* Based on dilithium.c and Reworked for Sphincs by Anthony Hu. */ #include @@ -37,7 +32,6 @@ #endif #include -#include #ifdef NO_INLINE #include #else diff --git a/src/wolfcrypt/src/srp.c b/src/wolfcrypt/src/srp.c index b06f62a..c7f5986 100644 --- a/src/wolfcrypt/src/srp.c +++ b/src/wolfcrypt/src/srp.c @@ -1,6 +1,6 @@ /* srp.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,18 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef WOLFCRYPT_HAVE_SRP #include #include -#include #ifdef NO_INLINE #include @@ -152,39 +146,39 @@ static int SrpHashFinal(SrpHash* hash, byte* digest) } } -static word32 SrpHashSize(SrpType type) +static int SrpHashSize(SrpType type) { switch (type) { case SRP_TYPE_SHA: #ifndef NO_SHA return WC_SHA_DIGEST_SIZE; #else - return 0; + return ALGO_ID_E; #endif case SRP_TYPE_SHA256: #ifndef NO_SHA256 return WC_SHA256_DIGEST_SIZE; #else - return 0; + return ALGO_ID_E; #endif case SRP_TYPE_SHA384: #ifdef WOLFSSL_SHA384 return WC_SHA384_DIGEST_SIZE; #else - return 0; + return ALGO_ID_E; #endif case SRP_TYPE_SHA512: #ifdef WOLFSSL_SHA512 return WC_SHA512_DIGEST_SIZE; #else - return 0; + return ALGO_ID_E; #endif default: - return 0; + return ALGO_ID_E; } } @@ -353,7 +347,8 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz, byte digest2[SRP_MAX_DIGEST_SIZE]; byte pad = 0; int r; - word32 i, j = 0; + word32 i; + int hashSize = 0; if (!srp || !N || !g || !salt || nSz < gSz) return BAD_FUNC_ARG; @@ -361,6 +356,10 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz, if (!srp->user) return SRP_CALL_ORDER_E; + hashSize = SrpHashSize(srp->type); + if (hashSize < 0) + return hashSize; + /* Set N */ if (mp_read_unsigned_bin(&srp->N, N, nSz) != MP_OKAY) return MP_READ_E; @@ -389,7 +388,7 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz, srp->saltSz = saltSz; /* Set k = H(N, g) */ - r = SrpHashInit(&hash, srp->type, srp->heap); + r = SrpHashInit(&hash, srp->type, srp->heap); if (!r) r = SrpHashUpdate(&hash, (byte*) N, nSz); for (i = 0; (word32)i < nSz - gSz; i++) { if (!r) r = SrpHashUpdate(&hash, &pad, 1); @@ -414,7 +413,7 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz, /* digest1 = H(N) ^ H(g) */ if (r == 0) { - for (i = 0, j = SrpHashSize(srp->type); i < j; i++) + for (i = 0; i < (word32)hashSize; i++) digest1[i] ^= digest2[i]; } @@ -425,8 +424,8 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz, SrpHashFree(&hash); /* client proof = H( H(N) ^ H(g) | H(user) | salt) */ - if (!r) r = SrpHashUpdate(&srp->client_proof, digest1, j); - if (!r) r = SrpHashUpdate(&srp->client_proof, digest2, j); + if (!r) r = SrpHashUpdate(&srp->client_proof, digest1, (word32)hashSize); + if (!r) r = SrpHashUpdate(&srp->client_proof, digest2, (word32)hashSize); if (!r) r = SrpHashUpdate(&srp->client_proof, salt, saltSz); return r; @@ -436,7 +435,7 @@ int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size) { SrpHash hash; byte digest[SRP_MAX_DIGEST_SIZE]; - word32 digestSz; + int digestSz; int r; if (!srp || !password || srp->side != SRP_CLIENT_SIDE) @@ -446,6 +445,8 @@ int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size) return SRP_CALL_ORDER_E; digestSz = SrpHashSize(srp->type); + if (digestSz < 0) + return digestSz; /* digest = H(username | ':' | password) */ r = SrpHashInit(&hash, srp->type, srp->heap); @@ -458,12 +459,12 @@ int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size) /* digest = H(salt | H(username | ':' | password)) */ if (!r) r = SrpHashInit(&hash, srp->type, srp->heap); if (!r) r = SrpHashUpdate(&hash, srp->salt, srp->saltSz); - if (!r) r = SrpHashUpdate(&hash, digest, digestSz); + if (!r) r = SrpHashUpdate(&hash, digest, (word32)digestSz); if (!r) r = SrpHashFinal(&hash, digest); SrpHashFree(&hash); /* Set x (private key) */ - if (!r) r = mp_read_unsigned_bin(&srp->auth, digest, digestSz); + if (!r) r = mp_read_unsigned_bin(&srp->auth, digest, (word32)digestSz); ForceZero(digest, SRP_MAX_DIGEST_SIZE); @@ -572,10 +573,15 @@ int wc_SrpGetPublic(Srp* srp, byte* pub, word32* size) #endif word32 modulusSz; int r; + int hashSize; if (!srp || !pub || !size) return BAD_FUNC_ARG; + hashSize = SrpHashSize(srp->type); + if (hashSize < 0) + return hashSize; + if (mp_iszero(&srp->auth) == MP_YES) return SRP_CALL_ORDER_E; @@ -616,7 +622,7 @@ int wc_SrpGetPublic(Srp* srp, byte* pub, word32* size) { r = mp_init_multi(i, j, 0, 0, 0, 0); } - if (!r) r = mp_read_unsigned_bin(i, srp->k,SrpHashSize(srp->type)); + if (!r) r = mp_read_unsigned_bin(i, srp->k, (word32)hashSize); if (!r) r = mp_iszero(i) == MP_YES ? SRP_BAD_KEY_E : 0; if (!r) r = mp_exptmod(&srp->g, &srp->priv, &srp->N, pubkey); if (!r) r = mp_mulmod(i, &srp->auth, &srp->N, j); @@ -654,17 +660,22 @@ static int wc_SrpSetKey(Srp* srp, byte* secret, word32 size) { SrpHash hash; byte digest[SRP_MAX_DIGEST_SIZE]; - word32 i, j, digestSz = SrpHashSize(srp->type); + word32 i, j; + int digestSz; byte counter[4]; int r = WC_NO_ERR_TRACE(BAD_FUNC_ARG); + digestSz = SrpHashSize(srp->type); + if (digestSz < 0) + return digestSz; + XMEMSET(digest, 0, SRP_MAX_DIGEST_SIZE); - srp->key = (byte*)XMALLOC(2 * digestSz, srp->heap, DYNAMIC_TYPE_SRP); + srp->key = (byte*)XMALLOC(2 * (word32)digestSz, srp->heap, DYNAMIC_TYPE_SRP); if (srp->key == NULL) return MEMORY_E; - srp->keySz = 2 * digestSz; + srp->keySz = 2 * (word32)digestSz; for (i = j = 0; j < srp->keySz; i++) { counter[0] = (byte)(i >> 24); @@ -677,7 +688,7 @@ static int wc_SrpSetKey(Srp* srp, byte* secret, word32 size) if (!r) r = SrpHashUpdate(&hash, counter, 4); if (!r) { - if (j + digestSz > srp->keySz) { + if (j + (word32)digestSz > srp->keySz) { r = SrpHashFinal(&hash, digest); XMEMCPY(srp->key + j, digest, srp->keySz - j); j = srp->keySz; @@ -685,7 +696,7 @@ static int wc_SrpSetKey(Srp* srp, byte* secret, word32 size) else { r = SrpHashFinal(&hash, srp->key + j); - j += digestSz; + j += (word32)digestSz; } } SrpHashFree(&hash); @@ -715,7 +726,8 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, mp_int u[1], s[1], temp1[1], temp2[1]; #endif byte *secret = NULL; - word32 i, secretSz, digestSz; + word32 i, secretSz; + int digestSz; byte pad = 0; int r; @@ -761,6 +773,11 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, goto out; digestSz = SrpHashSize(srp->type); + if (digestSz < 0) { + r = digestSz; + goto out; + } + secretSz = (word32)mp_unsigned_bin_size(&srp->N); if ((secretSz < clientPubKeySz) || (secretSz < serverPubKeySz)) { @@ -795,7 +812,7 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, /* set u */ if ((r = SrpHashFinal(hash, digest))) goto out; - if ((r = mp_read_unsigned_bin(u, digest, SrpHashSize(srp->type)))) + if ((r = mp_read_unsigned_bin(u, digest, (word32)digestSz))) goto out; SrpHashFree(hash); @@ -804,7 +821,7 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, if (srp->side == SRP_CLIENT_SIDE) { /* temp1 = B - k * v; rejects k == 0, B == 0 and B >= N. */ - if ((r = mp_read_unsigned_bin(temp1, srp->k, digestSz))) + if ((r = mp_read_unsigned_bin(temp1, srp->k, (word32)digestSz))) goto out; if (mp_iszero(temp1) == MP_YES) { r = SRP_BAD_KEY_E; @@ -940,11 +957,16 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, int wc_SrpGetProof(Srp* srp, byte* proof, word32* size) { int r; + int hashSize; if (!srp || !proof || !size) return BAD_FUNC_ARG; - if (*size < SrpHashSize(srp->type)) + hashSize = SrpHashSize(srp->type); + if (hashSize < 0) + return ALGO_ID_E; + + if (*size < (word32)hashSize) return BUFFER_E; if ((r = SrpHashFinal(srp->side == SRP_CLIENT_SIDE @@ -952,7 +974,7 @@ int wc_SrpGetProof(Srp* srp, byte* proof, word32* size) : &srp->server_proof, proof)) != 0) return r; - *size = SrpHashSize(srp->type); + *size = (word32)hashSize; if (srp->side == SRP_CLIENT_SIDE) { /* server proof = H( A | client proof | K) */ @@ -967,11 +989,16 @@ int wc_SrpVerifyPeersProof(Srp* srp, byte* proof, word32 size) { byte digest[SRP_MAX_DIGEST_SIZE]; int r; + int hashSize; if (!srp || !proof) return BAD_FUNC_ARG; - if (size != SrpHashSize(srp->type)) + hashSize = SrpHashSize(srp->type); + if (hashSize < 0) + return ALGO_ID_E; + + if (size != (word32)hashSize) return BUFFER_E; r = SrpHashFinal(srp->side == SRP_CLIENT_SIDE ? &srp->server_proof diff --git a/src/wolfcrypt/src/tfm.c b/src/wolfcrypt/src/tfm.c index 5b16871..5bd7328 100644 --- a/src/wolfcrypt/src/tfm.c +++ b/src/wolfcrypt/src/tfm.c @@ -1,6 +1,6 @@ /* tfm.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,7 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - +#include /* * Based on public domain TomsFastMath 0.10 by Tom St Denis, tomstdenis@iahu.ca, @@ -31,13 +31,6 @@ * to fit wolfSSL's needs. */ -#ifdef HAVE_CONFIG_H - #include -#endif - -/* in case user set USE_FAST_MATH there */ -#include - #ifdef USE_FAST_MATH #ifdef NO_INLINE @@ -4575,6 +4568,9 @@ void fp_zero(fp_int *a) void fp_clear(fp_int *a) { +#ifdef HAVE_FIPS + fp_forcezero(a); +#else int size; a->used = 0; a->sign = FP_ZPOS; @@ -4585,6 +4581,7 @@ void fp_clear(fp_int *a) #endif XMEMSET(a->dp, 0, size * sizeof(fp_digit)); fp_free(a); +#endif } void fp_forcezero (mp_int * a) diff --git a/src/wolfcrypt/src/wc_dsp.c b/src/wolfcrypt/src/wc_dsp.c index c6c76c2..09c7ea1 100644 --- a/src/wolfcrypt/src/wc_dsp.c +++ b/src/wolfcrypt/src/wc_dsp.c @@ -1,6 +1,6 @@ /* wc_dsp.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,13 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif +#include -#include -#include -#include #ifdef NO_INLINE #include #else diff --git a/src/wolfcrypt/src/wc_encrypt.c b/src/wolfcrypt/src/wc_encrypt.c index 9393a69..b1e8b82 100644 --- a/src/wolfcrypt/src/wc_encrypt.c +++ b/src/wolfcrypt/src/wc_encrypt.c @@ -1,6 +1,6 @@ /* wc_encrypt.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,23 +19,17 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#include -#ifdef HAVE_CONFIG_H - #include -#endif - -#include #include #include #include #include #include #include -#include #include #include #include -#include #ifdef NO_INLINE #include @@ -455,10 +449,12 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, #if defined(WOLFSSL_AES_256) case PBE_AES256_CBC: switch(shaOid) { + #ifndef NO_SHA256 case HMAC_SHA256_OID: typeH = WC_SHA256; derivedLen = 32; break; + #endif #ifndef NO_SHA default: typeH = WC_SHA; @@ -471,10 +467,12 @@ int wc_CryptKey(const char* password, int passwordSz, byte* salt, #if defined(WOLFSSL_AES_128) case PBE_AES128_CBC: switch(shaOid) { + #ifndef NO_SHA256 case HMAC_SHA256_OID: typeH = WC_SHA256; derivedLen = 16; break; + #endif #ifndef NO_SHA default: typeH = WC_SHA; diff --git a/src/wolfcrypt/src/wc_lms.c b/src/wolfcrypt/src/wc_lms.c index b2a3bf8..9de58da 100644 --- a/src/wolfcrypt/src/wc_lms.c +++ b/src/wolfcrypt/src/wc_lms.c @@ -1,6 +1,6 @@ /* wc_lms.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,13 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include -#include -#include +#include #if defined(WOLFSSL_HAVE_LMS) && defined(WOLFSSL_WC_LMS) #include @@ -352,14 +346,14 @@ static const wc_LmsParamsMap wc_lms_map[] = { WC_SHA256_192_DIGEST_SIZE) }, #endif #if LMS_MAX_HEIGHT >= 20 - { WC_LMS_PARM_L1_H20_W2 , "LMS/HSS_SHA256/192_L1_H20_W2", - LMS_PARAMS(1, 20, 2, 1, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W2, + { WC_LMS_PARM_SHA256_192_L1_H20_W2 , "LMS/HSS_SHA256/192_L1_H20_W2", + LMS_PARAMS(1, 20, 2, 1, LMS_SHA256_M24_H20, LMOTS_SHA256_N24_W2, WC_SHA256_192_DIGEST_SIZE) }, - { WC_LMS_PARM_L1_H20_W4 , "LMS/HSS_SHA256/192_L1_H20_W4", - LMS_PARAMS(1, 20, 4, 2, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W4, + { WC_LMS_PARM_SHA256_192_L1_H20_W4 , "LMS/HSS_SHA256/192_L1_H20_W4", + LMS_PARAMS(1, 20, 4, 2, LMS_SHA256_M24_H20, LMOTS_SHA256_N24_W4, WC_SHA256_192_DIGEST_SIZE) }, - { WC_LMS_PARM_L1_H20_W8 , "LMS/HSS_SHA256/192_L1_H20_W8", - LMS_PARAMS(1, 20, 8, 3, LMS_SHA256_M32_H20, LMOTS_SHA256_N32_W8, + { WC_LMS_PARM_SHA256_192_L1_H20_W8 , "LMS/HSS_SHA256/192_L1_H20_W8", + LMS_PARAMS(1, 20, 8, 3, LMS_SHA256_M24_H20, LMOTS_SHA256_N24_W8, WC_SHA256_192_DIGEST_SIZE) }, #endif #endif /* WOLFSSL_LMS_SHA256_192 */ @@ -1162,7 +1156,8 @@ int wc_LmsKey_ImportPubRaw(LmsKey* key, const byte* in, word32 inLen) if (ret == 0) { XMEMCPY(key->pub, in, inLen); - key->state = WC_LMS_STATE_VERIFYONLY; + if (key->state != WC_LMS_STATE_OK) + key->state = WC_LMS_STATE_VERIFYONLY; } return ret; @@ -1263,4 +1258,28 @@ int wc_LmsKey_Verify(LmsKey* key, const byte* sig, word32 sigSz, return ret; } +/* Get the Key ID from the raw private key data. + * + * PRIV = Q | PARAMS | SEED | I + * where I is the Key ID. + * + * @param [in] priv Private key data. + * @param [in] privSz Size of private key data. + * @param Pointer to 16 byte Key ID in the private key. + * @return NULL on failure. + */ +const byte * wc_LmsKey_GetKidFromPrivRaw(const byte * priv, word32 privSz) +{ + word32 seedSz = privSz - LMS_Q_LEN + HSS_PRIV_KEY_PARAM_SET_LEN - LMS_I_LEN; + + if (priv == NULL) { + return NULL; + } + if ((seedSz != WC_SHA256_192_DIGEST_SIZE) && + (seedSz != WC_SHA256_DIGEST_SIZE)) { + return NULL; + } + return priv - LMS_I_LEN; +} + #endif /* WOLFSSL_HAVE_LMS && WOLFSSL_WC_LMS */ diff --git a/src/wolfcrypt/src/wc_lms_impl.c b/src/wolfcrypt/src/wc_lms_impl.c index 44bff83..47b60a6 100644 --- a/src/wolfcrypt/src/wc_lms_impl.c +++ b/src/wolfcrypt/src/wc_lms_impl.c @@ -1,6 +1,6 @@ /* wc_lms_impl.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -37,13 +37,9 @@ * Enable when memory is limited. */ -#ifdef HAVE_CONFIG_H - #include -#endif +#include -#include #include -#include #ifdef NO_INLINE #include @@ -1339,10 +1335,10 @@ static void wc_lmots_public_key_encode(const LmsParams* params, const byte* priv_i = priv + LMS_Q_LEN + params->hash_len; /* u32str(type) || ... || T(1) */ - c32toa(params->lmsType, pub); + c32toa(params->lmsType & LMS_H_W_MASK, pub); pub += 4; /* u32str(type) || u32str(otstype) || ... || T(1) */ - c32toa(params->lmOtsType, pub); + c32toa(params->lmOtsType & LMS_H_W_MASK, pub); pub += 4; /* u32str(type) || u32str(otstype) || I || T(1) */ XMEMCPY(pub, priv_i, LMS_I_LEN); @@ -1365,14 +1361,14 @@ static int wc_lmots_public_key_check(const LmsParams* params, const byte* pub) ato32(pub, &type); pub += 4; /* Compare with parameters. */ - if (type != params->lmsType) { + if (type != (params->lmsType & LMS_H_W_MASK)) { ret = PUBLIC_KEY_E; } if (ret == 0) { /* Get node hash and Winternitz width type. */ ato32(pub, &type); /* Compare with parameters. */ - if (type != params->lmOtsType) { + if (type != (params->lmOtsType & LMS_H_W_MASK)) { ret = PUBLIC_KEY_E; } } @@ -2097,8 +2093,10 @@ static int wc_lms_treehash_update(LmsState* state, LmsPrivState* privState, #endif /* WOLFSSL_SMALL_STACK */ /* Public key, root node, is top of data stack. */ - XMEMCPY(stack, stackCache->stack, params->height * params->hash_len); - sp = stack + stackCache->offset; + if (ret == 0) { + XMEMCPY(stack, stackCache->stack, params->height * params->hash_len); + sp = stack + stackCache->offset; + } /* Compute all nodes requested. */ for (i = min_idx; (ret == 0) && (i <= max_idx); i++) { @@ -2193,7 +2191,7 @@ static int wc_lms_treehash_update(LmsState* state, LmsPrivState* privState, } } - if (!useRoot) { + if (!useRoot && (ret == 0)) { /* Copy stack back. */ XMEMCPY(stackCache->stack, stack, params->height * params->hash_len); stackCache->offset = (word32)((size_t)sp - (size_t)stack); @@ -2248,7 +2246,7 @@ static int wc_lms_sign(LmsState* state, const byte* priv, const byte* msg, s += LMS_Q_LEN; /* ots_signature = sig = u32str(type) || ... */ - c32toa(state->params->lmOtsType, s); + c32toa(state->params->lmOtsType & LMS_H_W_MASK, s); s += LMS_TYPE_LEN; /* Sign this level. * S = u32str(q) || ots_signature || ... */ @@ -2257,7 +2255,7 @@ static int wc_lms_sign(LmsState* state, const byte* priv, const byte* msg, /* Skip over ots_signature. */ s += params->hash_len + params->p * params->hash_len; /* S = u32str(q) || ots_signature || u32str(type) || ... */ - c32toa(params->lmsType, s); + c32toa(params->lmsType & LMS_H_W_MASK, s); } return ret; @@ -2278,13 +2276,13 @@ static void wc_lms_sig_copy(const LmsParams* params, const byte* y, XMEMCPY(sig, priv, LMS_Q_LEN); sig += LMS_Q_LEN; /* S = u32str(q) || ... */ - c32toa(params->lmOtsType, sig); + c32toa(params->lmOtsType & LMS_H_W_MASK, sig); sig += LMS_TYPE_LEN; /* S = u32str(q) || ots_signature || ... */ XMEMCPY(sig, y, params->hash_len + params->p * params->hash_len); sig += params->hash_len + params->p * params->hash_len; /* S = u32str(q) || ots_signature || u32str(type) || ... */ - c32toa(params->lmsType, sig); + c32toa(params->lmsType & LMS_H_W_MASK, sig); } #endif /* !WOLFSSL_WC_LMS_SMALL && !WOLFSSL_LMS_NO_SIG_CACHE */ #endif /* !WOLFSSL_LMS_VERIFY_ONLY */ @@ -3478,7 +3476,9 @@ static int wc_hss_sign_build_sig(LmsState* state, byte* priv_raw, /* Build from bottom up. */ for (i = params->levels - 1; (ret == 0) && (i >= 0); i--) { byte* p = priv + i * (LMS_Q_LEN + params->hash_len + LMS_I_LEN); + #if !defined(WOLFSSL_LMS_MAX_LEVELS) || WOLFSSL_LMS_MAX_LEVELS > 1 byte* root = NULL; + #endif #ifndef WOLFSSL_LMS_NO_SIG_CACHE int store_p = 0; word32 q_32 = LMS_Q_AT_LEVEL(q, params->levels, i, @@ -3489,10 +3489,12 @@ static int wc_hss_sign_build_sig(LmsState* state, byte* priv_raw, /* Move to start of next signature at this level. */ sig -= LMS_SIG_LEN(params->height, params->p, params->hash_len); + #if !defined(WOLFSSL_LMS_MAX_LEVELS) || WOLFSSL_LMS_MAX_LEVELS > 1 if (i != 0) { /* Put root node into signature at this index. */ root = sig - params->hash_len; } + #endif #ifndef WOLFSSL_LMS_NO_SIG_CACHE /* Check if we have a cached version of C and the p hashes that we @@ -3528,10 +3530,12 @@ static int wc_hss_sign_build_sig(LmsState* state, byte* priv_raw, /* Copy the authentication path out of the private key. */ XMEMCPY(s, priv_key->state[i].auth_path, params->height * params->hash_len); + #if !defined(WOLFSSL_LMS_MAX_LEVELS) || WOLFSSL_LMS_MAX_LEVELS > 1 /* Copy the root node into signature unless at top. */ if (i != 0) { XMEMCPY(root, priv_key->state[i].root, params->hash_len); } + #endif } if ((ret == 0) && (i != 0)) { /* Create public data for this level if there is another. */ diff --git a/src/wolfcrypt/src/wc_mlkem.c b/src/wolfcrypt/src/wc_mlkem.c new file mode 100644 index 0000000..a370279 --- /dev/null +++ b/src/wolfcrypt/src/wc_mlkem.c @@ -0,0 +1,2070 @@ +/* wc_mlkem.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 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Implementation based on FIPS 203: + * https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf + * + * Original implementation based on NIST 3rd Round submission package. + * See link at: + * https://csrc.nist.gov/Projects/post-quantum-cryptography/ + * post-quantum-cryptography-standardization/round-3-submissions + */ + +/* Possible Kyber options: + * + * WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM Default: OFF + * Uses less dynamic memory to perform key generation. + * Has a small performance trade-off. + * Only usable with C implementation. + * + * WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM Default: OFF + * Uses less dynamic memory to perform encapsulation. + * Affects decapsulation too as encapsulation called. + * Has a small performance trade-off. + * Only usable with C implementation. + * + * WOLFSSL_MLKEM_NO_MAKE_KEY Default: OFF + * Disable the make key or key generation API. + * Reduces the code size. + * Turn on when only doing encapsulation. + * + * WOLFSSL_MLKEM_NO_ENCAPSULATE Default: OFF + * Disable the encapsulation API. + * Reduces the code size. + * Turn on when doing make key/decapsulation. + * + * WOLFSSL_MLKEM_NO_DECAPSULATE Default: OFF + * Disable the decapsulation API. + * Reduces the code size. + * Turn on when only doing encapsulation. + * + * WOLFSSL_MLKEM_CACHE_A Default: OFF + * Stores the matrix A during key generation for use in encapsulation when + * performing decapsulation. + * KyberKey is 8KB larger but decapsulation is significantly faster. + * Turn on when performing make key and decapsualtion with same object. + */ + +#include + +#include +#include +#include +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#if defined(USE_INTEL_SPEEDUP) || \ + (defined(__aarch64__) && defined(WOLFSSL_ARMASM)) + #if defined(WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM) || \ + defined(WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM) + #error "Can't use small memory with assembly optimized code" + #endif +#endif +#if defined(WOLFSSL_MLKEM_CACHE_A) + #if defined(WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM) || \ + defined(WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM) + #error "Can't cache A with small memory code" + #endif +#endif + +#if defined(WOLFSSL_MLKEM_NO_MAKE_KEY) && \ + defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) && \ + defined(WOLFSSL_MLKEM_NO_DECAPSULATE) + #error "No ML-KEM operations to be built." +#endif + +#ifdef WOLFSSL_WC_MLKEM + +/******************************************************************************/ + +/* Use SHA3-256 to generate 32-bytes of hash. */ +#define MLKEM_HASH_H mlkem_hash256 +/* Use SHA3-512 to generate 64-bytes of hash. */ +#define MLKEM_HASH_G mlkem_hash512 +/* Use SHAKE-256 as a key derivation function (KDF). */ +#if defined(USE_INTEL_SPEEDUP) || \ + (defined(WOLFSSL_ARMASM) && defined(__aarch64__)) + #define MLKEM_KDF mlkem_kdf +#else + #define MLKEM_KDF wc_Shake256Hash +#endif + +/******************************************************************************/ + +/* Declare variable to make compiler not optimize code in mlkem_from_msg(). */ +volatile sword16 mlkem_opt_blocker = 0; + +/******************************************************************************/ + +/** + * Initialize the Kyber key. + * + * @param [in] type Type of key: + * WC_ML_KEM_512, WC_ML_KEM_768, WC_ML_KEM_1024, + * KYBER512, KYBER768, KYBER1024. + * @param [out] key Kyber key object to initialize. + * @param [in] heap Dynamic memory hint. + * @param [in] devId Device Id. + * @return 0 on success. + * @return BAD_FUNC_ARG when key is NULL or type is unrecognized. + * @return NOT_COMPILED_IN when key type is not supported. + */ +int wc_MlKemKey_Init(MlKemKey* key, int type, void* heap, int devId) +{ + int ret = 0; + + /* Validate key. */ + if (key == NULL) { + ret = BAD_FUNC_ARG; + } + if (ret == 0) { + /* Validate type. */ + switch (type) { + #ifndef WOLFSSL_NO_ML_KEM + case WC_ML_KEM_512: + #ifndef WOLFSSL_WC_ML_KEM_512 + /* Code not compiled in for Kyber-512. */ + ret = NOT_COMPILED_IN; + #endif + break; + case WC_ML_KEM_768: + #ifndef WOLFSSL_WC_ML_KEM_768 + /* Code not compiled in for Kyber-768. */ + ret = NOT_COMPILED_IN; + #endif + break; + case WC_ML_KEM_1024: + #ifndef WOLFSSL_WC_ML_KEM_1024 + /* Code not compiled in for Kyber-1024. */ + ret = NOT_COMPILED_IN; + #endif + break; + #endif + #ifdef WOLFSSL_MLKEM_KYBER + case KYBER512: + #ifndef WOLFSSL_KYBER512 + /* Code not compiled in for Kyber-512. */ + ret = NOT_COMPILED_IN; + #endif + break; + case KYBER768: + #ifndef WOLFSSL_KYBER768 + /* Code not compiled in for Kyber-768. */ + ret = NOT_COMPILED_IN; + #endif + break; + case KYBER1024: + #ifndef WOLFSSL_KYBER1024 + /* Code not compiled in for Kyber-1024. */ + ret = NOT_COMPILED_IN; + #endif + break; + #endif + default: + /* No other values supported. */ + ret = BAD_FUNC_ARG; + break; + } + } + if (ret == 0) { + /* Keep type for parameters. */ + key->type = type; + /* Cache heap pointer. */ + key->heap = heap; + #ifdef WOLF_CRYPTO_CB + /* Cache device id - not used in for this algorithm yet. */ + key->devId = devId; + #endif + key->flags = 0; + + /* Zero out all data. */ + XMEMSET(&key->prf, 0, sizeof(key->prf)); + + /* Initialize the hash algorithm object. */ + ret = mlkem_hash_new(&key->hash, heap, devId); + } + if (ret == 0) { + /* Initialize the PRF algorithm object. */ + ret = mlkem_prf_new(&key->prf, heap, devId); + } + if (ret == 0) { + mlkem_init(); + } + + (void)devId; + + return ret; +} + +/** + * Free the Kyber key object. + * + * @param [in, out] key Kyber key object to dispose of. + * @return 0 on success. + */ +int wc_MlKemKey_Free(MlKemKey* key) +{ + if (key != NULL) { + /* Dispose of PRF object. */ + mlkem_prf_free(&key->prf); + /* Dispose of hash object. */ + mlkem_hash_free(&key->hash); + /* Ensure all private data is zeroed. */ + ForceZero(&key->hash, sizeof(key->hash)); + ForceZero(&key->prf, sizeof(key->prf)); + ForceZero(key->priv, sizeof(key->priv)); + ForceZero(key->z, sizeof(key->z)); + } + + return 0; +} + +/******************************************************************************/ + +#ifndef WOLFSSL_MLKEM_NO_MAKE_KEY +/** + * Make a Kyber key object using a random number generator. + * + * FIPS 203 - Algorithm 19: ML-KEM.KeyGen() + * Generates an encapsulation key and a corresponding decapsulation key. + * 1: d <- B_32 > d is 32 random bytes + * 2: z <- B_32 > z is 32 random bytes + * 3: if d == NULL or z == NULL then + * 4: return falsum + * > return an error indication if random bit generation failed + * 5: end if + * 6: (ek,dk) <- ML-KEM.KeyGen_Interal(d, z) + * > run internal key generation algorithm + * &: return (ek,dk) + * + * @param [in, out] key Kyber key object. + * @param [in] rng Random number generator. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or rng is NULL. + * @return MEMORY_E when dynamic memory allocation failed. + * @return MEMORY_E when dynamic memory allocation failed. + * @return RNG_FAILURE_E when generating random numbers failed. + * @return DRBG_CONT_FAILURE when random number generator health check fails. + */ +int wc_MlKemKey_MakeKey(MlKemKey* key, WC_RNG* rng) +{ + int ret = 0; + unsigned char rand[WC_ML_KEM_MAKEKEY_RAND_SZ]; + + /* Validate parameters. */ + if ((key == NULL) || (rng == NULL)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + /* Generate random to use with PRFs. + * Step 1: d is 32 random bytes + * Step 2: z is 32 random bytes + */ + ret = wc_RNG_GenerateBlock(rng, rand, WC_ML_KEM_SYM_SZ * 2); + /* Step 3: ret is not zero when d == NULL or z == NULL. */ + } + if (ret == 0) { + /* Make a key pair from the random. + * Step 6. run internal key generation algorithm + * Step 7. public and private key are stored in key + */ + ret = wc_KyberKey_MakeKeyWithRandom(key, rand, sizeof(rand)); + } + + /* Ensure seeds are zeroized. */ + ForceZero((void*)rand, (word32)sizeof(rand)); + + /* Step 4: return ret != 0 on falsum or internal key generation failure. */ + return ret; +} + +/** + * Make a Kyber key object using random data. + * + * FIPS 203 - Algorithm 16: ML-KEM.KeyGen_internal(d,z) + * Uses randomness to generate an encapsulation key and a corresponding + * decapsulation key. + * 1: (ek_PKE,dk_PKE) < K-PKE.KeyGen(d) > run key generation for K-PKE + * ... + * + * FIPS 203 - Algorithm 13: K-PKE.KeyGen(d) + * Uses randomness to generate an encryption key and a corresponding decryption + * key. + * 1: (rho,sigma) <- G(d||k)A + * > expand 32+1 bytes to two pseudorandom 32-byte seeds + * 2: N <- 0 + * 3-7: generate matrix A_hat + * 8-11: generate s + * 12-15: generate e + * 16-18: calculate t_hat from A_hat, s and e + * ... + * + * @param [in, out] key Kyber key ovject. + * @param [in] rand Random data. + * @param [in] len Length of random data in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or rand is NULL. + * @return BUFFER_E when length is not WC_ML_KEM_MAKEKEY_RAND_SZ. + * @return NOT_COMPILED_IN when key type is not supported. + * @return MEMORY_E when dynamic memory allocation failed. + */ +int wc_MlKemKey_MakeKeyWithRandom(MlKemKey* key, const unsigned char* rand, + int len) +{ + byte buf[2 * WC_ML_KEM_SYM_SZ + 1]; + byte* rho = buf; + byte* sigma = buf + WC_ML_KEM_SYM_SZ; +#ifndef WOLFSSL_NO_MALLOC + sword16* e = NULL; +#else +#ifndef WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM +#ifndef WOLFSSL_MLKEM_CACHE_A + sword16 e[(WC_ML_KEM_MAX_K + 1) * WC_ML_KEM_MAX_K * MLKEM_N]; +#else + sword16 e[WC_ML_KEM_MAX_K * MLKEM_N]; +#endif +#else + sword16 e[WC_ML_KEM_MAX_K * MLKEM_N]; +#endif +#endif +#ifndef WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM + sword16* a = NULL; +#endif + sword16* s = NULL; + sword16* t = NULL; + int ret = 0; + int k = 0; + + /* Validate parameters. */ + if ((key == NULL) || (rand == NULL)) { + ret = BAD_FUNC_ARG; + } + if ((ret == 0) && (len != WC_ML_KEM_MAKEKEY_RAND_SZ)) { + ret = BUFFER_E; + } + + if (ret == 0) { + key->flags = 0; + + /* Establish parameters based on key type. */ + switch (key->type) { +#ifndef WOLFSSL_NO_ML_KEM + #ifdef WOLFSSL_WC_ML_KEM_512 + case WC_ML_KEM_512: + k = WC_ML_KEM_512_K; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_768 + case WC_ML_KEM_768: + k = WC_ML_KEM_768_K; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_1024 + case WC_ML_KEM_1024: + k = WC_ML_KEM_1024_K; + break; + #endif +#endif +#ifdef WOLFSSL_MLKEM_KYBER + #ifdef WOLFSSL_KYBER512 + case KYBER512: + k = KYBER512_K; + break; + #endif + #ifdef WOLFSSL_KYBER768 + case KYBER768: + k = KYBER768_K; + break; + #endif + #ifdef WOLFSSL_KYBER1024 + case KYBER1024: + k = KYBER1024_K; + break; + #endif +#endif + default: + /* No other values supported. */ + ret = NOT_COMPILED_IN; + break; + } + } + +#ifndef WOLFSSL_NO_MALLOC + if (ret == 0) { + /* Allocate dynamic memory for matrix and error vector. */ +#ifndef WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM +#ifndef WOLFSSL_MLKEM_CACHE_A + /* e (v) | a (m) */ + e = (sword16*)XMALLOC((k + 1) * k * MLKEM_N * sizeof(sword16), + key->heap, DYNAMIC_TYPE_TMP_BUFFER); +#else + /* e (v) */ + e = (sword16*)XMALLOC(k * MLKEM_N * sizeof(sword16), + key->heap, DYNAMIC_TYPE_TMP_BUFFER); +#endif +#else + /* e (v) */ + e = (sword16*)XMALLOC(k * MLKEM_N * sizeof(sword16), + key->heap, DYNAMIC_TYPE_TMP_BUFFER); +#endif + if (e == NULL) { + ret = MEMORY_E; + } + } +#endif + if (ret == 0) { + const byte* d = rand; + +#ifdef WOLFSSL_MLKEM_CACHE_A + a = key->a; +#elif !defined(WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM) + /* Matrix A allocated at end of error vector. */ + a = e + (k * MLKEM_N); +#endif + +#if defined(WOLFSSL_MLKEM_KYBER) && !defined(WOLFSSL_NO_ML_KEM) + if (key->type & MLKEM_KYBER) +#endif +#ifdef WOLFSSL_MLKEM_KYBER + { + /* Expand 32 bytes of random to 32. */ + ret = MLKEM_HASH_G(&key->hash, d, WC_ML_KEM_SYM_SZ, NULL, 0, buf); + } +#endif +#if defined(WOLFSSL_MLKEM_KYBER) && !defined(WOLFSSL_NO_ML_KEM) + else +#endif +#ifndef WOLFSSL_NO_ML_KEM + { + buf[0] = k; + /* Expand 33 bytes of random to 32. + * Alg 13: Step 1: (rho,sigma) <- G(d||k) + */ + ret = MLKEM_HASH_G(&key->hash, d, WC_ML_KEM_SYM_SZ, buf, 1, buf); + } +#endif + } + if (ret == 0) { + const byte* z = rand + WC_ML_KEM_SYM_SZ; + s = key->priv; + t = key->pub; + + /* Cache the public seed for use in encapsulation and encoding public + * key. */ + XMEMCPY(key->pubSeed, rho, WC_ML_KEM_SYM_SZ); + /* Cache the z value for decapsulation and encoding private key. */ + XMEMCPY(key->z, z, sizeof(key->z)); + + /* Initialize PRF for use in noise generation. */ + mlkem_prf_init(&key->prf); +#ifndef WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM + /* Generate noise using PRF. + * Alg 13: Steps 8-15: generate s and e + */ + ret = mlkem_get_noise(&key->prf, k, s, e, NULL, sigma); + } + if (ret == 0) { + /* Generate the matrix A. + * Alg 13: Steps 3-7 + */ + ret = mlkem_gen_matrix(&key->prf, a, k, rho, 0); + } + if (ret == 0) { + /* Generate key pair from random data. + * Alg 13: Steps 16-18. + */ + mlkem_keygen(s, t, e, a, k); +#else + /* Generate noise using PRF. + * Alg 13: Steps 8-11: generate s + */ + ret = mlkem_get_noise(&key->prf, k, s, NULL, NULL, sigma); + } + if (ret == 0) { + /* Generate key pair from private vector and seeds. + * Alg 13: Steps 3-7: generate matrix A_hat + * Alg 13: 12-15: generate e + * Alg 13: 16-18: calculate t_hat from A_hat, s and e + */ + ret = mlkem_keygen_seeds(s, t, &key->prf, e, k, rho, sigma); + } + if (ret == 0) { +#endif + /* Private and public key are set/available. */ + key->flags |= MLKEM_FLAG_PRIV_SET | MLKEM_FLAG_PUB_SET; +#ifdef WOLFSSL_MLKEM_CACHE_A + key->flags |= MLKEM_FLAG_A_SET; +#endif + } + +#ifndef WOLFSSL_NO_MALLOC + /* Free dynamic memory allocated in function. */ + if (key != NULL) { + XFREE(e, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + + return ret; +} +#endif /* !WOLFSSL_MLKEM_NO_MAKE_KEY */ + +/******************************************************************************/ + +/** + * Get the size in bytes of cipher text for key. + * + * @param [in] key Kyber key object. + * @param [out] len Length of cipher text in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or len is NULL. + * @return NOT_COMPILED_IN when key type is not supported. + */ +int wc_MlKemKey_CipherTextSize(MlKemKey* key, word32* len) +{ + int ret = 0; + + /* Validate parameters. */ + if ((key == NULL) || (len == NULL)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + /* Return in 'len' size of the cipher text for the type of this key. */ + switch (key->type) { +#ifndef WOLFSSL_NO_ML_KEM + #ifdef WOLFSSL_WC_ML_KEM_512 + case WC_ML_KEM_512: + *len = WC_ML_KEM_512_CIPHER_TEXT_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_768 + case WC_ML_KEM_768: + *len = WC_ML_KEM_768_CIPHER_TEXT_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_1024 + case WC_ML_KEM_1024: + *len = WC_ML_KEM_1024_CIPHER_TEXT_SIZE; + break; + #endif +#endif +#ifdef WOLFSSL_MLKEM_KYBER + #ifdef WOLFSSL_KYBER512 + case KYBER512: + *len = KYBER512_CIPHER_TEXT_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER768 + case KYBER768: + *len = KYBER768_CIPHER_TEXT_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER1024 + case KYBER1024: + *len = KYBER1024_CIPHER_TEXT_SIZE; + break; + #endif +#endif + default: + /* No other values supported. */ + ret = NOT_COMPILED_IN; + break; + } + } + + return ret; +} + +/** + * Size of a shared secret in bytes. Always KYBER_SS_SZ. + * + * @param [in] key Kyber key object. Not used. + * @param [out] Size of the shared secret created with a Kyber key. + * @return 0 on success. + * @return 0 to indicate success. + */ +int wc_MlKemKey_SharedSecretSize(MlKemKey* key, word32* len) +{ + (void)key; + + *len = WC_ML_KEM_SS_SZ; + + return 0; +} + +#if !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) || \ + !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) +/* Encapsulate data and derive secret. + * + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE, m, r) + * Uses the encryption key to encrypt a plaintext message using the randomness + * r. + * 1: N <- 0 + * 2: t_hat <- ByteDecode_12(ek_PKE[0:384k]) + * > run ByteDecode_12 k times to decode t_hat + * 3: rho <- ek_PKE[384k : 384K + 32] + * > extract 32-byte seed from ek_PKE + * 4-8: generate matrix A_hat + * 9-12: generate y + * 13-16: generate e_1 + * 17: generate e_2 + * 18-19: calculate u + * 20: mu <- Decompress_1(ByteDecode_1(m)) + * 21: calculate v + * 22: c_1 <- ByteEncode_d_u(Compress_d_u(u)) + * > run ByteEncode_d_u and Compress_d_u k times + * 23: c_2 <- ByteEncode_d_v(Compress_d_v(v)) + * 24: return c <- (c_1||c_2) + * + * @param [in] key Kyber key object. + * @param [in] m Random bytes. + * @param [in] r Seed to feed to PRF when generating y, e1 and e2. + * @param [out] c Calculated cipher text. + * @return 0 on success. + * @return NOT_COMPILED_IN when key type is not supported. + */ +static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c) +{ + int ret = 0; + sword16* a = NULL; +#ifndef WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM + sword16* mu = NULL; + sword16* e1 = NULL; + sword16* e2 = NULL; +#endif + unsigned int k = 0; + unsigned int compVecSz = 0; +#ifndef WOLFSSL_NO_MALLOC + sword16* y = NULL; +#else +#ifndef WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM + sword16 y[((WC_ML_KEM_MAX_K + 3) * WC_ML_KEM_MAX_K + 3) * MLKEM_N]; +#else + sword16 y[3 * WC_ML_KEM_MAX_K * MLKEM_N]; +#endif +#endif + sword16* u; + sword16* v; + + /* Establish parameters based on key type. */ + switch (key->type) { +#ifndef WOLFSSL_NO_ML_KEM +#ifdef WOLFSSL_WC_ML_KEM_512 + case WC_ML_KEM_512: + k = WC_ML_KEM_512_K; + compVecSz = WC_ML_KEM_512_POLY_VEC_COMPRESSED_SZ; + break; +#endif +#ifdef WOLFSSL_WC_ML_KEM_768 + case WC_ML_KEM_768: + k = WC_ML_KEM_768_K; + compVecSz = WC_ML_KEM_768_POLY_VEC_COMPRESSED_SZ; + break; +#endif +#ifdef WOLFSSL_WC_ML_KEM_1024 + case WC_ML_KEM_1024: + k = WC_ML_KEM_1024_K; + compVecSz = WC_ML_KEM_1024_POLY_VEC_COMPRESSED_SZ; + break; +#endif +#endif +#ifdef WOLFSSL_MLKEM_KYBER +#ifdef WOLFSSL_KYBER512 + case KYBER512: + k = KYBER512_K; + compVecSz = KYBER512_POLY_VEC_COMPRESSED_SZ; + break; +#endif +#ifdef WOLFSSL_KYBER768 + case KYBER768: + k = KYBER768_K; + compVecSz = KYBER768_POLY_VEC_COMPRESSED_SZ; + break; +#endif +#ifdef WOLFSSL_KYBER1024 + case KYBER1024: + k = KYBER1024_K; + compVecSz = KYBER1024_POLY_VEC_COMPRESSED_SZ; + break; +#endif +#endif + default: + /* No other values supported. */ + ret = NOT_COMPILED_IN; + break; + } + +#ifndef WOLFSSL_NO_MALLOC + if (ret == 0) { + /* Allocate dynamic memory for all matrices, vectors and polynomials. */ +#ifndef WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM + y = (sword16*)XMALLOC(((k + 3) * k + 3) * MLKEM_N * sizeof(sword16), + key->heap, DYNAMIC_TYPE_TMP_BUFFER); +#else + y = (sword16*)XMALLOC(3 * k * MLKEM_N * sizeof(sword16), key->heap, + DYNAMIC_TYPE_TMP_BUFFER); +#endif + if (y == NULL) { + ret = MEMORY_E; + } + } +#endif + +#ifndef WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM + if (ret == 0) { + /* Assign allocated dynamic memory to pointers. + * y (b) | a (m) | mu (p) | e1 (p) | e2 (v) | u (v) | v (p) */ + a = y + MLKEM_N * k; + mu = a + MLKEM_N * k * k; + e1 = mu + MLKEM_N; + e2 = e1 + MLKEM_N * k; + + /* Convert msg to a polynomial. + * Step 20: mu <- Decompress_1(ByteDecode_1(m)) */ + mlkem_from_msg(mu, m); + + /* Initialize the PRF for use in the noise generation. */ + mlkem_prf_init(&key->prf); + /* Generate noise using PRF. + * Steps 9-17: generate y, e_1, e_2 + */ + ret = mlkem_get_noise(&key->prf, k, y, e1, e2, r); + } + #ifdef WOLFSSL_MLKEM_CACHE_A + if ((ret == 0) && ((key->flags & MLKEM_FLAG_A_SET) != 0)) { + unsigned int i; + /* Transpose matrix. + * Steps 4-8: generate matrix A_hat (from original) */ + for (i = 0; i < k; i++) { + unsigned int j; + for (j = 0; j < k; j++) { + XMEMCPY(&a[(i * k + j) * MLKEM_N], + &key->a[(j * k + i) * MLKEM_N], + MLKEM_N * 2); + } + } + } + else + #endif /* WOLFSSL_MLKEM_CACHE_A */ + if (ret == 0) { + /* Generate the transposed matrix. + * Step 4-8: generate matrix A_hat */ + ret = mlkem_gen_matrix(&key->prf, a, k, key->pubSeed, 1); + } + if (ret == 0) { + /* Assign remaining allocated dynamic memory to pointers. + * y (v) | a (m) | mu (p) | e1 (p) | r2 (v) | u (v) | v (p)*/ + u = e2 + MLKEM_N; + v = u + MLKEM_N * k; + + /* Perform encapsulation maths. + * Steps 18-19, 21: calculate u and v */ + mlkem_encapsulate(key->pub, u, v, a, y, e1, e2, mu, k); + } +#else /* WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM */ + if (ret == 0) { + /* Assign allocated dynamic memory to pointers. + * y (v) | a (v) | u (v) */ + a = y + MLKEM_N * k; + + /* Initialize the PRF for use in the noise generation. */ + mlkem_prf_init(&key->prf); + /* Generate noise using PRF. + * Steps 9-12: generate y */ + ret = mlkem_get_noise(&key->prf, k, y, NULL, NULL, r); + } + if (ret == 0) { + /* Assign remaining allocated dynamic memory to pointers. + * y (v) | at (v) | u (v) */ + u = a + MLKEM_N * k; + v = a; + + /* Perform encapsulation maths. + * Steps 13-17: generate e_1 and e_2 + * Steps 18-19, 21: calculate u and v */ + ret = mlkem_encapsulate_seeds(key->pub, &key->prf, u, a, y, k, m, + key->pubSeed, r); + } +#endif /* WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM */ + + if (ret == 0) { + byte* c1 = c; + byte* c2 = c + compVecSz; + + #if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) + if (k == WC_ML_KEM_512_K) { + /* Step 22: c_1 <- ByteEncode_d_u(Compress_d_u(u)) */ + mlkem_vec_compress_10(c1, u, k); + /* Step 23: c_2 <- ByteEncode_d_v(Compress_d_v(v)) */ + mlkem_compress_4(c2, v); + /* Step 24: return c <- (c_1||c_2) */ + } + #endif + #if defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768) + if (k == WC_ML_KEM_768_K) { + /* Step 22: c_1 <- ByteEncode_d_u(Compress_d_u(u)) */ + mlkem_vec_compress_10(c1, u, k); + /* Step 23: c_2 <- ByteEncode_d_v(Compress_d_v(v)) */ + mlkem_compress_4(c2, v); + /* Step 24: return c <- (c_1||c_2) */ + } + #endif + #if defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) + if (k == WC_ML_KEM_1024_K) { + /* Step 22: c_1 <- ByteEncode_d_u(Compress_d_u(u)) */ + mlkem_vec_compress_11(c1, u); + /* Step 23: c_2 <- ByteEncode_d_v(Compress_d_v(v)) */ + mlkem_compress_5(c2, v); + /* Step 24: return c <- (c_1||c_2) */ + } + #endif + } + +#ifndef WOLFSSL_NO_MALLOC + /* Dispose of dynamic memory allocated in function. */ + XFREE(y, key->heap, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} +#endif + +#ifndef WOLFSSL_MLKEM_NO_ENCAPSULATE +/** + * Encapsulate with random number generator and derive secret. + * + * FIPS 203, Algorithm 20: ML-KEM.Encaps(ek) + * Uses the encapsulation key to generate a shared secret key and an associated + * ciphertext. + * 1: m <- B_32 > m is 32 random bytes + * 2: if m == NULL then + * 3: return falsum + * 4: end if + * 5: (K,c) <- ML-KEM.Encaps_internal(ek,m) + * > run internal encapsulation algorithm + * 6: return (K,c) + * + * @param [in] key Kyber key object. + * @param [out] c Cipher text. + * @param [out] k Shared secret generated. + * @param [in] rng Random number generator. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, ct, ss or RNG is NULL. + * @return NOT_COMPILED_IN when key type is not supported. + * @return MEMORY_E when dynamic memory allocation failed. + */ +int wc_MlKemKey_Encapsulate(MlKemKey* key, unsigned char* c, unsigned char* k, + WC_RNG* rng) +{ + int ret = 0; + unsigned char m[WC_ML_KEM_ENC_RAND_SZ]; + + /* Validate parameters. */ + if ((key == NULL) || (c == NULL) || (k == NULL) || (rng == NULL)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + /* Generate seed for use with PRFs. + * Step 1: m is 32 random bytes + */ + ret = wc_RNG_GenerateBlock(rng, m, sizeof(m)); + /* Step 2: ret is not zero when m == NULL. */ + } + if (ret == 0) { + /* Encapsulate with the random. + * Step 5: run internal encapsulation algorithm + */ + ret = wc_KyberKey_EncapsulateWithRandom(key, c, k, m, sizeof(m)); + } + + /* Step 3: return ret != 0 on falsum or internal key generation failure. */ + return ret; +} + +/** + * Encapsulate with random data and derive secret. + * + * FIPS 203, Algorithm 17: ML-KEM.Encaps_internal(ek, m) + * Uses the encapsulation key and randomness to generate a key and an associated + * ciphertext. + * Step 1: (K,r) <- G(m||H(ek)) + * > derive shared secret key K and randomness r + * Step 2: c <- K-PPKE.Encrypt(ek, m, r) + * > encrypt m using K-PKE with randomness r + * Step 3: return (K,c) + * + * @param [out] c Cipher text. + * @param [out] k Shared secret generated. + * @param [in] m Random bytes. + * @param [in] len Length of random bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, c, k or RNG is NULL. + * @return BUFFER_E when len is not WC_ML_KEM_ENC_RAND_SZ. + * @return NOT_COMPILED_IN when key type is not supported. + * @return MEMORY_E when dynamic memory allocation failed. + */ +int wc_MlKemKey_EncapsulateWithRandom(MlKemKey* key, unsigned char* c, + unsigned char* k, const unsigned char* m, int len) +{ +#ifdef WOLFSSL_MLKEM_KYBER + byte msg[KYBER_SYM_SZ]; +#endif + byte kr[2 * KYBER_SYM_SZ + 1]; + int ret = 0; +#ifdef WOLFSSL_MLKEM_KYBER + unsigned int cSz = 0; +#endif + + /* Validate parameters. */ + if ((key == NULL) || (c == NULL) || (k == NULL) || (m == NULL)) { + ret = BAD_FUNC_ARG; + } + if ((ret == 0) && (len != WC_ML_KEM_ENC_RAND_SZ)) { + ret = BUFFER_E; + } + +#ifdef WOLFSSL_MLKEM_KYBER + if (ret == 0) { + /* Establish parameters based on key type. */ + switch (key->type) { +#ifndef WOLFSSL_NO_ML_KEM + #ifdef WOLFSSL_WC_ML_KEM_512 + case WC_ML_KEM_512: + #endif + #ifdef WOLFSSL_WC_ML_KEM_768 + case WC_ML_KEM_768: + #endif + #ifdef WOLFSSL_WC_ML_KEM_1024 + case WC_ML_KEM_1024: + #endif + break; +#endif + #ifdef WOLFSSL_KYBER512 + case KYBER512: + cSz = KYBER512_CIPHER_TEXT_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER768 + case KYBER768: + cSz = KYBER768_CIPHER_TEXT_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER1024 + case KYBER1024: + cSz = KYBER1024_CIPHER_TEXT_SIZE; + break; + #endif + default: + /* No other values supported. */ + ret = NOT_COMPILED_IN; + break; + } + } +#endif + + /* If public hash (h) is not stored against key, calculate it + * (fields set explicitly instead of using decode). + * Step 1: ... H(ek)... + */ + if ((ret == 0) && ((key->flags & MLKEM_FLAG_H_SET) == 0)) { + #ifndef WOLFSSL_NO_MALLOC + byte* pubKey = NULL; + word32 pubKeyLen; + #else + byte pubKey[WC_ML_KEM_MAX_PUBLIC_KEY_SIZE]; + word32 pubKeyLen = WC_ML_KEM_MAX_PUBLIC_KEY_SIZE; + #endif + + #ifndef WOLFSSL_NO_MALLOC + /* Determine how big an encoded public key will be. */ + ret = wc_KyberKey_PublicKeySize(key, &pubKeyLen); + if (ret == 0) { + /* Allocate dynamic memory for encoded public key. */ + pubKey = (byte*)XMALLOC(pubKeyLen, key->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (pubKey == NULL) { + ret = MEMORY_E; + } + } + if (ret == 0) { + #endif + /* Encode public key - h is hash of encoded public key. */ + ret = wc_KyberKey_EncodePublicKey(key, pubKey, pubKeyLen); + #ifndef WOLFSSL_NO_MALLOC + } + /* Dispose of encoded public key. */ + XFREE(pubKey, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + #endif + } + if ((ret == 0) && ((key->flags & MLKEM_FLAG_H_SET) == 0)) { + /* Implementation issue if h not cached and flag set. */ + ret = BAD_STATE_E; + } + +#ifdef WOLFSSL_MLKEM_KYBER + if (ret == 0) { +#ifndef WOLFSSL_NO_ML_KEM + if (key->type & MLKEM_KYBER) +#endif + { + /* Hash random to anonymize as seed data. */ + ret = MLKEM_HASH_H(&key->hash, m, WC_ML_KEM_SYM_SZ, msg); + } + } +#endif + if (ret == 0) { + /* Hash message into seed buffer. */ +#if defined(WOLFSSL_MLKEM_KYBER) && !defined(WOLFSSL_NO_ML_KEM) + if (key->type & MLKEM_KYBER) +#endif +#ifdef WOLFSSL_MLKEM_KYBER + { + ret = MLKEM_HASH_G(&key->hash, msg, WC_ML_KEM_SYM_SZ, key->h, + WC_ML_KEM_SYM_SZ, kr); + } +#endif +#if defined(WOLFSSL_MLKEM_KYBER) && !defined(WOLFSSL_NO_ML_KEM) + else +#endif +#ifndef WOLFSSL_NO_ML_KEM + { + /* Step 1: (K,r) <- G(m||H(ek)) */ + ret = MLKEM_HASH_G(&key->hash, m, WC_ML_KEM_SYM_SZ, key->h, + WC_ML_KEM_SYM_SZ, kr); + } +#endif + } + + if (ret == 0) { + /* Encapsulate the message using the key and the seed. */ +#if defined(WOLFSSL_MLKEM_KYBER) && !defined(WOLFSSL_NO_ML_KEM) + if (key->type & MLKEM_KYBER) +#endif +#ifdef WOLFSSL_MLKEM_KYBER + { + ret = mlkemkey_encapsulate(key, msg, kr + WC_ML_KEM_SYM_SZ, c); + } +#endif +#if defined(WOLFSSL_MLKEM_KYBER) && !defined(WOLFSSL_NO_ML_KEM) + else +#endif +#ifndef WOLFSSL_NO_ML_KEM + { + /* Step 2: c <- K-PKE.Encrypt(ek,m,r) */ + ret = mlkemkey_encapsulate(key, m, kr + WC_ML_KEM_SYM_SZ, c); + } +#endif + } + +#if defined(WOLFSSL_MLKEM_KYBER) && !defined(WOLFSSL_NO_ML_KEM) + if (key->type & MLKEM_KYBER) +#endif +#ifdef WOLFSSL_MLKEM_KYBER + { + if (ret == 0) { + /* Hash the cipher text after the seed. */ + ret = MLKEM_HASH_H(&key->hash, c, cSz, kr + WC_ML_KEM_SYM_SZ); + } + if (ret == 0) { + /* Derive the secret from the seed and hash of cipher text. */ + ret = MLKEM_KDF(kr, 2 * WC_ML_KEM_SYM_SZ, k, WC_ML_KEM_SS_SZ); + } + } +#endif +#if defined(WOLFSSL_MLKEM_KYBER) && !defined(WOLFSSL_NO_ML_KEM) + else +#endif +#ifndef WOLFSSL_NO_ML_KEM + { + if (ret == 0) { + /* return (K,c) */ + XMEMCPY(k, kr, WC_ML_KEM_SS_SZ); + } + } +#endif + + return ret; +} +#endif /* !WOLFSSL_MLKEM_NO_ENCAPSULATE */ + +/******************************************************************************/ + +#ifndef WOLFSSL_MLKEM_NO_DECAPSULATE +/* Decapsulate cipher text to the message using key. + * + * FIPS 203, Algorithm 15: K-PKE.Decrypt(dk_PKE,c) + * Uses the decryption key to decrypt a ciphertext. + * 1: c1 <- c[0 : 32.d_u.k] + * 2: c2 <= c[32.d_u.k : 32(d_u.k + d_v)] + * 3: u' <= Decompress_d_u(ByteDecode_d_u(c1)) + * 4: v' <= Decompress_d_v(ByteDecode_d_v(c2)) + * ... + * 6: w <- v' - InvNTT(s_hat_trans o NTT(u')) + * 7: m <- ByteEncode_1(Compress_1(w)) + * 8: return m + * + * @param [in] key Kyber key object. + * @param [out] m Message than was encapsulated. + * @param [in] c Cipher text. + * @return 0 on success. + * @return NOT_COMPILED_IN when key type is not supported. + * @return MEMORY_E when dynamic memory allocation failed. + */ +static MLKEM_NOINLINE int mlkemkey_decapsulate(MlKemKey* key, byte* m, + const byte* c) +{ + int ret = 0; + sword16* v; + sword16* w; + unsigned int k = 0; + unsigned int compVecSz; +#if !defined(USE_INTEL_SPEEDUP) && !defined(WOLFSSL_NO_MALLOC) + sword16* u = NULL; +#else + sword16 u[(WC_ML_KEM_MAX_K + 1) * MLKEM_N]; +#endif + + /* Establish parameters based on key type. */ + switch (key->type) { +#ifndef WOLFSSL_NO_ML_KEM +#ifdef WOLFSSL_WC_ML_KEM_512 + case WC_ML_KEM_512: + k = WC_ML_KEM_512_K; + compVecSz = WC_ML_KEM_512_POLY_VEC_COMPRESSED_SZ; + break; +#endif +#ifdef WOLFSSL_WC_ML_KEM_768 + case WC_ML_KEM_768: + k = WC_ML_KEM_768_K; + compVecSz = WC_ML_KEM_768_POLY_VEC_COMPRESSED_SZ; + break; +#endif +#ifdef WOLFSSL_WC_ML_KEM_1024 + case WC_ML_KEM_1024: + k = WC_ML_KEM_1024_K; + compVecSz = WC_ML_KEM_1024_POLY_VEC_COMPRESSED_SZ; + break; +#endif +#endif +#ifdef WOLFSSL_MLKEM_KYBER +#ifdef WOLFSSL_KYBER512 + case KYBER512: + k = KYBER512_K; + compVecSz = KYBER512_POLY_VEC_COMPRESSED_SZ; + break; +#endif +#ifdef WOLFSSL_KYBER768 + case KYBER768: + k = KYBER768_K; + compVecSz = KYBER768_POLY_VEC_COMPRESSED_SZ; + break; +#endif +#ifdef WOLFSSL_KYBER1024 + case KYBER1024: + k = KYBER1024_K; + compVecSz = KYBER1024_POLY_VEC_COMPRESSED_SZ; + break; +#endif +#endif + default: + /* No other values supported. */ + ret = NOT_COMPILED_IN; + break; + } + +#if !defined(USE_INTEL_SPEEDUP) && !defined(WOLFSSL_NO_MALLOC) + if (ret == 0) { + /* Allocate dynamic memory for a vector and a polynomial. */ + u = (sword16*)XMALLOC((k + 1) * MLKEM_N * sizeof(sword16), key->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (u == NULL) { + ret = MEMORY_E; + } + } +#endif + if (ret == 0) { + /* Step 1: c1 <- c[0 : 32.d_u.k] */ + const byte* c1 = c; + /* Step 2: c2 <= c[32.d_u.k : 32(d_u.k + d_v)] */ + const byte* c2 = c + compVecSz; + + /* Assign allocated dynamic memory to pointers. + * u (v) | v (p) */ + v = u + k * MLKEM_N; + w = u; + + #if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) + if (k == WC_ML_KEM_512_K) { + /* Step 3: u' <= Decompress_d_u(ByteDecode_d_u(c1)) */ + mlkem_vec_decompress_10(u, c1, k); + /* Step 4: v' <= Decompress_d_v(ByteDecode_d_v(c2)) */ + mlkem_decompress_4(v, c2); + } + #endif + #if defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768) + if (k == WC_ML_KEM_768_K) { + /* Step 3: u' <= Decompress_d_u(ByteDecode_d_u(c1)) */ + mlkem_vec_decompress_10(u, c1, k); + /* Step 4: v' <= Decompress_d_v(ByteDecode_d_v(c2)) */ + mlkem_decompress_4(v, c2); + } + #endif + #if defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) + if (k == WC_ML_KEM_1024_K) { + /* Step 3: u' <= Decompress_d_u(ByteDecode_d_u(c1)) */ + mlkem_vec_decompress_11(u, c1); + /* Step 4: v' <= Decompress_d_v(ByteDecode_d_v(c2)) */ + mlkem_decompress_5(v, c2); + } + #endif + + /* Decapsulate the cipher text into polynomial. + * Step 6: w <- v' - InvNTT(s_hat_trans o NTT(u')) */ + mlkem_decapsulate(key->priv, w, u, v, k); + + /* Convert the polynomial into a array of bytes (message). + * Step 7: m <- ByteEncode_1(Compress_1(w)) */ + mlkem_to_msg(m, w); + /* Step 8: return m */ + } + +#if !defined(USE_INTEL_SPEEDUP) && !defined(WOLFSSL_NO_MALLOC) + /* Dispose of dynamically memory allocated in function. */ + XFREE(u, key->heap, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + +/** + * Decapsulate the cipher text to calculate the shared secret. + * + * Validates the cipher text by encapsulating and comparing with data passed in. + * + * FIPS 203, Algorithm 21: ML-KEM.Decaps(dk, c) + * Uses the decapsulation key to produce a shared secret key from a ciphertext. + * 1: K' <- ML-KEM.Decaps_internal(dk,c) + * > run internal decapsulation algorithm + * 2: return K' + * + * FIPS 203, Algorithm 18: ML-KEM.Decaps_internal(dk, c) + * Uses the decapsulation key to produce a shared secret key from a ciphertext. + * ... + * 1: dk_PKE <- dk[0 : 384k] + * > extract (from KEM decaps key) the PKE decryption key + * 2: ek_PKE <- dk[384k : 768l + 32] + * > extract PKE encryption key + * 3: h <- dk[768K + 32 : 768k + 64] + * > extract hash of PKE encryption key + * 4: z <- dk[768K + 64 : 768k + 96] + * > extract implicit rejection value + * 5: m' <- K-PKE.Decrypt(dk_PKE, c) > decrypt ciphertext + * 6: (K', r') <- G(m'||h) + * 7: K_bar <- J(z||c) + * 8: c' <- K-PKE.Encrypt(ek_PKE, m', r') + * > re-encrypt using the derived randomness r' + * 9: if c != c' then + * 10: K' <= K_bar + * > if ciphertexts do not match, "implicitly reject" + * 11: end if + * 12: return K' + * + * @param [in] key Kyber key object. + * @param [out] ss Shared secret. + * @param [in] ct Cipher text. + * @param [in] len Length of cipher text. + * @return 0 on success. + * @return BAD_FUNC_ARG when key, ss or cr are NULL. + * @return NOT_COMPILED_IN when key type is not supported. + * @return BUFFER_E when len is not the length of cipher text for the key type. + * @return MEMORY_E when dynamic memory allocation failed. + */ +int wc_MlKemKey_Decapsulate(MlKemKey* key, unsigned char* ss, + const unsigned char* ct, word32 len) +{ + byte msg[WC_ML_KEM_SYM_SZ]; + byte kr[2 * WC_ML_KEM_SYM_SZ + 1]; + int ret = 0; + unsigned int ctSz = 0; + unsigned int i = 0; + int fail = 0; +#if !defined(USE_INTEL_SPEEDUP) && !defined(WOLFSSL_NO_MALLOC) + byte* cmp = NULL; +#else + byte cmp[WC_ML_KEM_MAX_CIPHER_TEXT_SIZE]; +#endif + + /* Validate parameters. */ + if ((key == NULL) || (ss == NULL) || (ct == NULL)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + /* Establish cipher text size based on key type. */ + switch (key->type) { +#ifndef WOLFSSL_NO_ML_KEM + #ifdef WOLFSSL_WC_ML_KEM_512 + case WC_ML_KEM_512: + ctSz = WC_ML_KEM_512_CIPHER_TEXT_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_768 + case WC_ML_KEM_768: + ctSz = WC_ML_KEM_768_CIPHER_TEXT_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_1024 + case WC_ML_KEM_1024: + ctSz = WC_ML_KEM_1024_CIPHER_TEXT_SIZE; + break; + #endif +#endif +#ifdef WOLFSSL_MLKEM_KYBER + #ifdef WOLFSSL_KYBER512 + case KYBER512: + ctSz = KYBER512_CIPHER_TEXT_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER768 + case KYBER768: + ctSz = KYBER768_CIPHER_TEXT_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER1024 + case KYBER1024: + ctSz = KYBER1024_CIPHER_TEXT_SIZE; + break; + #endif +#endif + default: + /* No other values supported. */ + ret = NOT_COMPILED_IN; + break; + } + } + + /* Ensure the cipher text passed in is the correct size. */ + if ((ret == 0) && (len != ctSz)) { + ret = BUFFER_E; + } + +#if !defined(USE_INTEL_SPEEDUP) && !defined(WOLFSSL_NO_MALLOC) + if (ret == 0) { + /* Allocate memory for cipher text that is generated. */ + cmp = (byte*)XMALLOC(ctSz, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (cmp == NULL) { + ret = MEMORY_E; + } + } +#endif + + if (ret == 0) { + /* Decapsulate the cipher text. */ + ret = mlkemkey_decapsulate(key, msg, ct); + } + if (ret == 0) { + /* Hash message into seed buffer. */ + ret = MLKEM_HASH_G(&key->hash, msg, WC_ML_KEM_SYM_SZ, key->h, + WC_ML_KEM_SYM_SZ, kr); + } + if (ret == 0) { + /* Encapsulate the message. */ + ret = mlkemkey_encapsulate(key, msg, kr + WC_ML_KEM_SYM_SZ, cmp); + } + if (ret == 0) { + /* Compare generated cipher text with that passed in. */ + fail = mlkem_cmp(ct, cmp, ctSz); + +#if defined(WOLFSSL_MLKEM_KYBER) && !defined(WOLFSSL_NO_ML_KEM) + if (key->type & MLKEM_KYBER) +#endif +#ifdef WOLFSSL_MLKEM_KYBER + { + /* Hash the cipher text after the seed. */ + ret = MLKEM_HASH_H(&key->hash, ct, ctSz, kr + WC_ML_KEM_SYM_SZ); + if (ret == 0) { + /* Change seed to z on comparison failure. */ + for (i = 0; i < WC_ML_KEM_SYM_SZ; i++) { + kr[i] ^= (kr[i] ^ key->z[i]) & fail; + } + + /* Derive the secret from the seed and hash of cipher text. */ + ret = MLKEM_KDF(kr, 2 * WC_ML_KEM_SYM_SZ, ss, WC_ML_KEM_SS_SZ); + } + } +#endif +#if defined(WOLFSSL_MLKEM_KYBER) && !defined(WOLFSSL_NO_ML_KEM) + else +#endif +#ifndef WOLFSSL_NO_ML_KEM + { + ret = mlkem_derive_secret(&key->prf, key->z, ct, ctSz, msg); + if (ret == 0) { + /* Set secret to kr or fake secret on comparison failure. */ + for (i = 0; i < WC_ML_KEM_SYM_SZ; i++) { + ss[i] = kr[i] ^ ((kr[i] ^ msg[i]) & fail); + } + } + } +#endif + } + +#if !defined(USE_INTEL_SPEEDUP) && !defined(WOLFSSL_NO_MALLOC) + /* Dispose of dynamic memory allocated in function. */ + if (key != NULL) { + XFREE(cmp, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + + return ret; +} +#endif /* WOLFSSL_MLKEM_NO_DECAPSULATE */ + +/******************************************************************************/ + +/** + * Get the public key and public seed from bytes. + * + * FIPS 203, Algorithm 14 K-PKE.Encrypt(ek_PKE, m, r) + * ... + * 2: t <- ByteDecode_12(ek_PKE[0 : 384k]) + * 3: rho <- ek_PKE[384k : 384k + 32] + * ... + * + * @param [out] pub Public key - vector. + * @param [out] pubSeed Public seed. + * @param [in] p Public key data. + * @param [in] k Number of polynomials in vector. + */ +static void mlkemkey_decode_public(sword16* pub, byte* pubSeed, const byte* p, + unsigned int k) +{ + unsigned int i; + + /* Decode public key that is vector of polynomials. + * Step 2: t <- ByteDecode_12(ek_PKE[0 : 384k]) */ + mlkem_from_bytes(pub, p, k); + p += k * WC_ML_KEM_POLY_SIZE; + + /* Read public key seed. + * Step 3: rho <- ek_PKE[384k : 384k + 32] */ + for (i = 0; i < WC_ML_KEM_SYM_SZ; i++) { + pubSeed[i] = p[i]; + } +} + +/** + * Decode the private key. + * + * Private Vector | Public Key | Public Hash | Randomizer + * + * FIPS 203, Algorithm 18: ML-KEM.Decaps_internal(dk, c) + * 1: dk_PKE <- dk[0 : 384k] + * > extract (from KEM decaps key) the PKE decryption key + * 2: ek_PKE <- dk[384k : 768l + 32] + * > extract PKE encryption key + * 3: h <- dk[768K + 32 : 768k + 64] + * > extract hash of PKE encryption key + * 4: z <- dk[768K + 64 : 768k + 96] + * > extract implicit rejection value + * + * FIPS 203, Algorithm 15: K-PKE.Decrypt(dk_PKE, c) + * ... + * 5: s_hat <= ByteDecode_12(dk_PKE) + * ... + * + * @param [in, out] key Kyber key object. + * @param [in] in Buffer holding encoded key. + * @param [in] len Length of data in buffer. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or in is NULL. + * @return NOT_COMPILED_IN when key type is not supported. + * @return BUFFER_E when len is not the correct size. + */ +int wc_MlKemKey_DecodePrivateKey(MlKemKey* key, const unsigned char* in, + word32 len) +{ + int ret = 0; + word32 privLen = 0; + word32 pubLen = 0; + unsigned int k = 0; + const unsigned char* p = in; + + /* Validate parameters. */ + if ((key == NULL) || (in == NULL)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + /* Establish parameters based on key type. */ + switch (key->type) { +#ifndef WOLFSSL_NO_ML_KEM + #ifdef WOLFSSL_WC_ML_KEM_512 + case WC_ML_KEM_512: + k = WC_ML_KEM_512_K; + privLen = WC_ML_KEM_512_PRIVATE_KEY_SIZE; + pubLen = WC_ML_KEM_512_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_768 + case WC_ML_KEM_768: + k = WC_ML_KEM_768_K; + privLen = WC_ML_KEM_768_PRIVATE_KEY_SIZE; + pubLen = WC_ML_KEM_768_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_1024 + case WC_ML_KEM_1024: + k = WC_ML_KEM_1024_K; + privLen = WC_ML_KEM_1024_PRIVATE_KEY_SIZE; + pubLen = WC_ML_KEM_1024_PUBLIC_KEY_SIZE; + break; + #endif +#endif +#ifdef WOLFSSL_MLKEM_KYBER + #ifdef WOLFSSL_KYBER512 + case KYBER512: + k = KYBER512_K; + privLen = KYBER512_PRIVATE_KEY_SIZE; + pubLen = KYBER512_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER768 + case KYBER768: + k = KYBER768_K; + privLen = KYBER768_PRIVATE_KEY_SIZE; + pubLen = KYBER768_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER1024 + case KYBER1024: + k = KYBER1024_K; + privLen = KYBER1024_PRIVATE_KEY_SIZE; + pubLen = KYBER1024_PUBLIC_KEY_SIZE; + break; + #endif +#endif + default: + /* No other values supported. */ + ret = NOT_COMPILED_IN; + break; + } + } + /* Ensure the data is the correct length for the key type. */ + if ((ret == 0) && (len != privLen)) { + ret = BUFFER_E; + } + + if (ret == 0) { + /* Decode private key that is vector of polynomials. + * Alg 18 Step 1: dk_PKE <- dk[0 : 384k] + * Alg 15 Step 5: s_hat <- ByteDecode_12(dk_PKE) */ + mlkem_from_bytes(key->priv, p, k); + p += k * WC_ML_KEM_POLY_SIZE; + + /* Decode the public key that is after the private key. */ + mlkemkey_decode_public(key->pub, key->pubSeed, p, k); + p += pubLen; + + /* Copy the hash of the encoded public key that is after public key. */ + XMEMCPY(key->h, p, sizeof(key->h)); + p += WC_ML_KEM_SYM_SZ; + /* Copy the z (randomizer) that is after hash. */ + XMEMCPY(key->z, p, sizeof(key->z)); + + /* Set flags */ + key->flags |= MLKEM_FLAG_H_SET | MLKEM_FLAG_BOTH_SET; + } + + return ret; +} + +/** + * Decode public key. + * + * Public vector | Public Seed + * + * @param [in, out] key Kyber key object. + * @param [in] in Buffer holding encoded key. + * @param [in] len Length of data in buffer. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or in is NULL. + * @return NOT_COMPILED_IN when key type is not supported. + * @return BUFFER_E when len is not the correct size. + */ +int wc_MlKemKey_DecodePublicKey(MlKemKey* key, const unsigned char* in, + word32 len) +{ + int ret = 0; + word32 pubLen = 0; + unsigned int k = 0; + const unsigned char* p = in; + + if ((key == NULL) || (in == NULL)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + /* Establish parameters based on key type. */ + switch (key->type) { +#ifndef WOLFSSL_NO_ML_KEM + #ifdef WOLFSSL_WC_ML_KEM_512 + case WC_ML_KEM_512: + k = WC_ML_KEM_512_K; + pubLen = WC_ML_KEM_512_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_768 + case WC_ML_KEM_768: + k = WC_ML_KEM_768_K; + pubLen = WC_ML_KEM_768_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_1024 + case WC_ML_KEM_1024: + k = WC_ML_KEM_1024_K; + pubLen = WC_ML_KEM_1024_PUBLIC_KEY_SIZE; + break; + #endif +#endif +#ifdef WOLFSSL_MLKEM_KYBER + #ifdef WOLFSSL_KYBER512 + case KYBER512: + k = KYBER512_K; + pubLen = KYBER512_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER768 + case KYBER768: + k = KYBER768_K; + pubLen = KYBER768_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER1024 + case KYBER1024: + k = KYBER1024_K; + pubLen = KYBER1024_PUBLIC_KEY_SIZE; + break; + #endif +#endif + default: + /* No other values supported. */ + ret = NOT_COMPILED_IN; + break; + } + } + /* Ensure the data is the correct length for the key type. */ + if ((ret == 0) && (len != pubLen)) { + ret = BUFFER_E; + } + + if (ret == 0) { + mlkemkey_decode_public(key->pub, key->pubSeed, p, k); + + /* Calculate public hash. */ + ret = MLKEM_HASH_H(&key->hash, in, len, key->h); + } + if (ret == 0) { + /* Record public key and public hash set. */ + key->flags |= MLKEM_FLAG_PUB_SET | MLKEM_FLAG_H_SET; + } + + return ret; +} + +/** + * Get the size in bytes of encoded private key for the key. + * + * @param [in] key Kyber key object. + * @param [out] len Length of encoded private key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or len is NULL. + * @return NOT_COMPILED_IN when key type is not supported. + */ +int wc_MlKemKey_PrivateKeySize(MlKemKey* key, word32* len) +{ + int ret = 0; + + /* Validate parameters. */ + if ((key == NULL) || (len == NULL)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + /* Return in 'len' size of the encoded private key for the type of this + * key. */ + switch (key->type) { +#ifndef WOLFSSL_NO_ML_KEM + #ifdef WOLFSSL_WC_ML_KEM_512 + case WC_ML_KEM_512: + *len = WC_ML_KEM_512_PRIVATE_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_768 + case WC_ML_KEM_768: + *len = WC_ML_KEM_768_PRIVATE_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_1024 + case WC_ML_KEM_1024: + *len = WC_ML_KEM_1024_PRIVATE_KEY_SIZE; + break; + #endif +#endif +#ifdef WOLFSSL_MLKEM_KYBER + #ifdef WOLFSSL_KYBER512 + case KYBER512: + *len = KYBER512_PRIVATE_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER768 + case KYBER768: + *len = KYBER768_PRIVATE_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER1024 + case KYBER1024: + *len = KYBER1024_PRIVATE_KEY_SIZE; + break; + #endif +#endif + default: + /* No other values supported. */ + ret = NOT_COMPILED_IN; + break; + } + } + + return ret; +} + +/** + * Get the size in bytes of encoded public key for the key. + * + * @param [in] key Kyber key object. + * @param [out] len Length of encoded public key in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or len is NULL. + * @return NOT_COMPILED_IN when key type is not supported. + */ +int wc_MlKemKey_PublicKeySize(MlKemKey* key, word32* len) +{ + int ret = 0; + + /* Validate parameters. */ + if ((key == NULL) || (len == NULL)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + /* Return in 'len' size of the encoded public key for the type of this + * key. */ + switch (key->type) { +#ifndef WOLFSSL_NO_ML_KEM + #ifdef WOLFSSL_WC_ML_KEM_512 + case WC_ML_KEM_512: + *len = WC_ML_KEM_512_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_768 + case WC_ML_KEM_768: + *len = WC_ML_KEM_768_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_1024 + case WC_ML_KEM_1024: + *len = WC_ML_KEM_1024_PUBLIC_KEY_SIZE; + break; + #endif +#endif +#ifdef WOLFSSL_MLKEM_KYBER + #ifdef WOLFSSL_KYBER512 + case KYBER512: + *len = KYBER512_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER768 + case KYBER768: + *len = KYBER768_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER1024 + case KYBER1024: + *len = KYBER1024_PUBLIC_KEY_SIZE; + break; + #endif +#endif + default: + /* No other values supported. */ + ret = NOT_COMPILED_IN; + break; + } + } + + return ret; +} + +/** + * Encode the private key. + * + * Private Vector | Public Key | Public Hash | Randomizer + * + * FIPS 203, Algorithm 16: ML-KEM.KeyGen_internal(d,z) + * ... + * 3: dk <- (dk_PKE||ek||H(ek)||z) + * ... + * FIPS 203, Algorithm 13: K-PKE.KeyGen(d) + * ... + * 20: dk_PKE <- ByteEncode_12(s_hat) + * ... + * + * @param [in] key Kyber key object. + * @param [out] out Buffer to hold data. + * @param [in] len Size of buffer in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or out is NULL or private/public key not + * available. + * @return NOT_COMPILED_IN when key type is not supported. + */ +int wc_MlKemKey_EncodePrivateKey(MlKemKey* key, unsigned char* out, word32 len) +{ + int ret = 0; + unsigned int k = 0; + unsigned int pubLen = 0; + unsigned int privLen = 0; + unsigned char* p = out; + + if ((key == NULL) || (out == NULL)) { + ret = BAD_FUNC_ARG; + } + if ((ret == 0) && + ((key->flags & MLKEM_FLAG_BOTH_SET) != MLKEM_FLAG_BOTH_SET)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + switch (key->type) { +#ifndef WOLFSSL_NO_ML_KEM + #ifdef WOLFSSL_WC_ML_KEM_512 + case WC_ML_KEM_512: + k = WC_ML_KEM_512_K; + pubLen = WC_ML_KEM_512_PUBLIC_KEY_SIZE; + privLen = WC_ML_KEM_512_PRIVATE_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_768 + case WC_ML_KEM_768: + k = WC_ML_KEM_768_K; + pubLen = WC_ML_KEM_768_PUBLIC_KEY_SIZE; + privLen = WC_ML_KEM_768_PRIVATE_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_1024 + case WC_ML_KEM_1024: + k = WC_ML_KEM_1024_K; + pubLen = WC_ML_KEM_1024_PUBLIC_KEY_SIZE; + privLen = WC_ML_KEM_1024_PRIVATE_KEY_SIZE; + break; + #endif +#endif +#ifdef WOLFSSL_MLKEM_KYBER + #ifdef WOLFSSL_KYBER512 + case KYBER512: + k = KYBER512_K; + pubLen = KYBER512_PUBLIC_KEY_SIZE; + privLen = KYBER512_PRIVATE_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER768 + case KYBER768: + k = KYBER768_K; + pubLen = KYBER768_PUBLIC_KEY_SIZE; + privLen = KYBER768_PRIVATE_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER1024 + case KYBER1024: + k = KYBER1024_K; + pubLen = KYBER1024_PUBLIC_KEY_SIZE; + privLen = KYBER1024_PRIVATE_KEY_SIZE; + break; + #endif +#endif + default: + /* No other values supported. */ + ret = NOT_COMPILED_IN; + break; + } + } + /* Check buffer is big enough for encoding. */ + if ((ret == 0) && (len != privLen)) { + ret = BUFFER_E; + } + + if (ret == 0) { + /* Encode private key that is vector of polynomials. */ + mlkem_to_bytes(p, key->priv, k); + p += WC_ML_KEM_POLY_SIZE * k; + + /* Encode public key. */ + ret = wc_KyberKey_EncodePublicKey(key, p, pubLen); + p += pubLen; + } + /* Ensure hash of public key is available. */ + if ((ret == 0) && ((key->flags & MLKEM_FLAG_H_SET) == 0)) { + ret = MLKEM_HASH_H(&key->hash, p - pubLen, pubLen, key->h); + } + if (ret == 0) { + /* Public hash is available. */ + key->flags |= MLKEM_FLAG_H_SET; + /* Append public hash. */ + XMEMCPY(p, key->h, sizeof(key->h)); + p += WC_ML_KEM_SYM_SZ; + /* Append z (randomizer). */ + XMEMCPY(p, key->z, sizeof(key->z)); + } + + return ret; +} + +/** + * Encode the public key. + * + * Public vector | Public Seed + * + * FIPS 203, Algorithm 16: ML-KEM.KeyGen_internal(d,z) + * ... + * 2: ek <- ek_PKE + * ... + * FIPS 203, Algorithm 13: K-PKE.KeyGen(d) + * ... + * 19: ek_PKE <- ByteEncode_12(t_hat)||rho + * ... + * + * @param [in] key Kyber key object. + * @param [out] out Buffer to hold data. + * @param [in] len Size of buffer in bytes. + * @return 0 on success. + * @return BAD_FUNC_ARG when key or out is NULL or public key not available. + * @return NOT_COMPILED_IN when key type is not supported. + */ +int wc_MlKemKey_EncodePublicKey(MlKemKey* key, unsigned char* out, word32 len) +{ + int ret = 0; + unsigned int k = 0; + unsigned int pubLen = 0; + unsigned char* p = out; + + if ((key == NULL) || (out == NULL)) { + ret = BAD_FUNC_ARG; + } + if ((ret == 0) && + ((key->flags & MLKEM_FLAG_PUB_SET) != MLKEM_FLAG_PUB_SET)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + switch (key->type) { +#ifndef WOLFSSL_NO_ML_KEM + #ifdef WOLFSSL_WC_ML_KEM_512 + case WC_ML_KEM_512: + k = WC_ML_KEM_512_K; + pubLen = WC_ML_KEM_512_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_768 + case WC_ML_KEM_768: + k = WC_ML_KEM_768_K; + pubLen = WC_ML_KEM_768_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_WC_ML_KEM_1024 + case WC_ML_KEM_1024: + k = WC_ML_KEM_1024_K; + pubLen = WC_ML_KEM_1024_PUBLIC_KEY_SIZE; + break; + #endif +#endif +#ifdef WOLFSSL_MLKEM_KYBER + #ifdef WOLFSSL_KYBER512 + case KYBER512: + k = KYBER512_K; + pubLen = KYBER512_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER768 + case KYBER768: + k = KYBER768_K; + pubLen = KYBER768_PUBLIC_KEY_SIZE; + break; + #endif + #ifdef WOLFSSL_KYBER1024 + case KYBER1024: + k = KYBER1024_K; + pubLen = KYBER1024_PUBLIC_KEY_SIZE; + break; + #endif +#endif + default: + /* No other values supported. */ + ret = NOT_COMPILED_IN; + break; + } + } + /* Check buffer is big enough for encoding. */ + if ((ret == 0) && (len != pubLen)) { + ret = BUFFER_E; + } + + if (ret == 0) { + int i; + + /* Encode public key polynomial by polynomial. */ + mlkem_to_bytes(p, key->pub, k); + p += k * WC_ML_KEM_POLY_SIZE; + + /* Append public seed. */ + for (i = 0; i < WC_ML_KEM_SYM_SZ; i++) { + p[i] = key->pubSeed[i]; + } + + /* Make sure public hash is set. */ + if ((key->flags & MLKEM_FLAG_H_SET) == 0) { + ret = MLKEM_HASH_H(&key->hash, out, len, key->h); + } + } + if (ret == 0) { + /* Public hash is set. */ + key->flags |= MLKEM_FLAG_H_SET; + } + + return ret; +} + +#endif /* WOLFSSL_WC_MLKEM */ diff --git a/src/wolfcrypt/src/wc_mlkem_poly.c b/src/wolfcrypt/src/wc_mlkem_poly.c new file mode 100644 index 0000000..e5f4a18 --- /dev/null +++ b/src/wolfcrypt/src/wc_mlkem_poly.c @@ -0,0 +1,5986 @@ +/* wc_mlkem_poly.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 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Implementation based on FIPS 203: + * https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf + * + * Original implementation based on NIST 3rd Round submission package. + * See link at: + * https://csrc.nist.gov/Projects/post-quantum-cryptography/ + * post-quantum-cryptography-standardization/round-3-submissions + */ + +/* Implementation of the functions that operate on polynomials or vectors of + * polynomials. + */ + +/* Possible Kyber options: + * + * WOLFSSL_WC_MLKEM Default: OFF + * Enables this code, wolfSSL implementation, to be built. + * + * WOLFSSL_WC_ML_KEM_512 Default: OFF + * Enables the ML-KEM 512 parameter implementations. + * WOLFSSL_WC_ML_KEM_768 Default: OFF + * Enables the ML-KEM 768 parameter implementations. + * WOLFSSL_WC_ML_KEM_1024 Default: OFF + * Enables the ML-KEM 1024 parameter implementations. + * WOLFSSL_KYBER512 Default: OFF + * Enables the KYBER512 parameter implementations. + * WOLFSSL_KYBER768 Default: OFF + * Enables the KYBER768 parameter implementations. + * WOLFSSL_KYBER1024 Default: OFF + * Enables the KYBER1024 parameter implementations. + * + * USE_INTEL_SPEEDUP Default: OFF + * Compiles in Intel x64 specific implementations that are faster. + * WOLFSSL_MLKEM_NO_LARGE_CODE Default: OFF + * Compiles smaller, fast code size with a speed trade-off. + * WOLFSSL_MLKEM_SMALL Default: OFF + * Compiles to small code size with a speed trade-off. + * WOLFSSL_SMALL_STACK Default: OFF + * Use less stack by dynamically allocating local variables. + * + * WOLFSSL_MLKEM_NTT_UNROLL Default: OFF + * Enable an alternative NTT implementation that may be faster on some + * platforms and is smaller in code size. + * WOLFSSL_MLKEM_INVNTT_UNROLL Default: OFF + * Enables an alternative inverse NTT implementation that may be faster on + * some platforms and is smaller in code size. + */ + +#include + +#include +#include + +#ifdef WOLFSSL_WC_MLKEM + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#if defined(WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM) || \ + defined(WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM) +static int mlkem_gen_matrix_i(MLKEM_PRF_T* prf, sword16* a, int k, byte* seed, + int i, int transposed); +static int mlkem_get_noise_i(MLKEM_PRF_T* prf, int k, sword16* vec2, + byte* seed, int i, int make); +static int mlkem_get_noise_eta2_c(MLKEM_PRF_T* prf, sword16* p, + const byte* seed); +#endif + +/* Declared in wc_mlkem.c to stop compiler optimizer from simplifying. */ +extern volatile sword16 mlkem_opt_blocker; + +#if defined(USE_INTEL_SPEEDUP) || (defined(__aarch64__) && \ + defined(WOLFSSL_ARMASM)) +static word32 cpuid_flags = 0; +#endif + +/* Half of Q plus one. Converted message bit value of 1. */ +#define MLKEM_Q_1_HALF ((MLKEM_Q + 1) / 2) +/* Half of Q */ +#define MLKEM_Q_HALF (MLKEM_Q / 2) + + +/* q^-1 mod 2^16 (inverse of 3329 mod 16384) */ +#define MLKEM_QINV 62209 + +/* Used in Barrett Reduction: + * r = a mod q + * => r = a - ((V * a) >> 26) * q), as V based on 2^26 + * V is the multiplier that gets the quotient after shifting. + */ +#define MLKEM_V (((1U << 26) + (MLKEM_Q / 2)) / MLKEM_Q) + +/* Used in converting to Montgomery form. + * f is the normalizer = 2^k % m. + * 16-bit value cast to sword32 in use. + */ +#define MLKEM_F ((1ULL << 32) % MLKEM_Q) + +/* Number of bytes in an output block of SHA-3-128 */ +#define SHA3_128_BYTES (WC_SHA3_128_COUNT * 8) +/* Number of bytes in an output block of SHA-3-256 */ +#define SHA3_256_BYTES (WC_SHA3_256_COUNT * 8) + +/* Number of blocks to generate for matrix. */ +#define GEN_MATRIX_NBLOCKS \ + ((12 * MLKEM_N / 8 * (1 << 12) / MLKEM_Q + XOF_BLOCK_SIZE) / XOF_BLOCK_SIZE) +/* Number of bytes to generate for matrix. */ +#define GEN_MATRIX_SIZE GEN_MATRIX_NBLOCKS * XOF_BLOCK_SIZE + + +/* Number of random bytes to generate for ETA3. */ +#define ETA3_RAND_SIZE ((3 * MLKEM_N) / 4) +/* Number of random bytes to generate for ETA2. */ +#define ETA2_RAND_SIZE ((2 * MLKEM_N) / 4) + + +/* Montgomery reduce a. + * + * @param [in] a 32-bit value to be reduced. + * @return Montgomery reduction result. + */ +#define MLKEM_MONT_RED(a) \ + (sword16)(((a) - (sword32)(((sword16)((sword16)(a) * \ + (sword16)MLKEM_QINV)) * \ + (sword32)MLKEM_Q)) >> 16) + +/* Barrett reduce a. r = a mod q. + * + * Converted division to multiplication. + * + * @param [in] a 16-bit value to be reduced to range of q. + * @return Modulo result. + */ +#define MLKEM_BARRETT_RED(a) \ + (sword16)((sword16)(a) - (sword16)((sword16)( \ + ((sword32)((sword32)MLKEM_V * (sword16)(a))) >> 26) * (word16)MLKEM_Q)) + + +/* Zetas for NTT. */ +const sword16 zetas[MLKEM_N / 2] = { + 2285, 2571, 2970, 1812, 1493, 1422, 287, 202, + 3158, 622, 1577, 182, 962, 2127, 1855, 1468, + 573, 2004, 264, 383, 2500, 1458, 1727, 3199, + 2648, 1017, 732, 608, 1787, 411, 3124, 1758, + 1223, 652, 2777, 1015, 2036, 1491, 3047, 1785, + 516, 3321, 3009, 2663, 1711, 2167, 126, 1469, + 2476, 3239, 3058, 830, 107, 1908, 3082, 2378, + 2931, 961, 1821, 2604, 448, 2264, 677, 2054, + 2226, 430, 555, 843, 2078, 871, 1550, 105, + 422, 587, 177, 3094, 3038, 2869, 1574, 1653, + 3083, 778, 1159, 3182, 2552, 1483, 2727, 1119, + 1739, 644, 2457, 349, 418, 329, 3173, 3254, + 817, 1097, 603, 610, 1322, 2044, 1864, 384, + 2114, 3193, 1218, 1994, 2455, 220, 2142, 1670, + 2144, 1799, 2051, 794, 1819, 2475, 2459, 478, + 3221, 3021, 996, 991, 958, 1869, 1522, 1628 +}; + + +#if !defined(WOLFSSL_ARMASM) +/* Number-Theoretic Transform. + * + * FIPS 203, Algorithm 9: NTT(f) + * Computes the NTT representation f_hat of the given polynomial f element of + * R_q. + * 1: f_hat <- f + * 2: i <- 1 + * 3: for (len <- 128; len >= 2; len <- len/2) + * 4: for (start <- 0; start < 256; start <- start + 2.len) + * 5: zeta <- zetas^BitRev_7(i) mod q + * 6: i <- i + 1 + * 7: for (j <- start; j < start + len; j++) + * 8: t <- zeta.f[j+len] + * 9: f_hat[j+len] <- f_hat[j] - t + * 10: f_hat[j] <- f_hat[j] - t + * 11: end for + * 12: end for + * 13: end for + * 14: return f_hat + * + * @param [in, out] r Polynomial to transform. + */ +static void mlkem_ntt(sword16* r) +{ +#ifdef WOLFSSL_MLKEM_SMALL + unsigned int len; + unsigned int k; + unsigned int j; + + /* Step 2 */ + k = 1; + /* Step 3 */ + for (len = MLKEM_N / 2; len >= 2; len >>= 1) { + unsigned int start; + /* Step 4 */ + for (start = 0; start < MLKEM_N; start = j + len) { + /* Step 5, 6*/ + sword16 zeta = zetas[k++]; + /* Step 7 */ + for (j = start; j < start + len; ++j) { + /* Step 8 */ + sword32 p = (sword32)zeta * r[j + len]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[j]; + /* Step 9 */ + r[j + len] = rj - t; + /* Step 10 */ + r[j] = rj + t; + } + } + } + + /* Reduce coefficients with quick algorithm. */ + for (j = 0; j < MLKEM_N; ++j) { + r[j] = MLKEM_BARRETT_RED(r[j]); + } +#elif defined(WOLFSSL_MLKEM_NO_LARGE_CODE) + /* Take out the first iteration. */ + unsigned int len; + unsigned int k = 1; + unsigned int j; + unsigned int start; + sword16 zeta = zetas[k++]; + + for (j = 0; j < MLKEM_N / 2; ++j) { + sword32 p = (sword32)zeta * r[j + MLKEM_N / 2]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[j]; + r[j + MLKEM_N / 2] = rj - t; + r[j] = rj + t; + } + for (len = MLKEM_N / 4; len >= 2; len >>= 1) { + for (start = 0; start < MLKEM_N; start = j + len) { + zeta = zetas[k++]; + for (j = start; j < start + len; ++j) { + sword32 p = (sword32)zeta * r[j + len]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[j]; + r[j + len] = rj - t; + r[j] = rj + t; + } + } + } + + /* Reduce coefficients with quick algorithm. */ + for (j = 0; j < MLKEM_N; ++j) { + r[j] = MLKEM_BARRETT_RED(r[j]); + } +#elif defined(WOLFSSL_MLKEM_NTT_UNROLL) + /* Unroll len loop (Step 3). */ + unsigned int k = 1; + unsigned int j; + unsigned int start; + sword16 zeta = zetas[k++]; + + /* len = 128 */ + for (j = 0; j < MLKEM_N / 2; ++j) { + sword32 p = (sword32)zeta * r[j + MLKEM_N / 2]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[j]; + r[j + MLKEM_N / 2] = rj - t; + r[j] = rj + t; + } + /* len = 64 */ + for (start = 0; start < MLKEM_N; start += 2 * 64) { + zeta = zetas[k++]; + for (j = 0; j < 64; ++j) { + sword32 p = (sword32)zeta * r[start + j + 64]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[start + j]; + r[start + j + 64] = rj - t; + r[start + j] = rj + t; + } + } + /* len = 32 */ + for (start = 0; start < MLKEM_N; start += 2 * 32) { + zeta = zetas[k++]; + for (j = 0; j < 32; ++j) { + sword32 p = (sword32)zeta * r[start + j + 32]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[start + j]; + r[start + j + 32] = rj - t; + r[start + j] = rj + t; + } + } + /* len = 16 */ + for (start = 0; start < MLKEM_N; start += 2 * 16) { + zeta = zetas[k++]; + for (j = 0; j < 16; ++j) { + sword32 p = (sword32)zeta * r[start + j + 16]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[start + j]; + r[start + j + 16] = rj - t; + r[start + j] = rj + t; + } + } + /* len = 8 */ + for (start = 0; start < MLKEM_N; start += 2 * 8) { + zeta = zetas[k++]; + for (j = 0; j < 8; ++j) { + sword32 p = (sword32)zeta * r[start + j + 8]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[start + j]; + r[start + j + 8] = rj - t; + r[start + j] = rj + t; + } + } + /* len = 4 */ + for (start = 0; start < MLKEM_N; start += 2 * 4) { + zeta = zetas[k++]; + for (j = 0; j < 4; ++j) { + sword32 p = (sword32)zeta * r[start + j + 4]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[start + j]; + r[start + j + 4] = rj - t; + r[start + j] = rj + t; + } + } + /* len = 2 */ + for (start = 0; start < MLKEM_N; start += 2 * 2) { + zeta = zetas[k++]; + for (j = 0; j < 2; ++j) { + sword32 p = (sword32)zeta * r[start + j + 2]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[start + j]; + r[start + j + 2] = rj - t; + r[start + j] = rj + t; + } + } + /* Reduce coefficients with quick algorithm. */ + for (j = 0; j < MLKEM_N; ++j) { + r[j] = MLKEM_BARRETT_RED(r[j]); + } +#else + /* Unroll len (2, 3, 2) and start loops. */ + unsigned int j; + sword16 t0; + sword16 t1; + sword16 t2; + sword16 t3; + + /* len = 128,64 */ + sword16 zeta128 = zetas[1]; + sword16 zeta64_0 = zetas[2]; + sword16 zeta64_1 = zetas[3]; + for (j = 0; j < MLKEM_N / 8; j++) { + sword16 r0 = r[j + 0]; + sword16 r1 = r[j + 32]; + sword16 r2 = r[j + 64]; + sword16 r3 = r[j + 96]; + sword16 r4 = r[j + 128]; + sword16 r5 = r[j + 160]; + sword16 r6 = r[j + 192]; + sword16 r7 = r[j + 224]; + + t0 = MLKEM_MONT_RED((sword32)zeta128 * r4); + t1 = MLKEM_MONT_RED((sword32)zeta128 * r5); + t2 = MLKEM_MONT_RED((sword32)zeta128 * r6); + t3 = MLKEM_MONT_RED((sword32)zeta128 * r7); + r4 = r0 - t0; + r5 = r1 - t1; + r6 = r2 - t2; + r7 = r3 - t3; + r0 += t0; + r1 += t1; + r2 += t2; + r3 += t3; + + t0 = MLKEM_MONT_RED((sword32)zeta64_0 * r2); + t1 = MLKEM_MONT_RED((sword32)zeta64_0 * r3); + t2 = MLKEM_MONT_RED((sword32)zeta64_1 * r6); + t3 = MLKEM_MONT_RED((sword32)zeta64_1 * r7); + r2 = r0 - t0; + r3 = r1 - t1; + r6 = r4 - t2; + r7 = r5 - t3; + r0 += t0; + r1 += t1; + r4 += t2; + r5 += t3; + + r[j + 0] = r0; + r[j + 32] = r1; + r[j + 64] = r2; + r[j + 96] = r3; + r[j + 128] = r4; + r[j + 160] = r5; + r[j + 192] = r6; + r[j + 224] = r7; + } + + /* len = 32,16,8 */ + for (j = 0; j < MLKEM_N; j += 64) { + int i; + sword16 zeta32 = zetas[ 4 + j / 64 + 0]; + sword16 zeta16_0 = zetas[ 8 + j / 32 + 0]; + sword16 zeta16_1 = zetas[ 8 + j / 32 + 1]; + sword16 zeta8_0 = zetas[16 + j / 16 + 0]; + sword16 zeta8_1 = zetas[16 + j / 16 + 1]; + sword16 zeta8_2 = zetas[16 + j / 16 + 2]; + sword16 zeta8_3 = zetas[16 + j / 16 + 3]; + for (i = 0; i < 8; i++) { + sword16 r0 = r[j + i + 0]; + sword16 r1 = r[j + i + 8]; + sword16 r2 = r[j + i + 16]; + sword16 r3 = r[j + i + 24]; + sword16 r4 = r[j + i + 32]; + sword16 r5 = r[j + i + 40]; + sword16 r6 = r[j + i + 48]; + sword16 r7 = r[j + i + 56]; + + t0 = MLKEM_MONT_RED((sword32)zeta32 * r4); + t1 = MLKEM_MONT_RED((sword32)zeta32 * r5); + t2 = MLKEM_MONT_RED((sword32)zeta32 * r6); + t3 = MLKEM_MONT_RED((sword32)zeta32 * r7); + r4 = r0 - t0; + r5 = r1 - t1; + r6 = r2 - t2; + r7 = r3 - t3; + r0 += t0; + r1 += t1; + r2 += t2; + r3 += t3; + + t0 = MLKEM_MONT_RED((sword32)zeta16_0 * r2); + t1 = MLKEM_MONT_RED((sword32)zeta16_0 * r3); + t2 = MLKEM_MONT_RED((sword32)zeta16_1 * r6); + t3 = MLKEM_MONT_RED((sword32)zeta16_1 * r7); + r2 = r0 - t0; + r3 = r1 - t1; + r6 = r4 - t2; + r7 = r5 - t3; + r0 += t0; + r1 += t1; + r4 += t2; + r5 += t3; + + t0 = MLKEM_MONT_RED((sword32)zeta8_0 * r1); + t1 = MLKEM_MONT_RED((sword32)zeta8_1 * r3); + t2 = MLKEM_MONT_RED((sword32)zeta8_2 * r5); + t3 = MLKEM_MONT_RED((sword32)zeta8_3 * r7); + r1 = r0 - t0; + r3 = r2 - t1; + r5 = r4 - t2; + r7 = r6 - t3; + r0 += t0; + r2 += t1; + r4 += t2; + r6 += t3; + + r[j + i + 0] = r0; + r[j + i + 8] = r1; + r[j + i + 16] = r2; + r[j + i + 24] = r3; + r[j + i + 32] = r4; + r[j + i + 40] = r5; + r[j + i + 48] = r6; + r[j + i + 56] = r7; + } + } + + /* len = 4,2 and Final reduction */ + for (j = 0; j < MLKEM_N; j += 8) { + sword16 zeta4 = zetas[32 + j / 8 + 0]; + sword16 zeta2_0 = zetas[64 + j / 4 + 0]; + sword16 zeta2_1 = zetas[64 + j / 4 + 1]; + sword16 r0 = r[j + 0]; + sword16 r1 = r[j + 1]; + sword16 r2 = r[j + 2]; + sword16 r3 = r[j + 3]; + sword16 r4 = r[j + 4]; + sword16 r5 = r[j + 5]; + sword16 r6 = r[j + 6]; + sword16 r7 = r[j + 7]; + + t0 = MLKEM_MONT_RED((sword32)zeta4 * r4); + t1 = MLKEM_MONT_RED((sword32)zeta4 * r5); + t2 = MLKEM_MONT_RED((sword32)zeta4 * r6); + t3 = MLKEM_MONT_RED((sword32)zeta4 * r7); + r4 = r0 - t0; + r5 = r1 - t1; + r6 = r2 - t2; + r7 = r3 - t3; + r0 += t0; + r1 += t1; + r2 += t2; + r3 += t3; + + t0 = MLKEM_MONT_RED((sword32)zeta2_0 * r2); + t1 = MLKEM_MONT_RED((sword32)zeta2_0 * r3); + t2 = MLKEM_MONT_RED((sword32)zeta2_1 * r6); + t3 = MLKEM_MONT_RED((sword32)zeta2_1 * r7); + r2 = r0 - t0; + r3 = r1 - t1; + r6 = r4 - t2; + r7 = r5 - t3; + r0 += t0; + r1 += t1; + r4 += t2; + r5 += t3; + + r[j + 0] = MLKEM_BARRETT_RED(r0); + r[j + 1] = MLKEM_BARRETT_RED(r1); + r[j + 2] = MLKEM_BARRETT_RED(r2); + r[j + 3] = MLKEM_BARRETT_RED(r3); + r[j + 4] = MLKEM_BARRETT_RED(r4); + r[j + 5] = MLKEM_BARRETT_RED(r5); + r[j + 6] = MLKEM_BARRETT_RED(r6); + r[j + 7] = MLKEM_BARRETT_RED(r7); + } +#endif +} + +#if !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) || \ + !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) +/* Zetas for inverse NTT. */ +const sword16 zetas_inv[MLKEM_N / 2] = { + 1701, 1807, 1460, 2371, 2338, 2333, 308, 108, + 2851, 870, 854, 1510, 2535, 1278, 1530, 1185, + 1659, 1187, 3109, 874, 1335, 2111, 136, 1215, + 2945, 1465, 1285, 2007, 2719, 2726, 2232, 2512, + 75, 156, 3000, 2911, 2980, 872, 2685, 1590, + 2210, 602, 1846, 777, 147, 2170, 2551, 246, + 1676, 1755, 460, 291, 235, 3152, 2742, 2907, + 3224, 1779, 2458, 1251, 2486, 2774, 2899, 1103, + 1275, 2652, 1065, 2881, 725, 1508, 2368, 398, + 951, 247, 1421, 3222, 2499, 271, 90, 853, + 1860, 3203, 1162, 1618, 666, 320, 8, 2813, + 1544, 282, 1838, 1293, 2314, 552, 2677, 2106, + 1571, 205, 2918, 1542, 2721, 2597, 2312, 681, + 130, 1602, 1871, 829, 2946, 3065, 1325, 2756, + 1861, 1474, 1202, 2367, 3147, 1752, 2707, 171, + 3127, 3042, 1907, 1836, 1517, 359, 758, 1441 +}; + +/* Inverse Number-Theoretic Transform. + * + * FIPS 203, Algorithm 10: NTT^-1(f_hat) + * Computes the polynomial f element of R_q that corresponds to the given NTT + * representation f element of T_q. + * 1: f <- f_hat + * 2: i <- 127 + * 3: for (len <- 2; len <= 128 ; len <- 2.len) + * 4: for (start <- 0; start < 256; start <- start + 2.len) + * 5: zeta <- zetas^BitRev_7(i) mod q + * 6: i <- i - 1 + * 7: for (j <- start; j < start + len; j++) + * 8: t <- f[j] + * 9: f[j] < t + f[j + len] + * 10: f[j + len] <- zeta.(f[j+len] - t) + * 11: end for + * 12: end for + * 13: end for + * 14: f <- f.3303 mod q + * 15: return f + * + * @param [in, out] r Polynomial to transform. + */ +static void mlkem_invntt(sword16* r) +{ +#ifdef WOLFSSL_MLKEM_SMALL + unsigned int len; + unsigned int k; + unsigned int j; + sword16 zeta; + + /* Step 2 - table reversed */ + k = 0; + /* Step 3 */ + for (len = 2; len <= MLKEM_N / 2; len <<= 1) { + unsigned int start; + /* Step 4 */ + for (start = 0; start < MLKEM_N; start = j + len) { + /* Step 5, 6 */ + zeta = zetas_inv[k++]; + /* Step 7 */ + for (j = start; j < start + len; ++j) { + sword32 p; + /* Step 8 */ + sword16 rj = r[j]; + sword16 rjl = r[j + len]; + /* Step 9 */ + sword16 t = rj + rjl; + r[j] = MLKEM_BARRETT_RED(t); + /* Step 10 */ + rjl = rj - rjl; + p = (sword32)zeta * rjl; + r[j + len] = MLKEM_MONT_RED(p); + } + } + } + + /* Step 14 */ + zeta = zetas_inv[127]; + for (j = 0; j < MLKEM_N; ++j) { + sword32 p = (sword32)zeta * r[j]; + r[j] = MLKEM_MONT_RED(p); + } +#elif defined(WOLFSSL_MLKEM_NO_LARGE_CODE) + /* Take out last iteration. */ + unsigned int len; + unsigned int k; + unsigned int j; + sword16 zeta; + sword16 zeta2; + + k = 0; + for (len = 2; len <= MLKEM_N / 4; len <<= 1) { + unsigned int start; + for (start = 0; start < MLKEM_N; start = j + len) { + zeta = zetas_inv[k++]; + for (j = start; j < start + len; ++j) { + sword32 p; + sword16 rj = r[j]; + sword16 rjl = r[j + len]; + sword16 t = rj + rjl; + r[j] = MLKEM_BARRETT_RED(t); + rjl = rj - rjl; + p = (sword32)zeta * rjl; + r[j + len] = MLKEM_MONT_RED(p); + } + } + } + + zeta = zetas_inv[126]; + zeta2 = zetas_inv[127]; + for (j = 0; j < MLKEM_N / 2; ++j) { + sword32 p; + sword16 rj = r[j]; + sword16 rjl = r[j + MLKEM_N / 2]; + sword16 t = rj + rjl; + rjl = rj - rjl; + p = (sword32)zeta * rjl; + r[j] = t; + r[j + MLKEM_N / 2] = MLKEM_MONT_RED(p); + + p = (sword32)zeta2 * r[j]; + r[j] = MLKEM_MONT_RED(p); + p = (sword32)zeta2 * r[j + MLKEM_N / 2]; + r[j + MLKEM_N / 2] = MLKEM_MONT_RED(p); + } +#elif defined(WOLFSSL_MLKEM_INVNTT_UNROLL) + /* Unroll len loop (Step 3). */ + unsigned int k; + unsigned int j; + unsigned int start; + sword16 zeta; + sword16 zeta2; + + k = 0; + /* len = 2 */ + for (start = 0; start < MLKEM_N; start += 2 * 2) { + zeta = zetas_inv[k++]; + for (j = 0; j < 2; ++j) { + sword32 p; + sword16 rj = r[start + j]; + sword16 rjl = r[start + j + 2]; + sword16 t = rj + rjl; + r[start + j] = t; + rjl = rj - rjl; + p = (sword32)zeta * rjl; + r[start + j + 2] = MLKEM_MONT_RED(p); + } + } + /* len = 4 */ + for (start = 0; start < MLKEM_N; start += 2 * 4) { + zeta = zetas_inv[k++]; + for (j = 0; j < 4; ++j) { + sword32 p; + sword16 rj = r[start + j]; + sword16 rjl = r[start + j + 4]; + sword16 t = rj + rjl; + r[start + j] = t; + rjl = rj - rjl; + p = (sword32)zeta * rjl; + r[start + j + 4] = MLKEM_MONT_RED(p); + } + } + /* len = 8 */ + for (start = 0; start < MLKEM_N; start += 2 * 8) { + zeta = zetas_inv[k++]; + for (j = 0; j < 8; ++j) { + sword32 p; + sword16 rj = r[start + j]; + sword16 rjl = r[start + j + 8]; + sword16 t = rj + rjl; + /* Reduce. */ + r[start + j] = MLKEM_BARRETT_RED(t); + rjl = rj - rjl; + p = (sword32)zeta * rjl; + r[start + j + 8] = MLKEM_MONT_RED(p); + } + } + /* len = 16 */ + for (start = 0; start < MLKEM_N; start += 2 * 16) { + zeta = zetas_inv[k++]; + for (j = 0; j < 16; ++j) { + sword32 p; + sword16 rj = r[start + j]; + sword16 rjl = r[start + j + 16]; + sword16 t = rj + rjl; + r[start + j] = t; + rjl = rj - rjl; + p = (sword32)zeta * rjl; + r[start + j + 16] = MLKEM_MONT_RED(p); + } + } + /* len = 32 */ + for (start = 0; start < MLKEM_N; start += 2 * 32) { + zeta = zetas_inv[k++]; + for (j = 0; j < 32; ++j) { + sword32 p; + sword16 rj = r[start + j]; + sword16 rjl = r[start + j + 32]; + sword16 t = rj + rjl; + r[start + j] = t; + rjl = rj - rjl; + p = (sword32)zeta * rjl; + r[start + j + 32] = MLKEM_MONT_RED(p); + } + } + /* len = 64 */ + for (start = 0; start < MLKEM_N; start += 2 * 64) { + zeta = zetas_inv[k++]; + for (j = 0; j < 64; ++j) { + sword32 p; + sword16 rj = r[start + j]; + sword16 rjl = r[start + j + 64]; + sword16 t = rj + rjl; + /* Reduce. */ + r[start + j] = MLKEM_BARRETT_RED(t); + rjl = rj - rjl; + p = (sword32)zeta * rjl; + r[start + j + 64] = MLKEM_MONT_RED(p); + } + } + /* len = 128, 256 */ + zeta = zetas_inv[126]; + zeta2 = zetas_inv[127]; + for (j = 0; j < MLKEM_N / 2; ++j) { + sword32 p; + sword16 rj = r[j]; + sword16 rjl = r[j + MLKEM_N / 2]; + sword16 t = rj + rjl; + rjl = rj - rjl; + p = (sword32)zeta * rjl; + r[j] = t; + r[j + MLKEM_N / 2] = MLKEM_MONT_RED(p); + + p = (sword32)zeta2 * r[j]; + r[j] = MLKEM_MONT_RED(p); + p = (sword32)zeta2 * r[j + MLKEM_N / 2]; + r[j + MLKEM_N / 2] = MLKEM_MONT_RED(p); + } +#else + /* Unroll len (2, 3, 3) and start loops. */ + unsigned int j; + sword16 t0; + sword16 t1; + sword16 t2; + sword16 t3; + sword16 zeta64_0; + sword16 zeta64_1; + sword16 zeta128; + sword16 zeta256; + sword32 p; + + for (j = 0; j < MLKEM_N; j += 8) { + sword16 zeta2_0 = zetas_inv[ 0 + j / 4 + 0]; + sword16 zeta2_1 = zetas_inv[ 0 + j / 4 + 1]; + sword16 zeta4 = zetas_inv[64 + j / 8 + 0]; + sword16 r0 = r[j + 0]; + sword16 r1 = r[j + 1]; + sword16 r2 = r[j + 2]; + sword16 r3 = r[j + 3]; + sword16 r4 = r[j + 4]; + sword16 r5 = r[j + 5]; + sword16 r6 = r[j + 6]; + sword16 r7 = r[j + 7]; + + p = (sword32)zeta2_0 * (sword16)(r0 - r2); + t0 = MLKEM_MONT_RED(p); + p = (sword32)zeta2_0 * (sword16)(r1 - r3); + t1 = MLKEM_MONT_RED(p); + p = (sword32)zeta2_1 * (sword16)(r4 - r6); + t2 = MLKEM_MONT_RED(p); + p = (sword32)zeta2_1 * (sword16)(r5 - r7); + t3 = MLKEM_MONT_RED(p); + r0 += r2; + r1 += r3; + r4 += r6; + r5 += r7; + r2 = t0; + r3 = t1; + r6 = t2; + r7 = t3; + + p = (sword32)zeta4 * (sword16)(r0 - r4); + t0 = MLKEM_MONT_RED(p); + p = (sword32)zeta4 * (sword16)(r1 - r5); + t1 = MLKEM_MONT_RED(p); + p = (sword32)zeta4 * (sword16)(r2 - r6); + t2 = MLKEM_MONT_RED(p); + p = (sword32)zeta4 * (sword16)(r3 - r7); + t3 = MLKEM_MONT_RED(p); + r0 += r4; + r1 += r5; + r2 += r6; + r3 += r7; + r4 = t0; + r5 = t1; + r6 = t2; + r7 = t3; + + r[j + 0] = r0; + r[j + 1] = r1; + r[j + 2] = r2; + r[j + 3] = r3; + r[j + 4] = r4; + r[j + 5] = r5; + r[j + 6] = r6; + r[j + 7] = r7; + } + + for (j = 0; j < MLKEM_N; j += 64) { + int i; + sword16 zeta8_0 = zetas_inv[ 96 + j / 16 + 0]; + sword16 zeta8_1 = zetas_inv[ 96 + j / 16 + 1]; + sword16 zeta8_2 = zetas_inv[ 96 + j / 16 + 2]; + sword16 zeta8_3 = zetas_inv[ 96 + j / 16 + 3]; + sword16 zeta16_0 = zetas_inv[112 + j / 32 + 0]; + sword16 zeta16_1 = zetas_inv[112 + j / 32 + 1]; + sword16 zeta32 = zetas_inv[120 + j / 64 + 0]; + for (i = 0; i < 8; i++) { + sword16 r0 = r[j + i + 0]; + sword16 r1 = r[j + i + 8]; + sword16 r2 = r[j + i + 16]; + sword16 r3 = r[j + i + 24]; + sword16 r4 = r[j + i + 32]; + sword16 r5 = r[j + i + 40]; + sword16 r6 = r[j + i + 48]; + sword16 r7 = r[j + i + 56]; + + p = (sword32)zeta8_0 * (sword16)(r0 - r1); + t0 = MLKEM_MONT_RED(p); + p = (sword32)zeta8_1 * (sword16)(r2 - r3); + t1 = MLKEM_MONT_RED(p); + p = (sword32)zeta8_2 * (sword16)(r4 - r5); + t2 = MLKEM_MONT_RED(p); + p = (sword32)zeta8_3 * (sword16)(r6 - r7); + t3 = MLKEM_MONT_RED(p); + r0 = MLKEM_BARRETT_RED(r0 + r1); + r2 = MLKEM_BARRETT_RED(r2 + r3); + r4 = MLKEM_BARRETT_RED(r4 + r5); + r6 = MLKEM_BARRETT_RED(r6 + r7); + r1 = t0; + r3 = t1; + r5 = t2; + r7 = t3; + + p = (sword32)zeta16_0 * (sword16)(r0 - r2); + t0 = MLKEM_MONT_RED(p); + p = (sword32)zeta16_0 * (sword16)(r1 - r3); + t1 = MLKEM_MONT_RED(p); + p = (sword32)zeta16_1 * (sword16)(r4 - r6); + t2 = MLKEM_MONT_RED(p); + p = (sword32)zeta16_1 * (sword16)(r5 - r7); + t3 = MLKEM_MONT_RED(p); + r0 += r2; + r1 += r3; + r4 += r6; + r5 += r7; + r2 = t0; + r3 = t1; + r6 = t2; + r7 = t3; + + p = (sword32)zeta32 * (sword16)(r0 - r4); + t0 = MLKEM_MONT_RED(p); + p = (sword32)zeta32 * (sword16)(r1 - r5); + t1 = MLKEM_MONT_RED(p); + p = (sword32)zeta32 * (sword16)(r2 - r6); + t2 = MLKEM_MONT_RED(p); + p = (sword32)zeta32 * (sword16)(r3 - r7); + t3 = MLKEM_MONT_RED(p); + r0 += r4; + r1 += r5; + r2 += r6; + r3 += r7; + r4 = t0; + r5 = t1; + r6 = t2; + r7 = t3; + + r[j + i + 0] = r0; + r[j + i + 8] = r1; + r[j + i + 16] = r2; + r[j + i + 24] = r3; + r[j + i + 32] = r4; + r[j + i + 40] = r5; + r[j + i + 48] = r6; + r[j + i + 56] = r7; + } + } + + zeta64_0 = zetas_inv[124]; + zeta64_1 = zetas_inv[125]; + zeta128 = zetas_inv[126]; + zeta256 = zetas_inv[127]; + for (j = 0; j < MLKEM_N / 8; j++) { + sword16 r0 = r[j + 0]; + sword16 r1 = r[j + 32]; + sword16 r2 = r[j + 64]; + sword16 r3 = r[j + 96]; + sword16 r4 = r[j + 128]; + sword16 r5 = r[j + 160]; + sword16 r6 = r[j + 192]; + sword16 r7 = r[j + 224]; + + p = (sword32)zeta64_0 * (sword16)(r0 - r2); + t0 = MLKEM_MONT_RED(p); + p = (sword32)zeta64_0 * (sword16)(r1 - r3); + t1 = MLKEM_MONT_RED(p); + p = (sword32)zeta64_1 * (sword16)(r4 - r6); + t2 = MLKEM_MONT_RED(p); + p = (sword32)zeta64_1 * (sword16)(r5 - r7); + t3 = MLKEM_MONT_RED(p); + r0 = MLKEM_BARRETT_RED(r0 + r2); + r1 = MLKEM_BARRETT_RED(r1 + r3); + r4 = MLKEM_BARRETT_RED(r4 + r6); + r5 = MLKEM_BARRETT_RED(r5 + r7); + r2 = t0; + r3 = t1; + r6 = t2; + r7 = t3; + + p = (sword32)zeta128 * (sword16)(r0 - r4); + t0 = MLKEM_MONT_RED(p); + p = (sword32)zeta128 * (sword16)(r1 - r5); + t1 = MLKEM_MONT_RED(p); + p = (sword32)zeta128 * (sword16)(r2 - r6); + t2 = MLKEM_MONT_RED(p); + p = (sword32)zeta128 * (sword16)(r3 - r7); + t3 = MLKEM_MONT_RED(p); + r0 += r4; + r1 += r5; + r2 += r6; + r3 += r7; + r4 = t0; + r5 = t1; + r6 = t2; + r7 = t3; + + p = (sword32)zeta256 * r0; + r0 = MLKEM_MONT_RED(p); + p = (sword32)zeta256 * r1; + r1 = MLKEM_MONT_RED(p); + p = (sword32)zeta256 * r2; + r2 = MLKEM_MONT_RED(p); + p = (sword32)zeta256 * r3; + r3 = MLKEM_MONT_RED(p); + p = (sword32)zeta256 * r4; + r4 = MLKEM_MONT_RED(p); + p = (sword32)zeta256 * r5; + r5 = MLKEM_MONT_RED(p); + p = (sword32)zeta256 * r6; + r6 = MLKEM_MONT_RED(p); + p = (sword32)zeta256 * r7; + r7 = MLKEM_MONT_RED(p); + + r[j + 0] = r0; + r[j + 32] = r1; + r[j + 64] = r2; + r[j + 96] = r3; + r[j + 128] = r4; + r[j + 160] = r5; + r[j + 192] = r6; + r[j + 224] = r7; + } +#endif +} +#endif + +/* Multiplication of polynomials in Zq[X]/(X^2-zeta). + * + * Used for multiplication of elements in Rq in NTT domain. + * + * FIPS 203, Algorithm 12: BaseCaseMultiply(a0, a1, b0, b1, zeta) + * Computes the product of two degree-one polynomials with respect to a + * quadratic modulus. + * 1: c0 <- a0.b0 + a1.b1.zeta + * 2: c1 <- a0.b1 + a1.b0 + * 3: return (c0, c1) + * + * @param [out] r Result polynomial. + * @param [in] a First factor. + * @param [in] b Second factor. + * @param [in] zeta Integer defining the reduction polynomial. + */ +static void mlkem_basemul(sword16* r, const sword16* a, const sword16* b, + sword16 zeta) +{ + sword16 r0; + sword16 a0 = a[0]; + sword16 a1 = a[1]; + sword16 b0 = b[0]; + sword16 b1 = b[1]; + sword32 p1; + sword32 p2; + + /* Step 1 */ + p1 = (sword32)a0 * b0; + p2 = (sword32)a1 * b1; + r0 = MLKEM_MONT_RED(p2); + p2 = (sword32)zeta * r0; + p2 += p1; + r[0] = MLKEM_MONT_RED(p2); + + /* Step 2 */ + p1 = (sword32)a0 * b1; + p2 = (sword32)a1 * b0; + p1 += p2; + r[1] = MLKEM_MONT_RED(p1); +} + +/* Multiply two polynomials in NTT domain. r = a * b. + * + * FIPS 203, Algorithm 11: MultiplyNTTs(f_hat, g_hat) + * Computes the product (in the ring T_q) of two NTT representations. + * 1: for (i <- 0; i < 128; i++) + * 2: (h_hat[2i],h_hat[2i+1]) <- + * BaseCaseMultiply(f_hat[2i],f_hat[2i+1],g_hat[2i],g_hat[2i+1], + * zetas^(BitRev_7(i)+1) + * 3: end for + * 4: return h_hat + * + * @param [out] r Result polynomial. + * @param [in] a First polynomial multiplier. + * @param [in] b Second polynomial multiplier. + */ +static void mlkem_basemul_mont(sword16* r, const sword16* a, const sword16* b) +{ + const sword16* zeta = zetas + 64; + +#if defined(WOLFSSL_MLKEM_SMALL) + /* Two multiplications per loop. */ + unsigned int i; + /* Step 1 */ + for (i = 0; i < MLKEM_N; i += 4, zeta++) { + /* Step 2 */ + mlkem_basemul(r + i + 0, a + i + 0, b + i + 0, zeta[0]); + mlkem_basemul(r + i + 2, a + i + 2, b + i + 2, -zeta[0]); + } +#elif defined(WOLFSSL_MLKEM_NO_LARGE_CODE) + /* Four multiplications per loop. */ + unsigned int i; + for (i = 0; i < MLKEM_N; i += 8, zeta += 2) { + mlkem_basemul(r + i + 0, a + i + 0, b + i + 0, zeta[0]); + mlkem_basemul(r + i + 2, a + i + 2, b + i + 2, -zeta[0]); + mlkem_basemul(r + i + 4, a + i + 4, b + i + 4, zeta[1]); + mlkem_basemul(r + i + 6, a + i + 6, b + i + 6, -zeta[1]); + } +#else + /* Eight multiplications per loop. */ + unsigned int i; + for (i = 0; i < MLKEM_N; i += 16, zeta += 4) { + mlkem_basemul(r + i + 0, a + i + 0, b + i + 0, zeta[0]); + mlkem_basemul(r + i + 2, a + i + 2, b + i + 2, -zeta[0]); + mlkem_basemul(r + i + 4, a + i + 4, b + i + 4, zeta[1]); + mlkem_basemul(r + i + 6, a + i + 6, b + i + 6, -zeta[1]); + mlkem_basemul(r + i + 8, a + i + 8, b + i + 8, zeta[2]); + mlkem_basemul(r + i + 10, a + i + 10, b + i + 10, -zeta[2]); + mlkem_basemul(r + i + 12, a + i + 12, b + i + 12, zeta[3]); + mlkem_basemul(r + i + 14, a + i + 14, b + i + 14, -zeta[3]); + } +#endif +} + +/* Multiply two polynomials in NTT domain and add to result. r += a * b. + * + * FIPS 203, Algorithm 11: MultiplyNTTs(f_hat, g_hat) + * Computes the product (in the ring T_q) of two NTT representations. + * 1: for (i <- 0; i < 128; i++) + * 2: (h_hat[2i],h_hat[2i+1]) <- + * BaseCaseMultiply(f_hat[2i],f_hat[2i+1],g_hat[2i],g_hat[2i+1], + * zetas^(BitRev_7(i)+1) + * 3: end for + * 4: return h_hat + * Add h_hat to r. + * + * @param [in, out] r Result polynomial. + * @param [in] a First polynomial multiplier. + * @param [in] b Second polynomial multiplier. + */ +static void mlkem_basemul_mont_add(sword16* r, const sword16* a, + const sword16* b) +{ + const sword16* zeta = zetas + 64; + +#if defined(WOLFSSL_MLKEM_SMALL) + /* Two multiplications per loop. */ + unsigned int i; + for (i = 0; i < MLKEM_N; i += 4, zeta++) { + sword16 t0[2]; + sword16 t2[2]; + + mlkem_basemul(t0, a + i + 0, b + i + 0, zeta[0]); + mlkem_basemul(t2, a + i + 2, b + i + 2, -zeta[0]); + + r[i + 0] += t0[0]; + r[i + 1] += t0[1]; + r[i + 2] += t2[0]; + r[i + 3] += t2[1]; + } +#elif defined(WOLFSSL_MLKEM_NO_LARGE_CODE) + /* Four multiplications per loop. */ + unsigned int i; + for (i = 0; i < MLKEM_N; i += 8, zeta += 2) { + sword16 t0[2]; + sword16 t2[2]; + sword16 t4[2]; + sword16 t6[2]; + + mlkem_basemul(t0, a + i + 0, b + i + 0, zeta[0]); + mlkem_basemul(t2, a + i + 2, b + i + 2, -zeta[0]); + mlkem_basemul(t4, a + i + 4, b + i + 4, zeta[1]); + mlkem_basemul(t6, a + i + 6, b + i + 6, -zeta[1]); + + r[i + 0] += t0[0]; + r[i + 1] += t0[1]; + r[i + 2] += t2[0]; + r[i + 3] += t2[1]; + r[i + 4] += t4[0]; + r[i + 5] += t4[1]; + r[i + 6] += t6[0]; + r[i + 7] += t6[1]; + } +#else + /* Eight multiplications per loop. */ + unsigned int i; + for (i = 0; i < MLKEM_N; i += 16, zeta += 4) { + sword16 t0[2]; + sword16 t2[2]; + sword16 t4[2]; + sword16 t6[2]; + sword16 t8[2]; + sword16 t10[2]; + sword16 t12[2]; + sword16 t14[2]; + + mlkem_basemul(t0, a + i + 0, b + i + 0, zeta[0]); + mlkem_basemul(t2, a + i + 2, b + i + 2, -zeta[0]); + mlkem_basemul(t4, a + i + 4, b + i + 4, zeta[1]); + mlkem_basemul(t6, a + i + 6, b + i + 6, -zeta[1]); + mlkem_basemul(t8, a + i + 8, b + i + 8, zeta[2]); + mlkem_basemul(t10, a + i + 10, b + i + 10, -zeta[2]); + mlkem_basemul(t12, a + i + 12, b + i + 12, zeta[3]); + mlkem_basemul(t14, a + i + 14, b + i + 14, -zeta[3]); + + r[i + 0] += t0[0]; + r[i + 1] += t0[1]; + r[i + 2] += t2[0]; + r[i + 3] += t2[1]; + r[i + 4] += t4[0]; + r[i + 5] += t4[1]; + r[i + 6] += t6[0]; + r[i + 7] += t6[1]; + r[i + 8] += t8[0]; + r[i + 9] += t8[1]; + r[i + 10] += t10[0]; + r[i + 11] += t10[1]; + r[i + 12] += t12[0]; + r[i + 13] += t12[1]; + r[i + 14] += t14[0]; + r[i + 15] += t14[1]; + } +#endif +} +#endif + +/* Pointwise multiply elements of a and b, into r, and multiply by 2^-16. + * + * @param [out] r Result polynomial. + * @param [in] a First vector polynomial to multiply with. + * @param [in] b Second vector polynomial to multiply with. + * @param [in] k Number of polynomials in vector. + */ +static void mlkem_pointwise_acc_mont(sword16* r, const sword16* a, + const sword16* b, unsigned int k) +{ + unsigned int i; + + mlkem_basemul_mont(r, a, b); +#ifdef WOLFSSL_MLKEM_SMALL + for (i = 1; i < k; ++i) { + mlkem_basemul_mont_add(r, a + i * MLKEM_N, b + i * MLKEM_N); + } +#else + for (i = 1; i < k - 1; ++i) { + mlkem_basemul_mont_add(r, a + i * MLKEM_N, b + i * MLKEM_N); + } + mlkem_basemul_mont_add(r, a + (k - 1) * MLKEM_N, b + (k - 1) * MLKEM_N); +#endif +} + +/******************************************************************************/ + +/* Initialize Kyber implementation. + */ +void mlkem_init(void) +{ +#if defined(USE_INTEL_SPEEDUP) || (defined(__aarch64__) && \ + defined(WOLFSSL_ARMASM)) + cpuid_flags = cpuid_get_flags(); +#endif +} + +/******************************************************************************/ + +#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) + +#ifndef WOLFSSL_MLKEM_NO_MAKE_KEY +/* Generate a public-private key pair from randomly generated data. + * + * FIPS 203, Algorithm 13: K-PKE.KeyGen(d) + * ... + * 16: s_hat <- NTT(s) + * 17: e_hat <- NTT(e) + * 18: t^hat <- A_hat o s_hat + e_hat + * ... + * + * @param [in, out] s Private key vector of polynomials. + * @param [out] t Public key vector of polynomials. + * @param [in] e Error values as a vector of polynomials. Modified. + * @param [in] a Random values in an array of vectors of polynomials. + * @param [in] k Number of polynomials in vector. + */ +void mlkem_keygen(sword16* s, sword16* t, sword16* e, const sword16* a, int k) +{ + int i; + +#ifndef WOLFSSL_AARCH64_NO_SQRDMLSH + if (IS_AARCH64_RDM(cpuid_flags)) { + /* Transform private key. All of result used in public key calculation. + * Step 16: s_hat = NTT(s) */ + for (i = 0; i < k; ++i) { + mlkem_ntt_sqrdmlsh(s + i * MLKEM_N); + } + + /* For each polynomial in the vectors. + * Step 17, Step 18: Calculate public from A_hat, s_hat and e_hat. */ + for (i = 0; i < k; ++i) { + /* Multiply a by private into public polynomial. + * Step 18: ... A_hat o s_hat ... */ + mlkem_pointwise_acc_mont(t + i * MLKEM_N, a + i * k * MLKEM_N, s, + k); + /* Convert public polynomial to Montgomery form. + * Step 18: ... MontRed(A_hat o s_hat) ... */ + mlkem_to_mont_sqrdmlsh(t + i * MLKEM_N); + /* Transform error values polynomial. + * Step 17: e_hat = NTT(e) */ + mlkem_ntt_sqrdmlsh(e + i * MLKEM_N); + /* Add errors to public key and reduce. + * Step 18: t_hat = BarrettRed(MontRed(A_hat o s_hat) + e_hat) */ + mlkem_add_reduce(t + i * MLKEM_N, e + i * MLKEM_N); + } + } + else +#endif + { + /* Transform private key. All of result used in public key calculation. + * Step 16: s_hat = NTT(s) */ + for (i = 0; i < k; ++i) { + mlkem_ntt(s + i * MLKEM_N); + } + + /* For each polynomial in the vectors. + * Step 17, Step 18: Calculate public from A_hat, s_hat and e_hat. */ + for (i = 0; i < k; ++i) { + /* Multiply a by private into public polynomial. + * Step 18: ... A_hat o s_hat ... */ + mlkem_pointwise_acc_mont(t + i * MLKEM_N, a + i * k * MLKEM_N, s, + k); + /* Convert public polynomial to Montgomery form. + * Step 18: ... MontRed(A_hat o s_hat) ... */ + mlkem_to_mont(t + i * MLKEM_N); + /* Transform error values polynomial. + * Step 17: e_hat = NTT(e) */ + mlkem_ntt(e + i * MLKEM_N); + /* Add errors to public key and reduce. + * Step 18: t_hat = BarrettRed(MontRed(A_hat o s_hat) + e_hat) */ + mlkem_add_reduce(t + i * MLKEM_N, e + i * MLKEM_N); + } + } +} +#endif /* WOLFSSL_MLKEM_NO_MAKE_KEY */ + +#if !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) || \ + !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) +/* Encapsulate message. + * + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE, m, r) + * ... + * Step 18: y_hat <- NTT(y) + * Step 19: u <- InvNTT(A_hat_trans o y_hat) + e_1) + * ... + * Step 21: v <- InvNTT(t_hat_trans o y_hat) + e_2 + mu) + * ... + * + * @param [in] t Public key vector of polynomials. + * @param [out] u Vector of polynomials. + * @param [out] v Polynomial. + * @param [in] a Array of vector of polynomials. + * @param [in] y Vector of polynomials. + * @param [in] e1 Error Vector of polynomials. + * @param [in] e2 Error polynomial. + * @param [in] m Message polynomial. + * @param [in] k Number of polynomials in vector. + * @return 0 on success. + * + */ +void mlkem_encapsulate(const sword16* t, sword16* u , sword16* v, + const sword16* a, sword16* y, const sword16* e1, const sword16* e2, + const sword16* m, int k) +{ + int i; + +#ifndef WOLFSSL_AARCH64_NO_SQRDMLSH + if (IS_AARCH64_RDM(cpuid_flags)) { + /* Transform y. All of result used in calculation of u and v. + * Step 18: y_hat <- NTT(y) */ + for (i = 0; i < k; ++i) { + mlkem_ntt_sqrdmlsh(y + i * MLKEM_N); + } + + /* For each polynomial in the vectors. + * Step 19: u <- InvNTT(A_hat_trans o y_hat) + e_1) */ + for (i = 0; i < k; ++i) { + /* Multiply at by y into u polynomial. + * Step 19: ... A_hat_trans o y_hat ... */ + mlkem_pointwise_acc_mont(u + i * MLKEM_N, a + i * k * MLKEM_N, y, + k); + /* Inverse transform u polynomial. + * Step 19: ... InvNTT(A_hat_trans o y_hat) ... */ + mlkem_invntt_sqrdmlsh(u + i * MLKEM_N); + /* Add errors to u and reduce. + * Step 19: u <- InvNTT(A_hat_trans o y_hat) + e_1) */ + mlkem_add_reduce(u + i * MLKEM_N, e1 + i * MLKEM_N); + } + + /* Multiply public key by y into v polynomial. + * Step 21: ... t_hat_trans o y_hat ... */ + mlkem_pointwise_acc_mont(v, t, y, k); + /* Inverse transform v. + * Step 22: ... InvNTT(t_hat_trans o y_hat) ... */ + mlkem_invntt_sqrdmlsh(v); + } + else +#endif + { + /* Transform y. All of result used in calculation of u and v. + * Step 18: y_hat <- NTT(y) */ + for (i = 0; i < k; ++i) { + mlkem_ntt(y + i * MLKEM_N); + } + + /* For each polynomial in the vectors. + * Step 19: u <- InvNTT(A_hat_trans o y_hat) + e_1) */ + for (i = 0; i < k; ++i) { + /* Multiply at by y into u polynomial. + * Step 19: ... A_hat_trans o y_hat ... */ + mlkem_pointwise_acc_mont(u + i * MLKEM_N, a + i * k * MLKEM_N, y, + k); + /* Inverse transform u polynomial. + * Step 19: ... InvNTT(A_hat_trans o y_hat) ... */ + mlkem_invntt(u + i * MLKEM_N); + /* Add errors to u and reduce. + * Step 19: u <- InvNTT(A_hat_trans o y_hat) + e_1) */ + mlkem_add_reduce(u + i * MLKEM_N, e1 + i * MLKEM_N); + } + + /* Multiply public key by y into v polynomial. + * Step 21: ... t_hat_trans o y_hat ... */ + mlkem_pointwise_acc_mont(v, t, y, k); + /* Inverse transform v. + * Step 22: ... InvNTT(t_hat_trans o y_hat) ... */ + mlkem_invntt(v); + } + /* Add errors and message to v and reduce. + * Step 21: v <- InvNTT(t_hat_trans o y_hat) + e_2 + mu) */ + mlkem_add3_reduce(v, e2, m); +} +#endif /* !WOLFSSL_MLKEM_NO_ENCAPSULATE || !WOLFSSL_MLKEM_NO_DECAPSULATE */ + +#ifndef WOLFSSL_MLKEM_NO_DECAPSULATE +/* Decapsulate message. + * + * FIPS 203, Algorithm 15: K-PKE.Decrypt(dk_PKE,c) + * Uses the decryption key to decrypt a ciphertext. + * ... + * 6: w <- v' - InvNTT(s_hat_trans o NTT(u')) + * ... + * + * @param [in] s Decryption key as vector of polynomials. + * @param [out] w Message polynomial. + * @param [in] u Vector of polynomials containing error. + * @param [in] v Encapsulated message polynomial. + * @param [in] k Number of polynomials in vector. + */ +void mlkem_decapsulate(const sword16* s, sword16* w, sword16* u, + const sword16* v, int k) +{ + int i; + +#ifndef WOLFSSL_AARCH64_NO_SQRDMLSH + if (IS_AARCH64_RDM(cpuid_flags)) { + /* Transform u. All of result used in calculation of w. + * Step 6: ... NTT(u') */ + for (i = 0; i < k; ++i) { + mlkem_ntt_sqrdmlsh(u + i * MLKEM_N); + } + + /* Multiply private key by u into w polynomial. + * Step 6: ... s_hat_trans o NTT(u') */ + mlkem_pointwise_acc_mont(w, s, u, k); + /* Inverse transform w. + * Step 6: ... InvNTT(s_hat_trans o NTT(u')) */ + mlkem_invntt_sqrdmlsh(w); + } + else +#endif + { + /* Transform u. All of result used in calculation of w. + * Step 6: ... NTT(u') */ + for (i = 0; i < k; ++i) { + mlkem_ntt(u + i * MLKEM_N); + } + + /* Multiply private key by u into w polynomial. + * Step 6: ... s_hat_trans o NTT(u') */ + mlkem_pointwise_acc_mont(w, s, u, k); + /* Inverse transform w. + * Step 6: ... InvNTT(s_hat_trans o NTT(u')) */ + mlkem_invntt(w); + } + /* Subtract errors (in w) out of v and reduce into w. + * Step 6: w <- v' - InvNTT(s_hat_trans o NTT(u')) */ + mlkem_rsub_reduce(w, v); +} +#endif /* !WOLFSSL_MLKEM_NO_DECAPSULATE */ + +#else + +#ifndef WOLFSSL_MLKEM_NO_MAKE_KEY + +#if !defined(WOLFSSL_MLKEM_SMALL) && !defined(WOLFSSL_MLKEM_NO_LARGE_CODE) +/* Number-Theoretic Transform. + * + * FIPS 203, Algorithm 9: NTT(f) + * Computes the NTT representation f_hat of the given polynomial f element of + * R_q. + * 1: f_hat <- f + * 2: i <- 1 + * 3: for (len <- 128; len >= 2; len <- len/2) + * 4: for (start <- 0; start < 256; start <- start + 2.len) + * 5: zeta <- zetas^BitRev_7(i) mod q + * 6: i <- i + 1 + * 7: for (j <- start; j < start + len; j++) + * 8: t <- zeta.f[j+len] + * 9: f_hat[j+len] <- f_hat[j] - t + * 10: f_hat[j] <- f_hat[j] - t + * 11: end for + * 12: end for + * 13: end for + * 14: return f_hat + * + * @param [in, out] r Polynomial to transform. + */ +static void mlkem_ntt_add_to(sword16* r, sword16* a) +{ +#if defined(WOLFSSL_MLKEM_NTT_UNROLL) + /* Unroll len loop (Step 3). */ + unsigned int k = 1; + unsigned int j; + unsigned int start; + sword16 zeta = zetas[k++]; + + /* len = 128 */ + for (j = 0; j < MLKEM_N / 2; ++j) { + sword32 p = (sword32)zeta * r[j + MLKEM_N / 2]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[j]; + r[j + MLKEM_N / 2] = rj - t; + r[j] = rj + t; + } + /* len = 64 */ + for (start = 0; start < MLKEM_N; start += 2 * 64) { + zeta = zetas[k++]; + for (j = 0; j < 64; ++j) { + sword32 p = (sword32)zeta * r[start + j + 64]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[start + j]; + r[start + j + 64] = rj - t; + r[start + j] = rj + t; + } + } + /* len = 32 */ + for (start = 0; start < MLKEM_N; start += 2 * 32) { + zeta = zetas[k++]; + for (j = 0; j < 32; ++j) { + sword32 p = (sword32)zeta * r[start + j + 32]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[start + j]; + r[start + j + 32] = rj - t; + r[start + j] = rj + t; + } + } + /* len = 16 */ + for (start = 0; start < MLKEM_N; start += 2 * 16) { + zeta = zetas[k++]; + for (j = 0; j < 16; ++j) { + sword32 p = (sword32)zeta * r[start + j + 16]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[start + j]; + r[start + j + 16] = rj - t; + r[start + j] = rj + t; + } + } + /* len = 8 */ + for (start = 0; start < MLKEM_N; start += 2 * 8) { + zeta = zetas[k++]; + for (j = 0; j < 8; ++j) { + sword32 p = (sword32)zeta * r[start + j + 8]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[start + j]; + r[start + j + 8] = rj - t; + r[start + j] = rj + t; + } + } + /* len = 4 */ + for (start = 0; start < MLKEM_N; start += 2 * 4) { + zeta = zetas[k++]; + for (j = 0; j < 4; ++j) { + sword32 p = (sword32)zeta * r[start + j + 4]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[start + j]; + r[start + j + 4] = rj - t; + r[start + j] = rj + t; + } + } + /* len = 2 */ + for (start = 0; start < MLKEM_N; start += 2 * 2) { + zeta = zetas[k++]; + for (j = 0; j < 2; ++j) { + sword32 p = (sword32)zeta * r[start + j + 2]; + sword16 t = MLKEM_MONT_RED(p); + sword16 rj = r[start + j]; + r[start + j + 2] = rj - t; + r[start + j] = rj + t; + } + } + /* Reduce coefficients with quick algorithm. */ + for (j = 0; j < MLKEM_N; ++j) { + sword16 t = a[j] + r[j]; + a[j] = MLKEM_BARRETT_RED(t); + } +#else /* !WOLFSSL_MLKEM_NTT_UNROLL */ + /* Unroll len (2, 3, 2) and start loops. */ + unsigned int j; + sword16 t0; + sword16 t1; + sword16 t2; + sword16 t3; + + /* len = 128,64 */ + sword16 zeta128 = zetas[1]; + sword16 zeta64_0 = zetas[2]; + sword16 zeta64_1 = zetas[3]; + for (j = 0; j < MLKEM_N / 8; j++) { + sword16 r0 = r[j + 0]; + sword16 r1 = r[j + 32]; + sword16 r2 = r[j + 64]; + sword16 r3 = r[j + 96]; + sword16 r4 = r[j + 128]; + sword16 r5 = r[j + 160]; + sword16 r6 = r[j + 192]; + sword16 r7 = r[j + 224]; + + t0 = MLKEM_MONT_RED((sword32)zeta128 * r4); + t1 = MLKEM_MONT_RED((sword32)zeta128 * r5); + t2 = MLKEM_MONT_RED((sword32)zeta128 * r6); + t3 = MLKEM_MONT_RED((sword32)zeta128 * r7); + r4 = r0 - t0; + r5 = r1 - t1; + r6 = r2 - t2; + r7 = r3 - t3; + r0 += t0; + r1 += t1; + r2 += t2; + r3 += t3; + + t0 = MLKEM_MONT_RED((sword32)zeta64_0 * r2); + t1 = MLKEM_MONT_RED((sword32)zeta64_0 * r3); + t2 = MLKEM_MONT_RED((sword32)zeta64_1 * r6); + t3 = MLKEM_MONT_RED((sword32)zeta64_1 * r7); + r2 = r0 - t0; + r3 = r1 - t1; + r6 = r4 - t2; + r7 = r5 - t3; + r0 += t0; + r1 += t1; + r4 += t2; + r5 += t3; + + r[j + 0] = r0; + r[j + 32] = r1; + r[j + 64] = r2; + r[j + 96] = r3; + r[j + 128] = r4; + r[j + 160] = r5; + r[j + 192] = r6; + r[j + 224] = r7; + } + + /* len = 32,16,8 */ + for (j = 0; j < MLKEM_N; j += 64) { + int i; + sword16 zeta32 = zetas[ 4 + j / 64 + 0]; + sword16 zeta16_0 = zetas[ 8 + j / 32 + 0]; + sword16 zeta16_1 = zetas[ 8 + j / 32 + 1]; + sword16 zeta8_0 = zetas[16 + j / 16 + 0]; + sword16 zeta8_1 = zetas[16 + j / 16 + 1]; + sword16 zeta8_2 = zetas[16 + j / 16 + 2]; + sword16 zeta8_3 = zetas[16 + j / 16 + 3]; + for (i = 0; i < 8; i++) { + sword16 r0 = r[j + i + 0]; + sword16 r1 = r[j + i + 8]; + sword16 r2 = r[j + i + 16]; + sword16 r3 = r[j + i + 24]; + sword16 r4 = r[j + i + 32]; + sword16 r5 = r[j + i + 40]; + sword16 r6 = r[j + i + 48]; + sword16 r7 = r[j + i + 56]; + + t0 = MLKEM_MONT_RED((sword32)zeta32 * r4); + t1 = MLKEM_MONT_RED((sword32)zeta32 * r5); + t2 = MLKEM_MONT_RED((sword32)zeta32 * r6); + t3 = MLKEM_MONT_RED((sword32)zeta32 * r7); + r4 = r0 - t0; + r5 = r1 - t1; + r6 = r2 - t2; + r7 = r3 - t3; + r0 += t0; + r1 += t1; + r2 += t2; + r3 += t3; + + t0 = MLKEM_MONT_RED((sword32)zeta16_0 * r2); + t1 = MLKEM_MONT_RED((sword32)zeta16_0 * r3); + t2 = MLKEM_MONT_RED((sword32)zeta16_1 * r6); + t3 = MLKEM_MONT_RED((sword32)zeta16_1 * r7); + r2 = r0 - t0; + r3 = r1 - t1; + r6 = r4 - t2; + r7 = r5 - t3; + r0 += t0; + r1 += t1; + r4 += t2; + r5 += t3; + + t0 = MLKEM_MONT_RED((sword32)zeta8_0 * r1); + t1 = MLKEM_MONT_RED((sword32)zeta8_1 * r3); + t2 = MLKEM_MONT_RED((sword32)zeta8_2 * r5); + t3 = MLKEM_MONT_RED((sword32)zeta8_3 * r7); + r1 = r0 - t0; + r3 = r2 - t1; + r5 = r4 - t2; + r7 = r6 - t3; + r0 += t0; + r2 += t1; + r4 += t2; + r6 += t3; + + r[j + i + 0] = r0; + r[j + i + 8] = r1; + r[j + i + 16] = r2; + r[j + i + 24] = r3; + r[j + i + 32] = r4; + r[j + i + 40] = r5; + r[j + i + 48] = r6; + r[j + i + 56] = r7; + } + } + + /* len = 4,2 and Final reduction */ + for (j = 0; j < MLKEM_N; j += 8) { + sword16 zeta4 = zetas[32 + j / 8 + 0]; + sword16 zeta2_0 = zetas[64 + j / 4 + 0]; + sword16 zeta2_1 = zetas[64 + j / 4 + 1]; + sword16 r0 = r[j + 0]; + sword16 r1 = r[j + 1]; + sword16 r2 = r[j + 2]; + sword16 r3 = r[j + 3]; + sword16 r4 = r[j + 4]; + sword16 r5 = r[j + 5]; + sword16 r6 = r[j + 6]; + sword16 r7 = r[j + 7]; + + t0 = MLKEM_MONT_RED((sword32)zeta4 * r4); + t1 = MLKEM_MONT_RED((sword32)zeta4 * r5); + t2 = MLKEM_MONT_RED((sword32)zeta4 * r6); + t3 = MLKEM_MONT_RED((sword32)zeta4 * r7); + r4 = r0 - t0; + r5 = r1 - t1; + r6 = r2 - t2; + r7 = r3 - t3; + r0 += t0; + r1 += t1; + r2 += t2; + r3 += t3; + + t0 = MLKEM_MONT_RED((sword32)zeta2_0 * r2); + t1 = MLKEM_MONT_RED((sword32)zeta2_0 * r3); + t2 = MLKEM_MONT_RED((sword32)zeta2_1 * r6); + t3 = MLKEM_MONT_RED((sword32)zeta2_1 * r7); + r2 = r0 - t0; + r3 = r1 - t1; + r6 = r4 - t2; + r7 = r5 - t3; + r0 += t0; + r1 += t1; + r4 += t2; + r5 += t3; + + r0 += a[j + 0]; + r1 += a[j + 1]; + r2 += a[j + 2]; + r3 += a[j + 3]; + r4 += a[j + 4]; + r5 += a[j + 5]; + r6 += a[j + 6]; + r7 += a[j + 7]; + + a[j + 0] = MLKEM_BARRETT_RED(r0); + a[j + 1] = MLKEM_BARRETT_RED(r1); + a[j + 2] = MLKEM_BARRETT_RED(r2); + a[j + 3] = MLKEM_BARRETT_RED(r3); + a[j + 4] = MLKEM_BARRETT_RED(r4); + a[j + 5] = MLKEM_BARRETT_RED(r5); + a[j + 6] = MLKEM_BARRETT_RED(r6); + a[j + 7] = MLKEM_BARRETT_RED(r7); + } +#endif /* !WOLFSSL_MLKEM_NTT_UNROLL */ +} +#endif /* !WOLFSSL_MLKEM_SMALL && !WOLFSSL_MLKEM_NO_LARGE_CODE */ + +#ifndef WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM +/* Generate a public-private key pair from randomly generated data. + * + * FIPS 203, Algorithm 13: K-PKE.KeyGen(d) + * ... + * 16: s_hat <- NTT(s) + * 17: e_hat <- NTT(e) + * 18: t^hat <- A_hat o s_hat + e_hat + * ... + * + * @param [in, out] s Private key vector of polynomials. + * @param [out] t Public key vector of polynomials. + * @param [in] e Error values as a vector of polynomials. Modified. + * @param [in] a Random values in an array of vectors of polynomials. + * @param [in] k Number of polynomials in vector. + */ +static void mlkem_keygen_c(sword16* s, sword16* t, sword16* e, const sword16* a, + int k) +{ + int i; + + /* Transform private key. All of result used in public key calculation + * Step 16: s_hat = NTT(s) */ + for (i = 0; i < k; ++i) { + mlkem_ntt(s + i * MLKEM_N); + } + + /* For each polynomial in the vectors. + * Step 17, Step 18: Calculate public from A_hat, s_hat and e_hat. */ + for (i = 0; i < k; ++i) { + unsigned int j; + + /* Multiply a by private into public polynomial. + * Step 18: ... A_hat o s_hat ... */ + mlkem_pointwise_acc_mont(t + i * MLKEM_N, a + i * k * MLKEM_N, s, k); + /* Convert public polynomial to Montgomery form. + * Step 18: ... MontRed(A_hat o s_hat) ... */ + for (j = 0; j < MLKEM_N; ++j) { + sword32 n = t[i * MLKEM_N + j] * (sword32)MLKEM_F; + t[i * MLKEM_N + j] = MLKEM_MONT_RED(n); + } + /* Transform error values polynomial. + * Step 17: e_hat = NTT(e) */ +#if defined(WOLFSSL_MLKEM_SMALL) || defined(WOLFSSL_MLKEM_NO_LARGE_CODE) + mlkem_ntt(e + i * MLKEM_N); + /* Add errors to public key and reduce. + * Step 18: t_hat = BarrettRed(MontRed(A_hat o s_hat) + e_hat) */ + for (j = 0; j < MLKEM_N; ++j) { + sword16 n = t[i * MLKEM_N + j] + e[i * MLKEM_N + j]; + t[i * MLKEM_N + j] = MLKEM_BARRETT_RED(n); + } +#else + /* Add errors to public key and reduce. + * Step 18: t_hat = BarrettRed(MontRed(A_hat o s_hat) + e_hat) */ + mlkem_ntt_add_to(e + i * MLKEM_N, t + i * MLKEM_N); +#endif + } +} + +/* Generate a public-private key pair from randomly generated data. + * + * FIPS 203, Algorithm 13: K-PKE.KeyGen(d) + * ... + * 16: s_hat <- NTT(s) + * 17: e_hat <- NTT(e) + * 18: t^hat <- A_hat o s_hat + e_hat + * ... + * + * @param [in, out] s Private key vector of polynomials. + * @param [out] t Public key vector of polynomials. + * @param [in] e Error values as a vector of polynomials. Modified. + * @param [in] a Random values in an array of vectors of polynomials. + * @param [in] k Number of polynomials in vector. + */ +void mlkem_keygen(sword16* s, sword16* t, sword16* e, const sword16* a, int k) +{ +#ifdef USE_INTEL_SPEEDUP + if ((IS_INTEL_AVX2(cpuid_flags)) && (SAVE_VECTOR_REGISTERS2() == 0)) { + /* Alg 13: Steps 16-18 */ + mlkem_keygen_avx2(s, t, e, a, k); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + /* Alg 13: Steps 16-18 */ + mlkem_keygen_c(s, t, e, a, k); + } +} + +#else /* WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM */ + +/* Generate a public-private key pair from randomly generated data. + * + * FIPS 203, Algorithm 13: K-PKE.KeyGen(d) + * 3: for (i <- 0; i < k; i++) > generate matrix A_hat + * ... (generate A[i]) + * 7: end for + * ... + * 9: s[i] <- SamplePolyCBD_eta_1(PRF_eta_1(rho, N)) + * ... + * 16: s_hat <- NTT(s) + * 17: e_hat <- NTT(e) + * 18: t^hat <- A_hat o s_hat + e_hat + * ... + * + * @param [in, out] s Private key vector of polynomials. + * @param [out] tv Public key vector of polynomials. + * @param [in] prf XOF object. + * @param [in] tv Temporary vector of polynomials. + * @param [in] k Number of polynomials in vector. + * @param [in] rho Random seed to generate matrix A from. + * @param [in] sigma Random seed to generate noise from. + */ +int mlkem_keygen_seeds(sword16* s, sword16* t, MLKEM_PRF_T* prf, + sword16* tv, int k, byte* rho, byte* sigma) +{ + int i; + int ret = 0; + sword16* ai = tv; + sword16* e = tv; + + /* Transform private key. All of result used in public key calculation + * Step 16: s_hat = NTT(s) */ + for (i = 0; i < k; ++i) { + mlkem_ntt(s + i * MLKEM_N); + } + + /* For each polynomial in the vectors. + * Step 17, Step 18: Calculate public from A_hat, s_hat and e_hat. */ + for (i = 0; i < k; ++i) { + unsigned int j; + + /* Generate a vector of matrix A. + * Steps 4-6: generate A[i] */ + ret = mlkem_gen_matrix_i(prf, ai, k, rho, i, 0); + if (ret != 0) { + break; + } + + /* Multiply a by private into public polynomial. + * Step 18: ... A_hat o s_hat ... */ + mlkem_pointwise_acc_mont(t + i * MLKEM_N, ai, s, k); + /* Convert public polynomial to Montgomery form. + * Step 18: ... MontRed(A_hat o s_hat) ... */ + for (j = 0; j < MLKEM_N; ++j) { + sword32 n = t[i * MLKEM_N + j] * (sword32)MLKEM_F; + t[i * MLKEM_N + j] = MLKEM_MONT_RED(n); + } + + /* Generate noise using PRF. + * Step 9: s[i] <- SamplePolyCBD_eta_1(PRF_eta_1(rho, N)) */ + ret = mlkem_get_noise_i(prf, k, e, sigma, i, 1); + if (ret != 0) { + break; + } + /* Transform error values polynomial. + * Step 17: e_hat = NTT(e) */ +#if defined(WOLFSSL_MLKEM_SMALL) || defined(WOLFSSL_MLKEM_NO_LARGE_CODE) + mlkem_ntt(e); + /* Add errors to public key and reduce. + * Step 18: t_hat = BarrettRed(MontRed(A_hat o s_hat) + e_hat) */ + for (j = 0; j < MLKEM_N; ++j) { + sword16 n = t[i * MLKEM_N + j] + e[j]; + t[i * MLKEM_N + j] = MLKEM_BARRETT_RED(n); + } +#else + /* Add errors to public key and reduce. + * Step 18: t_hat = BarrettRed(MontRed(A_hat o s_hat) + e_hat) */ + mlkem_ntt_add_to(e, t + i * MLKEM_N); +#endif + } + + return ret; +} + +#endif /* WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM */ +#endif /* !WOLFSSL_MLKEM_NO_MAKE_KEY */ + +#if !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) || \ + !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) +#ifndef WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM +/* Encapsulate message. + * + * @param [in] pub Public key vector of polynomials. + * @param [out] u Vector of polynomials. + * @param [out] v Polynomial. + * @param [in] a Array of vector of polynomials. + * @param [in] y Vector of polynomials. + * @param [in] e1 Error Vector of polynomials. + * @param [in] e2 Error polynomial. + * @param [in] m Message polynomial. + * @param [in] k Number of polynomials in vector. + * @return 0 on success. + */ +static void mlkem_encapsulate_c(const sword16* pub, sword16* u, sword16* v, + const sword16* a, sword16* y, const sword16* e1, const sword16* e2, + const sword16* m, int k) +{ + int i; + + /* Transform y. All of result used in calculation of u and v. */ + for (i = 0; i < k; ++i) { + mlkem_ntt(y + i * MLKEM_N); + } + + /* For each polynomial in the vectors. */ + for (i = 0; i < k; ++i) { + unsigned int j; + + /* Multiply at by y into u polynomial. */ + mlkem_pointwise_acc_mont(u + i * MLKEM_N, a + i * k * MLKEM_N, y, k); + /* Inverse transform u polynomial. */ + mlkem_invntt(u + i * MLKEM_N); + /* Add errors to u and reduce. */ +#if defined(WOLFSSL_MLKEM_SMALL) || defined(WOLFSSL_MLKEM_NO_LARGE_CODE) + for (j = 0; j < MLKEM_N; ++j) { + sword16 t = u[i * MLKEM_N + j] + e1[i * MLKEM_N + j]; + u[i * MLKEM_N + j] = MLKEM_BARRETT_RED(t); + } +#else + for (j = 0; j < MLKEM_N; j += 8) { + sword16 t0 = u[i * MLKEM_N + j + 0] + e1[i * MLKEM_N + j + 0]; + sword16 t1 = u[i * MLKEM_N + j + 1] + e1[i * MLKEM_N + j + 1]; + sword16 t2 = u[i * MLKEM_N + j + 2] + e1[i * MLKEM_N + j + 2]; + sword16 t3 = u[i * MLKEM_N + j + 3] + e1[i * MLKEM_N + j + 3]; + sword16 t4 = u[i * MLKEM_N + j + 4] + e1[i * MLKEM_N + j + 4]; + sword16 t5 = u[i * MLKEM_N + j + 5] + e1[i * MLKEM_N + j + 5]; + sword16 t6 = u[i * MLKEM_N + j + 6] + e1[i * MLKEM_N + j + 6]; + sword16 t7 = u[i * MLKEM_N + j + 7] + e1[i * MLKEM_N + j + 7]; + u[i * MLKEM_N + j + 0] = MLKEM_BARRETT_RED(t0); + u[i * MLKEM_N + j + 1] = MLKEM_BARRETT_RED(t1); + u[i * MLKEM_N + j + 2] = MLKEM_BARRETT_RED(t2); + u[i * MLKEM_N + j + 3] = MLKEM_BARRETT_RED(t3); + u[i * MLKEM_N + j + 4] = MLKEM_BARRETT_RED(t4); + u[i * MLKEM_N + j + 5] = MLKEM_BARRETT_RED(t5); + u[i * MLKEM_N + j + 6] = MLKEM_BARRETT_RED(t6); + u[i * MLKEM_N + j + 7] = MLKEM_BARRETT_RED(t7); + } +#endif + } + + /* Multiply public key by y into v polynomial. */ + mlkem_pointwise_acc_mont(v, pub, y, k); + /* Inverse transform v. */ + mlkem_invntt(v); + /* Add errors and message to v and reduce. */ + for (i = 0; i < MLKEM_N; ++i) { + sword16 t = v[i] + e2[i] + m[i]; + v[i] = MLKEM_BARRETT_RED(t); + } +} + +/* Encapsulate message. + * + * @param [in] pub Public key vector of polynomials. + * @param [out] u Vector of polynomials. + * @param [out] v Polynomial. + * @param [in] a Array of vector of polynomials. + * @param [in] y Vector of polynomials. + * @param [in] e1 Error Vector of polynomials. + * @param [in] e2 Error polynomial. + * @param [in] m Message polynomial. + * @param [in] k Number of polynomials in vector. + * @return 0 on success. + */ +void mlkem_encapsulate(const sword16* pub, sword16* u, sword16* v, + const sword16* a, sword16* y, const sword16* e1, const sword16* e2, + const sword16* m, int k) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + mlkem_encapsulate_avx2(pub, u, v, a, y, e1, e2, m, k); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_encapsulate_c(pub, u, v, a, y, e1, e2, m, k); + } +} + +#else + +/* Encapsulate message. + * + * @param [in] pub Public key vector of polynomials. + * @param [in] prf XOF object. + * @param [out] u Vector of polynomials. + * @param [in, out] tp Polynomial. + * @param [in] y Vector of polynomials. + * @param [in] k Number of polynomials in vector. + * @param [in] msg Message to encapsulate. + * @param [in] seed Random seed to generate matrix A from. + * @param [in] coins Random seed to generate noise from. + */ +int mlkem_encapsulate_seeds(const sword16* pub, MLKEM_PRF_T* prf, sword16* u, + sword16* tp, sword16* y, int k, const byte* msg, byte* seed, byte* coins) +{ + int ret = 0; + int i; + sword16* a = tp; + sword16* e1 = tp; + sword16* v = tp; + sword16* e2 = tp + MLKEM_N; + sword16* m = y; + + /* Transform y. All of result used in calculation of u and v. */ + for (i = 0; i < k; ++i) { + mlkem_ntt(y + i * MLKEM_N); + } + + /* For each polynomial in the vectors. */ + for (i = 0; i < k; ++i) { + unsigned int j; + + /* Generate a vector of matrix A. */ + ret = mlkem_gen_matrix_i(prf, a, k, seed, i, 1); + if (ret != 0) { + break; + } + + /* Multiply at by y into u polynomial. */ + mlkem_pointwise_acc_mont(u + i * MLKEM_N, a, y, k); + /* Inverse transform u polynomial. */ + mlkem_invntt(u + i * MLKEM_N); + + /* Generate noise using PRF. */ + ret = mlkem_get_noise_i(prf, k, e1, coins, i, 0); + if (ret != 0) { + break; + } + /* Add errors to u and reduce. */ +#if defined(WOLFSSL_MLKEM_SMALL) || defined(WOLFSSL_MLKEM_NO_LARGE_CODE) + for (j = 0; j < MLKEM_N; ++j) { + sword16 t = u[i * MLKEM_N + j] + e1[j]; + u[i * MLKEM_N + j] = MLKEM_BARRETT_RED(t); + } +#else + for (j = 0; j < MLKEM_N; j += 8) { + sword16 t0 = u[i * MLKEM_N + j + 0] + e1[j + 0]; + sword16 t1 = u[i * MLKEM_N + j + 1] + e1[j + 1]; + sword16 t2 = u[i * MLKEM_N + j + 2] + e1[j + 2]; + sword16 t3 = u[i * MLKEM_N + j + 3] + e1[j + 3]; + sword16 t4 = u[i * MLKEM_N + j + 4] + e1[j + 4]; + sword16 t5 = u[i * MLKEM_N + j + 5] + e1[j + 5]; + sword16 t6 = u[i * MLKEM_N + j + 6] + e1[j + 6]; + sword16 t7 = u[i * MLKEM_N + j + 7] + e1[j + 7]; + u[i * MLKEM_N + j + 0] = MLKEM_BARRETT_RED(t0); + u[i * MLKEM_N + j + 1] = MLKEM_BARRETT_RED(t1); + u[i * MLKEM_N + j + 2] = MLKEM_BARRETT_RED(t2); + u[i * MLKEM_N + j + 3] = MLKEM_BARRETT_RED(t3); + u[i * MLKEM_N + j + 4] = MLKEM_BARRETT_RED(t4); + u[i * MLKEM_N + j + 5] = MLKEM_BARRETT_RED(t5); + u[i * MLKEM_N + j + 6] = MLKEM_BARRETT_RED(t6); + u[i * MLKEM_N + j + 7] = MLKEM_BARRETT_RED(t7); + } +#endif + } + + /* Multiply public key by y into v polynomial. */ + mlkem_pointwise_acc_mont(v, pub, y, k); + /* Inverse transform v. */ + mlkem_invntt(v); + + mlkem_from_msg(m, msg); + + /* Generate noise using PRF. */ + coins[WC_ML_KEM_SYM_SZ] = 2 * k; + ret = mlkem_get_noise_eta2_c(prf, e2, coins); + if (ret == 0) { + /* Add errors and message to v and reduce. */ + #if defined(WOLFSSL_MLKEM_SMALL) || defined(WOLFSSL_MLKEM_NO_LARGE_CODE) + for (i = 0; i < MLKEM_N; ++i) { + sword16 t = v[i] + e2[i] + m[i]; + v[i] = MLKEM_BARRETT_RED(t); + } + #else + for (i = 0; i < MLKEM_N; i += 8) { + sword16 t0 = v[i + 0] + e2[i + 0] + m[i + 0]; + sword16 t1 = v[i + 1] + e2[i + 1] + m[i + 1]; + sword16 t2 = v[i + 2] + e2[i + 2] + m[i + 2]; + sword16 t3 = v[i + 3] + e2[i + 3] + m[i + 3]; + sword16 t4 = v[i + 4] + e2[i + 4] + m[i + 4]; + sword16 t5 = v[i + 5] + e2[i + 5] + m[i + 5]; + sword16 t6 = v[i + 6] + e2[i + 6] + m[i + 6]; + sword16 t7 = v[i + 7] + e2[i + 7] + m[i + 7]; + v[i + 0] = MLKEM_BARRETT_RED(t0); + v[i + 1] = MLKEM_BARRETT_RED(t1); + v[i + 2] = MLKEM_BARRETT_RED(t2); + v[i + 3] = MLKEM_BARRETT_RED(t3); + v[i + 4] = MLKEM_BARRETT_RED(t4); + v[i + 5] = MLKEM_BARRETT_RED(t5); + v[i + 6] = MLKEM_BARRETT_RED(t6); + v[i + 7] = MLKEM_BARRETT_RED(t7); + } + #endif + } + + return ret; +} +#endif +#endif /* !WOLFSSL_MLKEM_NO_ENCAPSULATE || !WOLFSSL_MLKEM_NO_DECAPSULATE */ + +#ifndef WOLFSSL_MLKEM_NO_DECAPSULATE + +/* Decapsulate message. + * + * FIPS 203, Algorithm 15: K-PKE.Decrypt(dk_PKE,c) + * Uses the decryption key to decrypt a ciphertext. + * ... + * 6: w <- v' - InvNTT(s_hat_trans o NTT(u')) + * ... + * + * @param [in] s Private key vector of polynomials. + * @param [out] w Message polynomial. + * @param [in] u Vector of polynomials containing error. + * @param [in] v Encapsulated message polynomial. + * @param [in] k Number of polynomials in vector. + */ +static void mlkem_decapsulate_c(const sword16* s, sword16* w, sword16* u, + const sword16* v, int k) +{ + int i; + + /* Transform u. All of result used in calculation of w. + * Step 6: ... NTT(u') */ + for (i = 0; i < k; ++i) { + mlkem_ntt(u + i * MLKEM_N); + } + + /* Multiply private key by u into w polynomial. + * Step 6: ... s_hat_trans o NTT(u') */ + mlkem_pointwise_acc_mont(w, s, u, k); + /* Inverse transform w. + * Step 6: ... InvNTT(s_hat_trans o NTT(u')) */ + mlkem_invntt(w); + /* Subtract errors (in w) out of v and reduce into w. + * Step 6: w <- v' - InvNTT(s_hat_trans o NTT(u')) */ + for (i = 0; i < MLKEM_N; ++i) { + sword16 t = v[i] - w[i]; + w[i] = MLKEM_BARRETT_RED(t); + } +} + +/* Decapsulate message. + * + * FIPS 203, Algorithm 15: K-PKE.Decrypt(dk_PKE,c) + * Uses the decryption key to decrypt a ciphertext. + * ... + * 6: w <- v' - InvNTT(s_hat_trans o NTT(u')) + * ... + * + * @param [in] s Private key vector of polynomials. + * @param [out] w Message polynomial. + * @param [in] u Vector of polynomials containing error. + * @param [in] v Encapsulated message polynomial. + * @param [in] k Number of polynomials in vector. + */ +void mlkem_decapsulate(const sword16* s, sword16* w, sword16* u, + const sword16* v, int k) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + mlkem_decapsulate_avx2(s, w, u, v, k); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_decapsulate_c(s, w, u, v, k); + } +} + +#endif /* !WOLFSSL_MLKEM_ NO_DECAPSULATE */ +#endif + +/******************************************************************************/ + +#ifdef USE_INTEL_SPEEDUP +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) +/* Deterministically generate a matrix (or transpose) of uniform integers mod q. + * + * Seed used with XOF to generate random bytes. + * + * @param [out] a Matrix of uniform integers. + * @param [in] seed Bytes to seed XOF generation. + * @param [in] transposed Whether A or A^T is generated. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. Only possible when + * WOLFSSL_SMALL_STACK is defined. + */ +static int mlkem_gen_matrix_k2_avx2(sword16* a, byte* seed, int transposed) +{ + int i; + byte rand[4 * GEN_MATRIX_SIZE + 2]; + word64 state[25 * 4]; + unsigned int ctr0; + unsigned int ctr1; + unsigned int ctr2; + unsigned int ctr3; + byte* p; + + /* Loading 64 bits, only using 48 bits. Loading 2 bytes more than used. */ + rand[4 * GEN_MATRIX_SIZE + 0] = 0xff; + rand[4 * GEN_MATRIX_SIZE + 1] = 0xff; + + if (!transposed) { + state[4*4 + 0] = 0x1f0000 + 0x000; + state[4*4 + 1] = 0x1f0000 + 0x001; + state[4*4 + 2] = 0x1f0000 + 0x100; + state[4*4 + 3] = 0x1f0000 + 0x101; + } + else { + state[4*4 + 0] = 0x1f0000 + 0x000; + state[4*4 + 1] = 0x1f0000 + 0x100; + state[4*4 + 2] = 0x1f0000 + 0x001; + state[4*4 + 3] = 0x1f0000 + 0x101; + } + + mlkem_sha3_128_blocksx4_seed_avx2(state, seed); + mlkem_redistribute_21_rand_avx2(state, rand + 0 * GEN_MATRIX_SIZE, + rand + 1 * GEN_MATRIX_SIZE, rand + 2 * GEN_MATRIX_SIZE, + rand + 3 * GEN_MATRIX_SIZE); + for (i = SHA3_128_BYTES; i < GEN_MATRIX_SIZE; i += SHA3_128_BYTES) { + sha3_blocksx4_avx2(state); + mlkem_redistribute_21_rand_avx2(state, rand + i + 0 * GEN_MATRIX_SIZE, + rand + i + 1 * GEN_MATRIX_SIZE, rand + i + 2 * GEN_MATRIX_SIZE, + rand + i + 3 * GEN_MATRIX_SIZE); + } + + /* Sample random bytes to create a polynomial. */ + p = rand; + ctr0 = mlkem_rej_uniform_n_avx2(a + 0 * MLKEM_N, MLKEM_N, p, + GEN_MATRIX_SIZE); + p += GEN_MATRIX_SIZE; + ctr1 = mlkem_rej_uniform_n_avx2(a + 1 * MLKEM_N, MLKEM_N, p, + GEN_MATRIX_SIZE); + p += GEN_MATRIX_SIZE; + ctr2 = mlkem_rej_uniform_n_avx2(a + 2 * MLKEM_N, MLKEM_N, p, + GEN_MATRIX_SIZE); + p += GEN_MATRIX_SIZE; + ctr3 = mlkem_rej_uniform_n_avx2(a + 3 * MLKEM_N, MLKEM_N, p, + GEN_MATRIX_SIZE); + /* Create more blocks if too many rejected. */ + while ((ctr0 < MLKEM_N) || (ctr1 < MLKEM_N) || (ctr2 < MLKEM_N) || + (ctr3 < MLKEM_N)) { + sha3_blocksx4_avx2(state); + mlkem_redistribute_21_rand_avx2(state, rand + 0 * GEN_MATRIX_SIZE, + rand + 1 * GEN_MATRIX_SIZE, rand + 2 * GEN_MATRIX_SIZE, + rand + 3 * GEN_MATRIX_SIZE); + + p = rand; + ctr0 += mlkem_rej_uniform_avx2(a + 0 * MLKEM_N + ctr0, MLKEM_N - ctr0, + p, XOF_BLOCK_SIZE); + p += GEN_MATRIX_SIZE; + ctr1 += mlkem_rej_uniform_avx2(a + 1 * MLKEM_N + ctr1, MLKEM_N - ctr1, + p, XOF_BLOCK_SIZE); + p += GEN_MATRIX_SIZE; + ctr2 += mlkem_rej_uniform_avx2(a + 2 * MLKEM_N + ctr2, MLKEM_N - ctr2, + p, XOF_BLOCK_SIZE); + p += GEN_MATRIX_SIZE; + ctr3 += mlkem_rej_uniform_avx2(a + 3 * MLKEM_N + ctr3, MLKEM_N - ctr3, + p, XOF_BLOCK_SIZE); + } + + return 0; +} +#endif + +#if defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768) +/* Deterministically generate a matrix (or transpose) of uniform integers mod q. + * + * Seed used with XOF to generate random bytes. + * + * @param [out] a Matrix of uniform integers. + * @param [in] seed Bytes to seed XOF generation. + * @param [in] transposed Whether A or A^T is generated. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. Only possible when + * WOLFSSL_SMALL_STACK is defined. + */ +static int mlkem_gen_matrix_k3_avx2(sword16* a, byte* seed, int transposed) +{ + int i; + int k; + byte rand[4 * GEN_MATRIX_SIZE + 2]; + word64 state[25 * 4]; + unsigned int ctr0; + unsigned int ctr1; + unsigned int ctr2; + unsigned int ctr3; + byte* p; + + /* Loading 64 bits, only using 48 bits. Loading 2 bytes more than used. */ + rand[4 * GEN_MATRIX_SIZE + 0] = 0xff; + rand[4 * GEN_MATRIX_SIZE + 1] = 0xff; + + for (k = 0; k < 2; k++) { + for (i = 0; i < 4; i++) { + if (!transposed) { + state[4*4 + i] = 0x1f0000 + (((k*4+i)/3) << 8) + ((k*4+i)%3); + } + else { + state[4*4 + i] = 0x1f0000 + (((k*4+i)%3) << 8) + ((k*4+i)/3); + } + } + + mlkem_sha3_128_blocksx4_seed_avx2(state, seed); + mlkem_redistribute_21_rand_avx2(state, + rand + 0 * GEN_MATRIX_SIZE, rand + 1 * GEN_MATRIX_SIZE, + rand + 2 * GEN_MATRIX_SIZE, rand + 3 * GEN_MATRIX_SIZE); + for (i = SHA3_128_BYTES; i < GEN_MATRIX_SIZE; i += SHA3_128_BYTES) { + sha3_blocksx4_avx2(state); + mlkem_redistribute_21_rand_avx2(state, + rand + i + 0 * GEN_MATRIX_SIZE, rand + i + 1 * GEN_MATRIX_SIZE, + rand + i + 2 * GEN_MATRIX_SIZE, rand + i + 3 * GEN_MATRIX_SIZE); + } + + /* Sample random bytes to create a polynomial. */ + p = rand; + ctr0 = mlkem_rej_uniform_n_avx2(a + 0 * MLKEM_N, MLKEM_N, p, + GEN_MATRIX_SIZE); + p += GEN_MATRIX_SIZE; + ctr1 = mlkem_rej_uniform_n_avx2(a + 1 * MLKEM_N, MLKEM_N, p, + GEN_MATRIX_SIZE); + p += GEN_MATRIX_SIZE; + ctr2 = mlkem_rej_uniform_n_avx2(a + 2 * MLKEM_N, MLKEM_N, p, + GEN_MATRIX_SIZE); + p += GEN_MATRIX_SIZE; + ctr3 = mlkem_rej_uniform_n_avx2(a + 3 * MLKEM_N, MLKEM_N, p, + GEN_MATRIX_SIZE); + /* Create more blocks if too many rejected. */ + while ((ctr0 < MLKEM_N) || (ctr1 < MLKEM_N) || (ctr2 < MLKEM_N) || + (ctr3 < MLKEM_N)) { + sha3_blocksx4_avx2(state); + mlkem_redistribute_21_rand_avx2(state, rand + 0 * GEN_MATRIX_SIZE, + rand + 1 * GEN_MATRIX_SIZE, rand + 2 * GEN_MATRIX_SIZE, + rand + 3 * GEN_MATRIX_SIZE); + + p = rand; + ctr0 += mlkem_rej_uniform_avx2(a + 0 * MLKEM_N + ctr0, + MLKEM_N - ctr0, p, XOF_BLOCK_SIZE); + p += GEN_MATRIX_SIZE; + ctr1 += mlkem_rej_uniform_avx2(a + 1 * MLKEM_N + ctr1, + MLKEM_N - ctr1, p, XOF_BLOCK_SIZE); + p += GEN_MATRIX_SIZE; + ctr2 += mlkem_rej_uniform_avx2(a + 2 * MLKEM_N + ctr2, + MLKEM_N - ctr2, p, XOF_BLOCK_SIZE); + p += GEN_MATRIX_SIZE; + ctr3 += mlkem_rej_uniform_avx2(a + 3 * MLKEM_N + ctr3, + MLKEM_N - ctr3, p, XOF_BLOCK_SIZE); + } + + a += 4 * MLKEM_N; + } + + readUnalignedWords64(state, seed, 4); + /* Transposed value same as not. */ + state[4] = 0x1f0000 + (2 << 8) + 2; + XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5)); + state[20] = W64LIT(0x8000000000000000); + for (i = 0; i < GEN_MATRIX_SIZE; i += SHA3_128_BYTES) { + if (IS_INTEL_BMI2(cpuid_flags)) { + sha3_block_bmi2(state); + } + else if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) + { + sha3_block_avx2(state); + RESTORE_VECTOR_REGISTERS(); + } + else { + BlockSha3(state); + } + XMEMCPY(rand + i, state, SHA3_128_BYTES); + } + ctr0 = mlkem_rej_uniform_n_avx2(a, MLKEM_N, rand, GEN_MATRIX_SIZE); + while (ctr0 < MLKEM_N) { + if (IS_INTEL_BMI2(cpuid_flags)) { + sha3_block_bmi2(state); + } + else if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) + { + sha3_block_avx2(state); + RESTORE_VECTOR_REGISTERS(); + } + else { + BlockSha3(state); + } + XMEMCPY(rand, state, SHA3_128_BYTES); + ctr0 += mlkem_rej_uniform_avx2(a + ctr0, MLKEM_N - ctr0, rand, + XOF_BLOCK_SIZE); + } + + return 0; +} +#endif +#if defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) +/* Deterministically generate a matrix (or transpose) of uniform integers mod q. + * + * Seed used with XOF to generate random bytes. + * + * @param [out] a Matrix of uniform integers. + * @param [in] seed Bytes to seed XOF generation. + * @param [in] transposed Whether A or A^T is generated. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. Only possible when + * WOLFSSL_SMALL_STACK is defined. + */ +static int mlkem_gen_matrix_k4_avx2(sword16* a, byte* seed, int transposed) +{ + int i; + int k; + byte rand[4 * GEN_MATRIX_SIZE + 2]; + word64 state[25 * 4]; + unsigned int ctr0; + unsigned int ctr1; + unsigned int ctr2; + unsigned int ctr3; + byte* p; + + /* Loading 64 bits, only using 48 bits. Loading 2 bytes more than used. */ + rand[4 * GEN_MATRIX_SIZE + 0] = 0xff; + rand[4 * GEN_MATRIX_SIZE + 1] = 0xff; + + for (k = 0; k < 4; k++) { + for (i = 0; i < 4; i++) { + if (!transposed) { + state[4*4 + i] = 0x1f0000 + (k << 8) + i; + } + else { + state[4*4 + i] = 0x1f0000 + (i << 8) + k; + } + } + + mlkem_sha3_128_blocksx4_seed_avx2(state, seed); + mlkem_redistribute_21_rand_avx2(state, + rand + 0 * GEN_MATRIX_SIZE, rand + 1 * GEN_MATRIX_SIZE, + rand + 2 * GEN_MATRIX_SIZE, rand + 3 * GEN_MATRIX_SIZE); + for (i = SHA3_128_BYTES; i < GEN_MATRIX_SIZE; i += SHA3_128_BYTES) { + sha3_blocksx4_avx2(state); + mlkem_redistribute_21_rand_avx2(state, + rand + i + 0 * GEN_MATRIX_SIZE, rand + i + 1 * GEN_MATRIX_SIZE, + rand + i + 2 * GEN_MATRIX_SIZE, rand + i + 3 * GEN_MATRIX_SIZE); + } + + /* Sample random bytes to create a polynomial. */ + p = rand; + ctr0 = mlkem_rej_uniform_n_avx2(a + 0 * MLKEM_N, MLKEM_N, p, + GEN_MATRIX_SIZE); + p += GEN_MATRIX_SIZE; + ctr1 = mlkem_rej_uniform_n_avx2(a + 1 * MLKEM_N, MLKEM_N, p, + GEN_MATRIX_SIZE); + p += GEN_MATRIX_SIZE; + ctr2 = mlkem_rej_uniform_n_avx2(a + 2 * MLKEM_N, MLKEM_N, p, + GEN_MATRIX_SIZE); + p += GEN_MATRIX_SIZE; + ctr3 = mlkem_rej_uniform_n_avx2(a + 3 * MLKEM_N, MLKEM_N, p, + GEN_MATRIX_SIZE); + /* Create more blocks if too many rejected. */ + while ((ctr0 < MLKEM_N) || (ctr1 < MLKEM_N) || (ctr2 < MLKEM_N) || + (ctr3 < MLKEM_N)) { + sha3_blocksx4_avx2(state); + mlkem_redistribute_21_rand_avx2(state, rand + 0 * GEN_MATRIX_SIZE, + rand + 1 * GEN_MATRIX_SIZE, rand + 2 * GEN_MATRIX_SIZE, + rand + 3 * GEN_MATRIX_SIZE); + + p = rand; + ctr0 += mlkem_rej_uniform_avx2(a + 0 * MLKEM_N + ctr0, + MLKEM_N - ctr0, p, XOF_BLOCK_SIZE); + p += GEN_MATRIX_SIZE; + ctr1 += mlkem_rej_uniform_avx2(a + 1 * MLKEM_N + ctr1, + MLKEM_N - ctr1, p, XOF_BLOCK_SIZE); + p += GEN_MATRIX_SIZE; + ctr2 += mlkem_rej_uniform_avx2(a + 2 * MLKEM_N + ctr2, + MLKEM_N - ctr2, p, XOF_BLOCK_SIZE); + p += GEN_MATRIX_SIZE; + ctr3 += mlkem_rej_uniform_avx2(a + 3 * MLKEM_N + ctr3, + MLKEM_N - ctr3, p, XOF_BLOCK_SIZE); + } + + a += 4 * MLKEM_N; + } + + return 0; +} +#endif /* WOLFSSL_KYBER1024 || WOLFSSL_WC_ML_KEM_1024 */ +#elif defined(WOLFSSL_ARMASM) && defined(__aarch64__) +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) +/* Deterministically generate a matrix (or transpose) of uniform integers mod q. + * + * Seed used with XOF to generate random bytes. + * + * @param [out] a Matrix of uniform integers. + * @param [in] seed Bytes to seed XOF generation. + * @param [in] transposed Whether A or A^T is generated. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. Only possible when + * WOLFSSL_SMALL_STACK is defined. + */ +static int mlkem_gen_matrix_k2_aarch64(sword16* a, byte* seed, int transposed) +{ + word64 state[3 * 25]; + word64* st = (word64*)state; + unsigned int ctr0; + unsigned int ctr1; + unsigned int ctr2; + byte* p; + + if (!transposed) { + state[0*25 + 4] = 0x1f0000 + (0 << 8) + 0; + state[1*25 + 4] = 0x1f0000 + (0 << 8) + 1; + state[2*25 + 4] = 0x1f0000 + (1 << 8) + 0; + } + else { + state[0*25 + 4] = 0x1f0000 + (0 << 8) + 0; + state[1*25 + 4] = 0x1f0000 + (1 << 8) + 0; + state[2*25 + 4] = 0x1f0000 + (0 << 8) + 1; + } + + mlkem_shake128_blocksx3_seed_neon(state, seed); + /* Sample random bytes to create a polynomial. */ + p = (byte*)st; + ctr0 = mlkem_rej_uniform_neon(a + 0 * MLKEM_N, MLKEM_N, p, XOF_BLOCK_SIZE); + p += 25 * 8; + ctr1 = mlkem_rej_uniform_neon(a + 1 * MLKEM_N, MLKEM_N, p, XOF_BLOCK_SIZE); + p += 25 * 8; + ctr2 = mlkem_rej_uniform_neon(a + 2 * MLKEM_N, MLKEM_N, p, XOF_BLOCK_SIZE); + while ((ctr0 < MLKEM_N) || (ctr1 < MLKEM_N) || (ctr2 < MLKEM_N)) { + mlkem_sha3_blocksx3_neon(st); + + p = (byte*)st; + ctr0 += mlkem_rej_uniform_neon(a + 0 * MLKEM_N + ctr0, MLKEM_N - ctr0, + p, XOF_BLOCK_SIZE); + p += 25 * 8; + ctr1 += mlkem_rej_uniform_neon(a + 1 * MLKEM_N + ctr1, MLKEM_N - ctr1, + p, XOF_BLOCK_SIZE); + p += 25 * 8; + ctr2 += mlkem_rej_uniform_neon(a + 2 * MLKEM_N + ctr2, MLKEM_N - ctr2, + p, XOF_BLOCK_SIZE); + } + + a += 3 * MLKEM_N; + + readUnalignedWords64(state, seed, 4); + /* Transposed value same as not. */ + state[4] = 0x1f0000 + (1 << 8) + 1; + XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5)); + state[20] = W64LIT(0x8000000000000000); + BlockSha3(state); + p = (byte*)state; + ctr0 = mlkem_rej_uniform_neon(a, MLKEM_N, p, XOF_BLOCK_SIZE); + while (ctr0 < MLKEM_N) { + BlockSha3(state); + ctr0 += mlkem_rej_uniform_neon(a + ctr0, MLKEM_N - ctr0, p, + XOF_BLOCK_SIZE); + } + + return 0; +} +#endif + +#if defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768) +/* Deterministically generate a matrix (or transpose) of uniform integers mod q. + * + * Seed used with XOF to generate random bytes. + * + * @param [out] a Matrix of uniform integers. + * @param [in] seed Bytes to seed XOF generation. + * @param [in] transposed Whether A or A^T is generated. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. Only possible when + * WOLFSSL_SMALL_STACK is defined. + */ +static int mlkem_gen_matrix_k3_aarch64(sword16* a, byte* seed, int transposed) +{ + int i; + int k; + word64 state[3 * 25]; + word64* st = (word64*)state; + unsigned int ctr0; + unsigned int ctr1; + unsigned int ctr2; + byte* p; + + for (k = 0; k < 3; k++) { + for (i = 0; i < 3; i++) { + if (!transposed) { + state[i*25 + 4] = 0x1f0000 + ((k << 8) + i); + } + else { + state[i*25 + 4] = 0x1f0000 + ((i << 8) + k); + } + } + + mlkem_shake128_blocksx3_seed_neon(state, seed); + /* Sample random bytes to create a polynomial. */ + p = (byte*)st; + ctr0 = mlkem_rej_uniform_neon(a + 0 * MLKEM_N, MLKEM_N, p, + XOF_BLOCK_SIZE); + p += 25 * 8; + ctr1 = mlkem_rej_uniform_neon(a + 1 * MLKEM_N, MLKEM_N, p, + XOF_BLOCK_SIZE); + p +=25 * 8; + ctr2 = mlkem_rej_uniform_neon(a + 2 * MLKEM_N, MLKEM_N, p, + XOF_BLOCK_SIZE); + /* Create more blocks if too many rejected. */ + while ((ctr0 < MLKEM_N) || (ctr1 < MLKEM_N) || (ctr2 < MLKEM_N)) { + mlkem_sha3_blocksx3_neon(st); + + p = (byte*)st; + ctr0 += mlkem_rej_uniform_neon(a + 0 * MLKEM_N + ctr0, + MLKEM_N - ctr0, p, XOF_BLOCK_SIZE); + p += 25 * 8; + ctr1 += mlkem_rej_uniform_neon(a + 1 * MLKEM_N + ctr1, + MLKEM_N - ctr1, p, XOF_BLOCK_SIZE); + p += 25 * 8; + ctr2 += mlkem_rej_uniform_neon(a + 2 * MLKEM_N + ctr2, + MLKEM_N - ctr2, p, XOF_BLOCK_SIZE); + } + + a += 3 * MLKEM_N; + } + + return 0; +} +#endif + +#if defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) +/* Deterministically generate a matrix (or transpose) of uniform integers mod q. + * + * Seed used with XOF to generate random bytes. + * + * @param [out] a Matrix of uniform integers. + * @param [in] seed Bytes to seed XOF generation. + * @param [in] transposed Whether A or A^T is generated. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. Only possible when + * WOLFSSL_SMALL_STACK is defined. + */ +static int mlkem_gen_matrix_k4_aarch64(sword16* a, byte* seed, int transposed) +{ + int i; + int k; + word64 state[3 * 25]; + word64* st = (word64*)state; + unsigned int ctr0; + unsigned int ctr1; + unsigned int ctr2; + byte* p; + + for (k = 0; k < 5; k++) { + for (i = 0; i < 3; i++) { + byte bi = ((k * 3) + i) / 4; + byte bj = ((k * 3) + i) % 4; + if (!transposed) { + state[i*25 + 4] = 0x1f0000 + (bi << 8) + bj; + } + else { + state[i*25 + 4] = 0x1f0000 + (bj << 8) + bi; + } + } + + mlkem_shake128_blocksx3_seed_neon(state, seed); + /* Sample random bytes to create a polynomial. */ + p = (byte*)st; + ctr0 = mlkem_rej_uniform_neon(a + 0 * MLKEM_N, MLKEM_N, p, + XOF_BLOCK_SIZE); + p += 25 * 8; + ctr1 = mlkem_rej_uniform_neon(a + 1 * MLKEM_N, MLKEM_N, p, + XOF_BLOCK_SIZE); + p += 25 * 8; + ctr2 = mlkem_rej_uniform_neon(a + 2 * MLKEM_N, MLKEM_N, p, + XOF_BLOCK_SIZE); + /* Create more blocks if too many rejected. */ + while ((ctr0 < MLKEM_N) || (ctr1 < MLKEM_N) || (ctr2 < MLKEM_N)) { + mlkem_sha3_blocksx3_neon(st); + + p = (byte*)st; + ctr0 += mlkem_rej_uniform_neon(a + 0 * MLKEM_N + ctr0, + MLKEM_N - ctr0, p, XOF_BLOCK_SIZE); + p += 25 * 8; + ctr1 += mlkem_rej_uniform_neon(a + 1 * MLKEM_N + ctr1, + MLKEM_N - ctr1, p, XOF_BLOCK_SIZE); + p += 25 * 8; + ctr2 += mlkem_rej_uniform_neon(a + 2 * MLKEM_N + ctr2, + MLKEM_N - ctr2, p, XOF_BLOCK_SIZE); + } + + a += 3 * MLKEM_N; + } + + readUnalignedWords64(state, seed, 4); + /* Transposed value same as not. */ + state[4] = 0x1f0000 + (3 << 8) + 3; + XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5)); + state[20] = W64LIT(0x8000000000000000); + BlockSha3(state); + p = (byte*)state; + ctr0 = mlkem_rej_uniform_neon(a, MLKEM_N, p, XOF_BLOCK_SIZE); + while (ctr0 < MLKEM_N) { + BlockSha3(state); + ctr0 += mlkem_rej_uniform_neon(a + ctr0, MLKEM_N - ctr0, p, + XOF_BLOCK_SIZE); + } + + return 0; +} +#endif +#endif /* USE_INTEL_SPEEDUP */ + +#if !(defined(WOLFSSL_ARMASM) && defined(__aarch64__)) +/* Absorb the seed data for squeezing out pseudo-random data. + * + * FIPS 203, Section 4.1: + * 1. XOF.init() = SHA128.Init(). + * 2. XOF.Absorb(ctx,str) = SHAKE128.Absorb(ctx,str). + * + * @param [in, out] shake128 SHAKE-128 object. + * @param [in] seed Data to absorb. + * @param [in] len Length of data to absorb in bytes. + * @return 0 on success always. + */ +static int mlkem_xof_absorb(wc_Shake* shake128, byte* seed, int len) +{ + int ret; + + ret = wc_InitShake128(shake128, NULL, INVALID_DEVID); + if (ret == 0) { + ret = wc_Shake128_Absorb(shake128, seed, len); + } + + return ret; +} + +/* Squeeze the state to produce pseudo-random data. + * + * FIPS 203, Section 4.1: + * 3. XOF.Absorb(ctx,l) = SHAKE128.Squeeze(ctx,8.l). + * + * @param [in, out] shake128 SHAKE-128 object. + * @param [out] out Buffer to write to. + * @param [in] blocks Number of blocks to write. + * @return 0 on success always. + */ +static int mlkem_xof_squeezeblocks(wc_Shake* shake128, byte* out, int blocks) +{ + return wc_Shake128_SqueezeBlocks(shake128, out, blocks); +} +#endif + +/* New/Initialize SHA-3 object. + * + * FIPS 203, Section 4.1: + * H(s) := SHA3-256(s) + * + * @param [in, out] hash SHA-3 object. + * @param [in] heap Dynamic memory allocator hint. + * @param [in] devId Device id. + * @return 0 on success always. + */ +int mlkem_hash_new(wc_Sha3* hash, void* heap, int devId) +{ + return wc_InitSha3_256(hash, heap, devId); +} + +/* Free SHA-3 object. + * + * FIPS 203, Section 4.1: + * H(s) := SHA3-256(s) + * + * @param [in, out] hash SHA-3 object. + */ +void mlkem_hash_free(wc_Sha3* hash) +{ + wc_Sha3_256_Free(hash); +} + +/* Hash data using SHA3-256 with SHA-3 object. + * + * FIPS 203, Section 4.1: + * H(s) := SHA3-256(s) + * + * @param [in, out] hash SHA-3 object. + * @param [io] data Data to be hashed. + * @param [in] dataLen Length of data in bytes. + * @param [out] out Hash of data. + * @return 0 on success. + */ +int mlkem_hash256(wc_Sha3* hash, const byte* data, word32 dataLen, byte* out) +{ + int ret; + + /* Process all data. */ + ret = wc_Sha3_256_Update(hash, data, dataLen); + if (ret == 0) { + /* Calculate Hash of data passed in an re-initialize. */ + ret = wc_Sha3_256_Final(hash, out); + } + + return ret; +} + +/* Hash one or two blocks of data using SHA3-512 with SHA-3 object. + * + * FIPS 203, Section 4.1: + * G(s) := SHA3-512(s) + * + * @param [in, out] hash SHA-3 object. + * @param [io] data1 First block of data to be hashed. + * @param [in] data1Len Length of first block of data in bytes. + * @param [io] data2 Second block of data to be hashed. May be NULL. + * @param [in] data2Len Length of second block of data in bytes. + * @param [out] out Hash of all data. + * @return 0 on success. + */ +int mlkem_hash512(wc_Sha3* hash, const byte* data1, word32 data1Len, + const byte* data2, word32 data2Len, byte* out) +{ + int ret; + + /* Process first block of data. */ + ret = wc_Sha3_512_Update(hash, data1, data1Len); + /* Check if there is a second block of data. */ + if ((ret == 0) && (data2Len > 0)) { + /* Process second block of data. */ + ret = wc_Sha3_512_Update(hash, data2, data2Len); + } + if (ret == 0) { + /* Calculate Hash of data passed in an re-initialize. */ + ret = wc_Sha3_512_Final(hash, out); + } + + return ret; +} + +/* Initialize SHAKE-256 object. + * + * @param [in, out] shake256 SHAKE-256 object. + */ +void mlkem_prf_init(wc_Shake* prf) +{ + XMEMSET(prf->s, 0, sizeof(prf->s)); +} + +/* New/Initialize SHAKE-256 object. + * + * FIPS 203, Section 4.1: + * PRF_eta(s,b) := SHA256(s||b,8.64.eta) + * + * @param [in, out] shake256 SHAKE-256 object. + * @param [in] heap Dynamic memory allocator hint. + * @param [in] devId Device id. + * @return 0 on success always. + */ +int mlkem_prf_new(wc_Shake* prf, void* heap, int devId) +{ + return wc_InitShake256(prf, heap, devId); +} + +/* Free SHAKE-256 object. + * + * FIPS 203, Section 4.1: + * PRF_eta(s,b) := SHA256(s||b,8.64.eta) + * + * @param [in, out] shake256 SHAKE-256 object. + */ +void mlkem_prf_free(wc_Shake* prf) +{ + wc_Shake256_Free(prf); +} + +#if !(defined(WOLFSSL_ARMASM) && defined(__aarch64__)) +/* Create pseudo-random data from the key using SHAKE-256. + * + * FIPS 203, Section 4.1: + * PRF_eta(s,b) := SHA256(s||b,8.64.eta) + * + * @param [in, out] shake256 SHAKE-256 object. + * @param [out] out Buffer to write to. + * @param [in] outLen Number of bytes to write. + * @param [in] key Data to derive from. Must be: + * WC_ML_KEM_SYM_SZ + 1 bytes in length. + * @return 0 on success always. + */ +static int mlkem_prf(wc_Shake* shake256, byte* out, unsigned int outLen, + const byte* key) +{ +#ifdef USE_INTEL_SPEEDUP + word64 state[25]; + + (void)shake256; + + /* Put first WC_ML_KEM_SYM_SZ bytes og key into blank state. */ + readUnalignedWords64(state, key, WC_ML_KEM_SYM_SZ / sizeof(word64)); + /* Last byte in with end of content marker. */ + state[WC_ML_KEM_SYM_SZ / 8] = 0x1f00 | key[WC_ML_KEM_SYM_SZ]; + /* Set rest of state to 0. */ + XMEMSET(state + WC_ML_KEM_SYM_SZ / 8 + 1, 0, + (25 - WC_ML_KEM_SYM_SZ / 8 - 1) * sizeof(word64)); + /* ... except for rate marker. */ + state[WC_SHA3_256_COUNT - 1] = W64LIT(0x8000000000000000); + + /* Generate as much output as is required. */ + while (outLen > 0) { + /* Get as much of an output block as is needed. */ + unsigned int len = min(outLen, WC_SHA3_256_BLOCK_SIZE); + + /* Perform a block operation on the state for next block of output. */ + if (IS_INTEL_BMI2(cpuid_flags)) { + sha3_block_bmi2(state); + } + else if (IS_INTEL_AVX2(cpuid_flags) && + (SAVE_VECTOR_REGISTERS2() == 0)) { + sha3_block_avx2(state); + RESTORE_VECTOR_REGISTERS(); + } + else { + BlockSha3(state); + } + + /* Copy the state as output. */ + XMEMCPY(out, state, len); + /* Update output pointer and length. */ + out += len; + outLen -= len; + } + + return 0; +#else + int ret; + + /* Process all data. */ + ret = wc_Shake256_Update(shake256, key, WC_ML_KEM_SYM_SZ + 1); + if (ret == 0) { + /* Calculate Hash of data passed in an re-initialize. */ + ret = wc_Shake256_Final(shake256, out, outLen); + } + + return ret; +#endif +} +#endif + +#ifdef WOLFSSL_MLKEM_KYBER +#ifdef USE_INTEL_SPEEDUP +/* Create pseudo-random key from the seed using SHAKE-256. + * + * @param [in] seed Data to derive from. + * @param [in] seedLen Length of data to derive from in bytes. + * @param [out] out Buffer to write to. + * @param [in] outLen Number of bytes to derive. + * @return 0 on success always. + */ +int mlkem_kdf(byte* seed, int seedLen, byte* out, int outLen) +{ + word64 state[25]; + word32 len64 = seedLen / 8; + + readUnalignedWords64(state, seed, len64); + state[len64] = 0x1f; + XMEMSET(state + len64 + 1, 0, (25 - len64 - 1) * sizeof(word64)); + state[WC_SHA3_256_COUNT - 1] = W64LIT(0x8000000000000000); + + if (IS_INTEL_BMI2(cpuid_flags)) { + sha3_block_bmi2(state); + } + else if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + sha3_block_avx2(state); + RESTORE_VECTOR_REGISTERS(); + } + else { + BlockSha3(state); + } + XMEMCPY(out, state, outLen); + + return 0; +} +#endif + +#if defined(WOLFSSL_ARMASM) && defined(__aarch64__) +/* Create pseudo-random key from the seed using SHAKE-256. + * + * @param [in] seed Data to derive from. + * @param [in] seedLen Length of data to derive from in bytes. + * @param [out] out Buffer to write to. + * @param [in] outLen Number of bytes to derive. + * @return 0 on success always. + */ +int mlkem_kdf(byte* seed, int seedLen, byte* out, int outLen) +{ + word64 state[25]; + word32 len64 = seedLen / 8; + + readUnalignedWords64(state, seed, len64); + state[len64] = 0x1f; + XMEMSET(state + len64 + 1, 0, (25 - len64 - 1) * sizeof(word64)); + state[WC_SHA3_256_COUNT - 1] = W64LIT(0x8000000000000000); + + BlockSha3(state); + XMEMCPY(out, state, outLen); + + return 0; +} +#endif +#endif + +#ifndef WOLFSSL_NO_ML_KEM +/* Derive the secret from z and cipher text. + * + * @param [in, out] shake256 SHAKE-256 object. + * @param [in] z Implicit rejection value. + * @param [in] ct Cipher text. + * @param [in] ctSz Length of cipher text in bytes. + * @param [out] ss Shared secret. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation failed. + * @return Other negative when a hash error occurred. + */ +int mlkem_derive_secret(wc_Shake* shake256, const byte* z, const byte* ct, + word32 ctSz, byte* ss) +{ + int ret; + +#ifdef USE_INTEL_SPEEDUP + XMEMCPY(shake256->t, z, WC_ML_KEM_SYM_SZ); + XMEMCPY(shake256->t, ct, WC_SHA3_256_COUNT * 8 - WC_ML_KEM_SYM_SZ); + shake256->i = WC_ML_KEM_SYM_SZ; + ct += WC_SHA3_256_COUNT * 8 - WC_ML_KEM_SYM_SZ; + ctSz -= WC_SHA3_256_COUNT * 8 - WC_ML_KEM_SYM_SZ; + ret = wc_Shake256_Update(shake256, ct, ctSz); + if (ret == 0) { + ret = wc_Shake256_Final(shake256, ss, WC_ML_KEM_SS_SZ); + } +#else + ret = wc_Shake256_Update(shake256, z, WC_ML_KEM_SYM_SZ); + if (ret == 0) { + ret = wc_Shake256_Update(shake256, ct, ctSz); + } + if (ret == 0) { + ret = wc_Shake256_Final(shake256, ss, WC_ML_KEM_SS_SZ); + } +#endif + + return ret; +} +#endif + +#if !defined(WOLFSSL_ARMASM) +/* Rejection sampling on uniform random bytes to generate uniform random + * integers mod q. + * + * FIPS 203, Algorithm 7: SampleNTT(B) + * Takes a 32-byte seed and two indices as input and outputs a pseudorandom + * element of T_q. + * ... + * 4: while j < 256 do + * 5: (ctx,C) <- XOF.Squeeze(ctx,3) + * 6: d1 <- C[0] + 256.(C[1] mod 16) + * 7: d2 <- lower(C[1] / 16) + 16.C[2] + * 8: if d1 < q then + * 9: a_hat[j] <- d1 + * 10: j <- j + 1 + * 11: end if + * 12: if d2 < q and j < 256 then + * 13: a_hat[j] <- d2 + * 14: j <- j + 1 + * 15: end if + * 16: end while + * ... + * + * @param [out] p Uniform random integers mod q. + * @param [in] len Maximum number of integers. + * @param [in] r Uniform random bytes buffer. + * @param [in] rLen Length of random data in buffer. + * @return Number of integers sampled. + */ +static unsigned int mlkem_rej_uniform_c(sword16* p, unsigned int len, + const byte* r, unsigned int rLen) +{ + unsigned int i; + unsigned int j; + +#if defined(WOLFSSL_MLKEM_SMALL) || !defined(WC_64BIT_CPU) || \ + defined(BIG_ENDIAN_ORDER) + /* Keep sampling until maximum number of integers reached or buffer used up. + * Step 4. */ + for (i = 0, j = 0; (i < len) && (j <= rLen - 3); j += 3) { + /* Step 5 - caller generates and now using 3 bytes of it. */ + /* Use 24 bits (3 bytes) as two 12 bits integers. */ + /* Step 6. */ + sword16 v0 = ((r[0] >> 0) | ((word16)r[1] << 8)) & 0xFFF; + /* Step 7. */ + sword16 v1 = ((r[1] >> 4) | ((word16)r[2] << 4)) & 0xFFF; + + /* Reject first 12-bit integer if greater than or equal to q. + * Step 8 */ + if (v0 < MLKEM_Q) { + /* Steps 9-10 */ + p[i++] = v0; + } + /* Check second if we don't have enough integers yet. + * Reject second 12-bit integer if greater than or equal to q. + * Step 12 */ + if ((i < len) && (v1 < MLKEM_Q)) { + /* Steps 13-14 */ + p[i++] = v1; + } + + /* Move over used bytes. */ + r += 3; + } +#else + /* Unroll loops. Minimal work per loop. */ + unsigned int minJ; + + /* Calculate minimum number of 6 byte data blocks to get all required + * numbers assuming no rejections. */ + minJ = len / 4 * 6; + if (minJ > rLen) + minJ = rLen; + i = 0; + for (j = 0; j < minJ; j += 6) { + /* Use 48 bits (6 bytes) as four 12-bit integers. */ + word64 r_word = readUnalignedWord64(r); + sword16 v0 = r_word & 0xfff; + sword16 v1 = (r_word >> 12) & 0xfff; + sword16 v2 = (r_word >> 24) & 0xfff; + sword16 v3 = (r_word >> 36) & 0xfff; + + p[i] = v0; + i += (v0 < MLKEM_Q); + p[i] = v1; + i += (v1 < MLKEM_Q); + p[i] = v2; + i += (v2 < MLKEM_Q); + p[i] = v3; + i += (v3 < MLKEM_Q); + + /* Move over used bytes. */ + r += 6; + } + /* Check whether we have all the numbers we need. */ + if (j < rLen) { + /* Keep trying until we have less than 4 numbers to find or data is used + * up. */ + for (; (i + 4 < len) && (j < rLen); j += 6) { + /* Use 48 bits (6 bytes) as four 12-bit integers. */ + word64 r_word = readUnalignedWord64(r); + sword16 v0 = r_word & 0xfff; + sword16 v1 = (r_word >> 12) & 0xfff; + sword16 v2 = (r_word >> 24) & 0xfff; + sword16 v3 = (r_word >> 36) & 0xfff; + + p[i] = v0; + i += (v0 < MLKEM_Q); + p[i] = v1; + i += (v1 < MLKEM_Q); + p[i] = v2; + i += (v2 < MLKEM_Q); + p[i] = v3; + i += (v3 < MLKEM_Q); + + /* Move over used bytes. */ + r += 6; + } + /* Keep trying until we have all the numbers we need or the data is used + * up. */ + for (; (i < len) && (j < rLen); j += 6) { + /* Use 48 bits (6 bytes) as four 12-bit integers. */ + word64 r_word = readUnalignedWord64(r); + sword16 v0 = r_word & 0xfff; + sword16 v1 = (r_word >> 12) & 0xfff; + sword16 v2 = (r_word >> 24) & 0xfff; + sword16 v3 = (r_word >> 36) & 0xfff; + + /* Reject first 12-bit integer if greater than or equal to q. */ + if (v0 < MLKEM_Q) { + p[i++] = v0; + } + /* Check second if we don't have enough integers yet. + * Reject second 12-bit integer if greater than or equal to q. */ + if ((i < len) && (v1 < MLKEM_Q)) { + p[i++] = v1; + } + /* Check second if we don't have enough integers yet. + * Reject third 12-bit integer if greater than or equal to q. */ + if ((i < len) && (v2 < MLKEM_Q)) { + p[i++] = v2; + } + /* Check second if we don't have enough integers yet. + * Reject fourth 12-bit integer if greater than or equal to q. */ + if ((i < len) && (v3 < MLKEM_Q)) { + p[i++] = v3; + } + + /* Move over used bytes. */ + r += 6; + } + } +#endif + + return i; +} +#endif + +#if !defined(WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM) || \ + !defined(WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM) + +#if !(defined(WOLFSSL_ARMASM) && defined(__aarch64__)) +/* Deterministically generate a matrix (or transpose) of uniform integers mod q. + * + * Seed used with XOF to generate random bytes. + * + * FIPS 203, Algorithm 13: K-PKE.KeyGen(d) + * ... + * 3: for (i <- 0; i < k; i++) + * 4: for (j <- 0; j < k; j++) + * 5: A_hat[i,j] <- SampleNTT(rho||j||i) + * 6: end for + * 7: end for + * ... + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE,m,r) + * ... + * 4: for (i <- 0; i < k; i++) + * 5: for (j <- 0; j < k; j++) + * 6: A_hat[i,j] <- SampleNTT(rho||j||i) (Transposed is rho||i||j) + * 7: end for + * 8: end for + * ... + * FIPS 203, Algorithm 7: SampleNTT(B) + * Takes a 32-byte seed and two indices as input and outputs a pseudorandom + * element of T_q. + * 1: ctx <- XOF.init() + * 2: ctx <- XOF.Absorb(ctx,B) + * 3: j <- 0 + * 4: while j < 256 do + * 5: (ctx,C) <- XOF.Squeeze(ctx,3) + * ... + * 16: end while + * 17: return a_hat + * + * @param [in] prf XOF object. + * @param [out] a Matrix of uniform integers. + * @param [in] k Number of dimensions. k x k polynomials. + * @param [in] seed Bytes to seed XOF generation. + * @param [in] transposed Whether A or A^T is generated. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. Only possible when + * WOLFSSL_SMALL_STACK is defined. + */ +static int mlkem_gen_matrix_c(MLKEM_PRF_T* prf, sword16* a, int k, byte* seed, + int transposed) +{ +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + byte* rand; +#else + byte rand[GEN_MATRIX_SIZE + 2]; +#endif + byte extSeed[WC_ML_KEM_SYM_SZ + 2]; + int ret = 0; + int i; + + /* Copy seed into buffer than has space for i and j to be appended. */ + XMEMCPY(extSeed, seed, WC_ML_KEM_SYM_SZ); + +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + /* Allocate large amount of memory to hold random bytes to be samples. */ + rand = (byte*)XMALLOC(GEN_MATRIX_SIZE + 2, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (rand == NULL) { + ret = MEMORY_E; + } +#endif + +#if !defined(WOLFSSL_MLKEM_SMALL) && defined(WC_64BIT_CPU) + /* Loading 64 bits, only using 48 bits. Loading 2 bytes more than used. */ + if (ret == 0) { + rand[GEN_MATRIX_SIZE+0] = 0xff; + rand[GEN_MATRIX_SIZE+1] = 0xff; + } +#endif + + /* Generate each vector of polynomials. + * Alg 13, Step 3. Alg 14, Step 4. */ + for (i = 0; (ret == 0) && (i < k); i++, a += k * MLKEM_N) { + int j; + /* Generate each polynomial in vector from seed with indices. + * Alg 13, Step 4. Alg 14, Step 5. */ + for (j = 0; (ret == 0) && (j < k); j++) { + if (transposed) { + /* Alg 14, Step 6: .. rho||i||j ... */ + extSeed[WC_ML_KEM_SYM_SZ + 0] = i; + extSeed[WC_ML_KEM_SYM_SZ + 1] = j; + } + else { + /* Alg 13, Step 5: .. rho||j||i ... */ + extSeed[WC_ML_KEM_SYM_SZ + 0] = j; + extSeed[WC_ML_KEM_SYM_SZ + 1] = i; + } + /* Absorb the index specific seed. + * Alg 7, Step 1-2 */ + ret = mlkem_xof_absorb(prf, extSeed, sizeof(extSeed)); + if (ret == 0) { + /* Create data based on the seed. + * Alg 7, Step 5. Generating enough to, on average, be able to + * get enough valid values. */ + ret = mlkem_xof_squeezeblocks(prf, rand, GEN_MATRIX_NBLOCKS); + } + if (ret == 0) { + unsigned int ctr; + + /* Sample random bytes to create a polynomial. + * Alg 7, Step 3 - implicitly counter is 0. + * Alg 7, Step 4-16. */ + ctr = mlkem_rej_uniform_c(a + j * MLKEM_N, MLKEM_N, rand, + GEN_MATRIX_SIZE); + /* Create more blocks if too many rejected. + * Alg 7, Step 4. */ + while (ctr < MLKEM_N) { + /* Alg 7, Step 5. */ + mlkem_xof_squeezeblocks(prf, rand, 1); + /* Alg 7, Step 4-16. */ + ctr += mlkem_rej_uniform_c(a + j * MLKEM_N + ctr, + MLKEM_N - ctr, rand, XOF_BLOCK_SIZE); + } + } + } + } + +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + /* Dispose of temporary buffer. */ + XFREE(rand, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} +#endif + +/* Deterministically generate a matrix (or transpose) of uniform integers mod q. + * + * Seed used with XOF to generate random bytes. + * + * FIPS 203, Algorithm 13: K-PKE.KeyGen(d), Steps 3-7 + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE,m,r), Steps 4-8 + * + * @param [in] prf XOF object. + * @param [out] a Matrix of uniform integers. + * @param [in] k Number of dimensions. k x k polynomials. + * @param [in] seed Bytes to seed XOF generation. + * @param [in] transposed Whether A or A^T is generated. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. Only possible when + * WOLFSSL_SMALL_STACK is defined. + */ +int mlkem_gen_matrix(MLKEM_PRF_T* prf, sword16* a, int k, byte* seed, + int transposed) +{ + int ret; + +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) + if (k == WC_ML_KEM_512_K) { +#if defined(WOLFSSL_ARMASM) && defined(__aarch64__) + ret = mlkem_gen_matrix_k2_aarch64(a, seed, transposed); +#else + #ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + ret = mlkem_gen_matrix_k2_avx2(a, seed, transposed); + RESTORE_VECTOR_REGISTERS(); + } + else + #endif + { + ret = mlkem_gen_matrix_c(prf, a, WC_ML_KEM_512_K, seed, transposed); + } +#endif + } + else +#endif +#if defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768) + if (k == WC_ML_KEM_768_K) { +#if defined(WOLFSSL_ARMASM) && defined(__aarch64__) + ret = mlkem_gen_matrix_k3_aarch64(a, seed, transposed); +#else + #ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + ret = mlkem_gen_matrix_k3_avx2(a, seed, transposed); + RESTORE_VECTOR_REGISTERS(); + } + else + #endif + { + ret = mlkem_gen_matrix_c(prf, a, WC_ML_KEM_768_K, seed, transposed); + } +#endif + } + else +#endif +#if defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) + if (k == WC_ML_KEM_1024_K) { +#if defined(WOLFSSL_ARMASM) && defined(__aarch64__) + ret = mlkem_gen_matrix_k4_aarch64(a, seed, transposed); +#else + #ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + ret = mlkem_gen_matrix_k4_avx2(a, seed, transposed); + RESTORE_VECTOR_REGISTERS(); + } + else + #endif + { + ret = mlkem_gen_matrix_c(prf, a, WC_ML_KEM_1024_K, seed, + transposed); + } +#endif + } + else +#endif + { + ret = BAD_STATE_E; + } + + (void)prf; + + return ret; +} + +#endif + +#if defined(WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM) || \ + defined(WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM) + +/* Deterministically generate a matrix (or transpose) of uniform integers mod q. + * + * Seed used with XOF to generate random bytes. + * + * FIPS 203, Algorithm 13: K-PKE.KeyGen(d) + * ... + * 4: for (j <- 0; j < k; j++) + * 5: A_hat[i,j] <- SampleNTT(rho||j||i) + * 6: end for + * ... + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE,m,r) + * ... + * 5: for (j <- 0; j < k; j++) + * 6: A_hat[i,j] <- SampleNTT(rho||j||i) (Transposed is rho||i||j) + * 7: end for + * ... + * + * @param [in] prf XOF object. + * @param [out] a Matrix of uniform integers. + * @param [in] k Number of dimensions. k x k polynomials. + * @param [in] seed Bytes to seed XOF generation. + * @param [in] i Index of vector to generate. + * @param [in] transposed Whether A or A^T is generated. + * @return 0 on success. + * @return MEMORY_E when dynamic memory allocation fails. Only possible when + * WOLFSSL_SMALL_STACK is defined. + */ +static int mlkem_gen_matrix_i(MLKEM_PRF_T* prf, sword16* a, int k, byte* seed, + int i, int transposed) +{ +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + byte* rand; +#else + byte rand[GEN_MATRIX_SIZE + 2]; +#endif + byte extSeed[WC_ML_KEM_SYM_SZ + 2]; + int ret = 0; + int j; + + XMEMCPY(extSeed, seed, WC_ML_KEM_SYM_SZ); + +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + /* Allocate large amount of memory to hold random bytes to be samples. */ + rand = (byte*)XMALLOC(GEN_MATRIX_SIZE + 2, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (rand == NULL) { + ret = MEMORY_E; + } +#endif + +#if !defined(WOLFSSL_MLKEM_SMALL) && defined(WC_64BIT_CPU) + /* Loading 64 bits, only using 48 bits. Loading 2 bytes more than used. */ + if (ret == 0) { + rand[GEN_MATRIX_SIZE+0] = 0xff; + rand[GEN_MATRIX_SIZE+1] = 0xff; + } +#endif + + /* Generate each polynomial in vector from seed with indices. + * Alg 13, Step 4. Alg 14, Step 5. */ + for (j = 0; (ret == 0) && (j < k); j++) { + if (transposed) { + /* Alg 14, Step 6: .. rho||i||j ... */ + extSeed[WC_ML_KEM_SYM_SZ + 0] = i; + extSeed[WC_ML_KEM_SYM_SZ + 1] = j; + } + else { + /* Alg 13, Step 5: .. rho||j||i ... */ + extSeed[WC_ML_KEM_SYM_SZ + 0] = j; + extSeed[WC_ML_KEM_SYM_SZ + 1] = i; + } + /* Absorb the index specific seed. + * Alg 7, Step 1-2 */ + ret = mlkem_xof_absorb(prf, extSeed, sizeof(extSeed)); + if (ret == 0) { + /* Create out based on the seed. + * Alg 7, Step 5. Generating enough to, on average, be able to get + * enough valid values. */ + ret = mlkem_xof_squeezeblocks(prf, rand, GEN_MATRIX_NBLOCKS); + } + if (ret == 0) { + unsigned int ctr; + + /* Sample random bytes to create a polynomial. + * Alg 7, Step 3 - implicitly counter is 0. + * Alg 7, Step 4-16. */ + ctr = mlkem_rej_uniform_c(a + j * MLKEM_N, MLKEM_N, rand, + GEN_MATRIX_SIZE); + /* Create more blocks if too many rejected. + * Alg 7, Step 4. */ + while (ctr < MLKEM_N) { + /* Alg 7, Step 5. */ + mlkem_xof_squeezeblocks(prf, rand, 1); + /* Alg 7, Step 4-16. */ + ctr += mlkem_rej_uniform_c(a + j * MLKEM_N + ctr, + MLKEM_N - ctr, rand, XOF_BLOCK_SIZE); + } + } + } + +#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) + /* Dispose of temporary buffer. */ + XFREE(rand, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + +#endif + + +/******************************************************************************/ + +/* Subtract one 2 bit value from another out of a larger number. + * + * FIPS 203, Algorithm 8: SmaplePolyCBD_eta(B) + * Takes a seed as input and outputs a pseudorandom sample from the distribution + * D_eta(R_q). + * + * @param [in] d Value containing sequential 2 bit values. + * @param [in] i Start index of the two values in 2 bits each. + * @return Difference of the two values with range 0..2. + */ +#define ETA2_SUB(d, i) \ + (((sword16)(((d) >> ((i) * 4 + 0)) & 0x3)) - \ + ((sword16)(((d) >> ((i) * 4 + 2)) & 0x3))) + +/* Compute polynomial with coefficients distributed according to a centered + * binomial distribution with parameter eta2 from uniform random bytes. + * + * FIPS 203, Algorithm 8: SmaplePolyCBD_eta(B) + * Takes a seed as input and outputs a pseudorandom sample from the distribution + * D_eta(R_q). + * + * @param [out] p Polynomial computed. + * @param [in] r Random bytes. + */ +static void mlkem_cbd_eta2(sword16* p, const byte* r) +{ + unsigned int i; + +#ifndef WORD64_AVAILABLE + /* Calculate eight integer coefficients at a time. */ + for (i = 0; i < MLKEM_N; i += 8) { + #ifdef WOLFSSL_MLKEM_SMALL + unsigned int j; + #endif + /* Take the next 4 bytes, little endian, as a 32 bit value. */ + #ifdef BIG_ENDIAN_ORDER + word32 t = ByteReverseWord32(*(word32*)r); + #else + word32 t = *(word32*)r; + #endif + word32 d; + /* Add second bits to first. */ + d = (t >> 0) & 0x55555555; + d += (t >> 1) & 0x55555555; + /* Values 0, 1 or 2 in consecutive 2 bits. + * 0 - 1/4, 1 - 2/4, 2 - 1/4. */ + + #ifdef WOLFSSL_MLKEM_SMALL + for (j = 0; j < 8; j++) { + p[i + j] = ETA2_SUB(d, j); + } + #else + p[i + 0] = ETA2_SUB(d, 0); + p[i + 1] = ETA2_SUB(d, 1); + p[i + 2] = ETA2_SUB(d, 2); + p[i + 3] = ETA2_SUB(d, 3); + p[i + 4] = ETA2_SUB(d, 4); + p[i + 5] = ETA2_SUB(d, 5); + p[i + 6] = ETA2_SUB(d, 6); + p[i + 7] = ETA2_SUB(d, 7); + #endif + /* -2 - 1/16, -1 - 4/16, 0 - 6/16, 1 - 4/16, 2 - 1/16 */ + + /* Move over used bytes. */ + r += 4; + } +#else + /* Calculate sixteen integer coefficients at a time. */ + for (i = 0; i < MLKEM_N; i += 16) { + #ifdef WOLFSSL_MLKEM_SMALL + unsigned int j; + #endif + /* Take the next 8 bytes, little endian, as a 64 bit value. */ + #ifdef BIG_ENDIAN_ORDER + word64 t = ByteReverseWord64(readUnalignedWord64(r)); + #else + word64 t = readUnalignedWord64(r); + #endif + word64 d; + /* Add second bits to first. */ + d = (t >> 0) & 0x5555555555555555L; + d += (t >> 1) & 0x5555555555555555L; + /* Values 0, 1 or 2 in consecutive 2 bits. + * 0 - 1/4, 1 - 2/4, 2 - 1/4. */ + + #ifdef WOLFSSL_MLKEM_SMALL + for (j = 0; j < 16; j++) { + p[i + j] = ETA2_SUB(d, j); + } + #else + p[i + 0] = ETA2_SUB(d, 0); + p[i + 1] = ETA2_SUB(d, 1); + p[i + 2] = ETA2_SUB(d, 2); + p[i + 3] = ETA2_SUB(d, 3); + p[i + 4] = ETA2_SUB(d, 4); + p[i + 5] = ETA2_SUB(d, 5); + p[i + 6] = ETA2_SUB(d, 6); + p[i + 7] = ETA2_SUB(d, 7); + p[i + 8] = ETA2_SUB(d, 8); + p[i + 9] = ETA2_SUB(d, 9); + p[i + 10] = ETA2_SUB(d, 10); + p[i + 11] = ETA2_SUB(d, 11); + p[i + 12] = ETA2_SUB(d, 12); + p[i + 13] = ETA2_SUB(d, 13); + p[i + 14] = ETA2_SUB(d, 14); + p[i + 15] = ETA2_SUB(d, 15); + #endif + /* -2 - 1/16, -1 - 4/16, 0 - 6/16, 1 - 4/16, 2 - 1/16 */ + + /* Move over used bytes. */ + r += 8; + } +#endif +} + +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) +/* Subtract one 3 bit value from another out of a larger number. + * + * FIPS 203, Algorithm 8: SmaplePolyCBD_eta(B) + * Takes a seed as input and outputs a pseudorandom sample from the distribution + * D_eta(R_q). + * + * @param [in] d Value containing sequential 3 bit values. + * @param [in] i Start index of the two values in 3 bits each. + * @return Difference of the two values with range 0..3. + */ +#define ETA3_SUB(d, i) \ + (((sword16)(((d) >> ((i) * 6 + 0)) & 0x7)) - \ + ((sword16)(((d) >> ((i) * 6 + 3)) & 0x7))) + +/* Compute polynomial with coefficients distributed according to a centered + * binomial distribution with parameter eta3 from uniform random bytes. + * + * FIPS 203, Algorithm 8: SmaplePolyCBD_eta(B) + * Takes a seed as input and outputs a pseudorandom sample from the distribution + * D_eta(R_q). + * + * @param [out] p Polynomial computed. + * @param [in] r Random bytes. + */ +static void mlkem_cbd_eta3(sword16* p, const byte* r) +{ + unsigned int i; + +#if defined(WOLFSSL_SMALL_STACK) || defined(WOLFSSL_MLKEM_NO_LARGE_CODE) || \ + defined(BIG_ENDIAN_ORDER) +#ifndef WORD64_AVAILABLE + /* Calculate four integer coefficients at a time. */ + for (i = 0; i < MLKEM_N; i += 4) { + #ifdef WOLFSSL_MLKEM_SMALL + unsigned int j; + #endif + /* Take the next 3 bytes, little endian, as a 24 bit value. */ + word32 t = (((word32)(r[0])) << 0) | + (((word32)(r[1])) << 8) | + (((word32)(r[2])) << 16); + word32 d; + /* Add second and third bits to first. */ + d = (t >> 0) & 0x00249249; + d += (t >> 1) & 0x00249249; + d += (t >> 2) & 0x00249249; + /* Values 0, 1, 2 or 3 in consecutive 3 bits. + * 0 - 1/8, 1 - 3/8, 2 - 3/8, 3 - 1/8. */ + + #ifdef WOLFSSL_MLKEM_SMALL + for (j = 0; j < 4; j++) { + p[i + j] = ETA3_SUB(d, j); + } + #else + p[i + 0] = ETA3_SUB(d, 0); + p[i + 1] = ETA3_SUB(d, 1); + p[i + 2] = ETA3_SUB(d, 2); + p[i + 3] = ETA3_SUB(d, 3); + #endif + /* -3-1/64, -2-6/64, -1-15/64, 0-20/64, 1-15/64, 2-6/64, 3-1/64 */ + + /* Move over used bytes. */ + r += 3; + } +#else + /* Calculate eight integer coefficients at a time. */ + for (i = 0; i < MLKEM_N; i += 8) { + #ifdef WOLFSSL_MLKEM_SMALL + unsigned int j; + #endif + /* Take the next 6 bytes, little endian, as a 48 bit value. */ + word64 t = (((word64)(r[0])) << 0) | + (((word64)(r[1])) << 8) | + (((word64)(r[2])) << 16) | + (((word64)(r[3])) << 24) | + (((word64)(r[4])) << 32) | + (((word64)(r[5])) << 40); + word64 d; + /* Add second and third bits to first. */ + d = (t >> 0) & 0x0000249249249249L; + d += (t >> 1) & 0x0000249249249249L; + d += (t >> 2) & 0x0000249249249249L; + /* Values 0, 1, 2 or 3 in consecutive 3 bits. + * 0 - 1/8, 1 - 3/8, 2 - 3/8, 3 - 1/8. */ + + #ifdef WOLFSSL_MLKEM_SMALL + for (j = 0; j < 8; j++) { + p[i + j] = ETA3_SUB(d, j); + } + #else + p[i + 0] = ETA3_SUB(d, 0); + p[i + 1] = ETA3_SUB(d, 1); + p[i + 2] = ETA3_SUB(d, 2); + p[i + 3] = ETA3_SUB(d, 3); + p[i + 4] = ETA3_SUB(d, 4); + p[i + 5] = ETA3_SUB(d, 5); + p[i + 6] = ETA3_SUB(d, 6); + p[i + 7] = ETA3_SUB(d, 7); + #endif + /* -3-1/64, -2-6/64, -1-15/64, 0-20/64, 1-15/64, 2-6/64, 3-1/64 */ + + /* Move over used bytes. */ + r += 6; + } +#endif /* WORD64_AVAILABLE */ +#else + /* Calculate eight integer coefficients at a time. */ + for (i = 0; i < MLKEM_N; i += 16) { + const word32* r32 = (const word32*)r; + /* Take the next 12 bytes, little endian, as 24 bit values. */ + word32 t0 = r32[0] & 0xffffff; + word32 t1 = ((r32[0] >> 24) | (r32[1] << 8)) & 0xffffff; + word32 t2 = ((r32[1] >> 16) | (r32[2] << 16)) & 0xffffff; + word32 t3 = r32[2] >> 8 ; + word32 d0; + word32 d1; + word32 d2; + word32 d3; + + /* Add second and third bits to first. */ + d0 = (t0 >> 0) & 0x00249249; + d0 += (t0 >> 1) & 0x00249249; + d0 += (t0 >> 2) & 0x00249249; + d1 = (t1 >> 0) & 0x00249249; + d1 += (t1 >> 1) & 0x00249249; + d1 += (t1 >> 2) & 0x00249249; + d2 = (t2 >> 0) & 0x00249249; + d2 += (t2 >> 1) & 0x00249249; + d2 += (t2 >> 2) & 0x00249249; + d3 = (t3 >> 0) & 0x00249249; + d3 += (t3 >> 1) & 0x00249249; + d3 += (t3 >> 2) & 0x00249249; + /* Values 0, 1, 2 or 3 in consecutive 3 bits. + * 0 - 1/8, 1 - 3/8, 2 - 3/8, 3 - 1/8. */ + + p[i + 0] = ETA3_SUB(d0, 0); + p[i + 1] = ETA3_SUB(d0, 1); + p[i + 2] = ETA3_SUB(d0, 2); + p[i + 3] = ETA3_SUB(d0, 3); + p[i + 4] = ETA3_SUB(d1, 0); + p[i + 5] = ETA3_SUB(d1, 1); + p[i + 6] = ETA3_SUB(d1, 2); + p[i + 7] = ETA3_SUB(d1, 3); + p[i + 8] = ETA3_SUB(d2, 0); + p[i + 9] = ETA3_SUB(d2, 1); + p[i + 10] = ETA3_SUB(d2, 2); + p[i + 11] = ETA3_SUB(d2, 3); + p[i + 12] = ETA3_SUB(d3, 0); + p[i + 13] = ETA3_SUB(d3, 1); + p[i + 14] = ETA3_SUB(d3, 2); + p[i + 15] = ETA3_SUB(d3, 3); + /* -3-1/64, -2-6/64, -1-15/64, 0-20/64, 1-15/64, 2-6/64, 3-1/64 */ + + /* Move over used bytes. */ + r += 12; + } +#endif /* WOLFSSL_SMALL_STACK || WOLFSSL_MLKEM_NO_LARGE_CODE || + * BIG_ENDIAN_ORDER */ +} +#endif + +#if !(defined(__aarch64__) && defined(WOLFSSL_ARMASM)) + +/* Get noise/error by calculating random bytes and sampling to a binomial + * distribution. + * + * FIPS 203, Algorithm 13: K-PKE.KeyGen(d) + * ... + * 9: s[i] <- SamplePolyCBD_eta_1(PRF_eta_1(rho, N)) + * ... + * 13: e[i] <- SamplePolyCBD_eta_1(PRF_eta_1(rho, N)) + * ... + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE,m,r) + * ... + * 10: y[i] <- SamplePolyCBD_eta_1(PRF_eta_1(r, N)) + * ... + * + * @param [in, out] prf Pseudo-random function object. + * @param [out] p Polynomial. + * @param [in] seed Seed to use when calculating random. + * @param [in] eta1 Size of noise/error integers. + * @return 0 on success. + */ +static int mlkem_get_noise_eta1_c(MLKEM_PRF_T* prf, sword16* p, + const byte* seed, byte eta1) +{ + int ret; + + (void)eta1; + +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) + if (eta1 == MLKEM_CBD_ETA3) { + byte rand[ETA3_RAND_SIZE]; + + /* Calculate random bytes from seed with PRF. */ + ret = mlkem_prf(prf, rand, sizeof(rand), seed); + if (ret == 0) { + /* Sample for values in range -3..3 from 3 bits of random. */ + mlkem_cbd_eta3(p, rand); + } + } + else +#endif + { + byte rand[ETA2_RAND_SIZE]; + + /* Calculate random bytes from seed with PRF. */ + ret = mlkem_prf(prf, rand, sizeof(rand), seed); + if (ret == 0) { + /* Sample for values in range -2..2 from 2 bits of random. */ + mlkem_cbd_eta2(p, rand); + } + } + + return ret; +} + +/* Get noise/error by calculating random bytes and sampling to a binomial + * distribution. Values -2..2 + * + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE,m,r) + * ... + * 14: e1[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * 17: e2[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * + * @param [in, out] prf Pseudo-random function object. + * @param [out] p Polynomial. + * @param [in] seed Seed to use when calculating random. + * @return 0 on success. + */ +static int mlkem_get_noise_eta2_c(MLKEM_PRF_T* prf, sword16* p, + const byte* seed) +{ + int ret; + byte rand[ETA2_RAND_SIZE]; + + /* Calculate random bytes from seed with PRF. */ + ret = mlkem_prf(prf, rand, sizeof(rand), seed); + if (ret == 0) { + mlkem_cbd_eta2(p, rand); + } + + return ret; +} + +#endif + +#ifdef USE_INTEL_SPEEDUP +#define PRF_RAND_SZ (2 * SHA3_256_BYTES) + +#if defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768) || \ + defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) +/* Get the noise/error by calculating random bytes. + * + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE,m,r) + * ... + * 14: e1[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * 17: e2[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * + * @param [out] rand Random number byte array. + * @param [in] seed Seed to generate random from. + * @param [in] o Offset of seed count. + */ +static void mlkem_get_noise_x4_eta2_avx2(byte* rand, byte* seed, byte o) +{ + int i; + word64 state[25 * 4]; + + for (i = 0; i < 4; i++) { + state[4*4 + i] = 0x1f00 + i + o; + } + + mlkem_sha3_256_blocksx4_seed_avx2(state, seed); + mlkem_redistribute_16_rand_avx2(state, rand + 0 * ETA2_RAND_SIZE, + rand + 1 * ETA2_RAND_SIZE, rand + 2 * ETA2_RAND_SIZE, + rand + 3 * ETA2_RAND_SIZE); +} +#endif + +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) || \ + defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) +/* Get noise/error by calculating random bytes and sampling to a binomial + * distribution. Values -2..2 + * + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE,m,r) + * ... + * 14: e1[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * 17: e2[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * + * @param [in, out] prf Pseudo-random function object. + * @param [out] p Polynomial. + * @param [in] seed Seed to use when calculating random. + * @return 0 on success. + */ +static int mlkem_get_noise_eta2_avx2(MLKEM_PRF_T* prf, sword16* p, + const byte* seed) +{ + word64 state[25]; + + (void)prf; + + /* Put first WC_ML_KEM_SYM_SZ bytes og key into blank state. */ + readUnalignedWords64(state, seed, WC_ML_KEM_SYM_SZ / sizeof(word64)); + /* Last byte in with end of content marker. */ + state[WC_ML_KEM_SYM_SZ / 8] = 0x1f00 | seed[WC_ML_KEM_SYM_SZ]; + /* Set rest of state to 0. */ + XMEMSET(state + WC_ML_KEM_SYM_SZ / 8 + 1, 0, + (25 - WC_ML_KEM_SYM_SZ / 8 - 1) * sizeof(word64)); + /* ... except for rate marker. */ + state[WC_SHA3_256_COUNT - 1] = W64LIT(0x8000000000000000); + + /* Perform a block operation on the state for next block of output. */ + if (IS_INTEL_BMI2(cpuid_flags)) { + sha3_block_bmi2(state); + } + else if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + sha3_block_avx2(state); + RESTORE_VECTOR_REGISTERS(); + } + else { + BlockSha3(state); + } + mlkem_cbd_eta2_avx2(p, (byte*)state); + + return 0; +} +#endif + +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) +/* Get the noise/error by calculating random bytes. + * + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE,m,r) + * ... + * 14: e1[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * 17: e2[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * + * @param [out] rand Random number byte array. + * @param [in] seed Seed to generate random from. + * @param [in] o Offset of seed count. + */ +static void mlkem_get_noise_x4_eta3_avx2(byte* rand, byte* seed) +{ + word64 state[25 * 4]; + int i; + + state[4*4 + 0] = 0x1f00 + 0; + state[4*4 + 1] = 0x1f00 + 1; + state[4*4 + 2] = 0x1f00 + 2; + state[4*4 + 3] = 0x1f00 + 3; + + mlkem_sha3_256_blocksx4_seed_avx2(state, seed); + mlkem_redistribute_17_rand_avx2(state, rand + 0 * PRF_RAND_SZ, + rand + 1 * PRF_RAND_SZ, rand + 2 * PRF_RAND_SZ, + rand + 3 * PRF_RAND_SZ); + i = SHA3_256_BYTES; + sha3_blocksx4_avx2(state); + mlkem_redistribute_8_rand_avx2(state, rand + i + 0 * PRF_RAND_SZ, + rand + i + 1 * PRF_RAND_SZ, rand + i + 2 * PRF_RAND_SZ, + rand + i + 3 * PRF_RAND_SZ); +} + +/* Get the noise/error by calculating random bytes and sampling to a binomial + * distribution. + * + * @param [in, out] prf Pseudo-random function object. + * @param [out] vec1 First Vector of polynomials. + * @param [out] vec2 Second Vector of polynomials. + * @param [out] poly Polynomial. + * @param [in] seed Seed to use when calculating random. + * @return 0 on success. + */ +static int mlkem_get_noise_k2_avx2(MLKEM_PRF_T* prf, sword16* vec1, + sword16* vec2, sword16* poly, byte* seed) +{ + int ret = 0; + byte rand[4 * PRF_RAND_SZ]; + + mlkem_get_noise_x4_eta3_avx2(rand, seed); + mlkem_cbd_eta3_avx2(vec1 , rand + 0 * PRF_RAND_SZ); + mlkem_cbd_eta3_avx2(vec1 + MLKEM_N, rand + 1 * PRF_RAND_SZ); + if (poly == NULL) { + mlkem_cbd_eta3_avx2(vec2 , rand + 2 * PRF_RAND_SZ); + mlkem_cbd_eta3_avx2(vec2 + MLKEM_N, rand + 3 * PRF_RAND_SZ); + } + else { + mlkem_cbd_eta2_avx2(vec2 , rand + 2 * PRF_RAND_SZ); + mlkem_cbd_eta2_avx2(vec2 + MLKEM_N, rand + 3 * PRF_RAND_SZ); + + seed[WC_ML_KEM_SYM_SZ] = 4; + ret = mlkem_get_noise_eta2_avx2(prf, poly, seed); + } + + return ret; +} +#endif + +#if defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768) +/* Get the noise/error by calculating random bytes and sampling to a binomial + * distribution. + * + * @param [out] vec1 First Vector of polynomials. + * @param [out] vec2 Second Vector of polynomials. + * @param [out] poly Polynomial. + * @param [in] seed Seed to use when calculating random. + * @return 0 on success. + */ +static int mlkem_get_noise_k3_avx2(sword16* vec1, sword16* vec2, sword16* poly, + byte* seed) +{ + byte rand[4 * ETA2_RAND_SIZE]; + + mlkem_get_noise_x4_eta2_avx2(rand, seed, 0); + mlkem_cbd_eta2_avx2(vec1 , rand + 0 * ETA2_RAND_SIZE); + mlkem_cbd_eta2_avx2(vec1 + 1 * MLKEM_N, rand + 1 * ETA2_RAND_SIZE); + mlkem_cbd_eta2_avx2(vec1 + 2 * MLKEM_N, rand + 2 * ETA2_RAND_SIZE); + mlkem_cbd_eta2_avx2(vec2 , rand + 3 * ETA2_RAND_SIZE); + mlkem_get_noise_x4_eta2_avx2(rand, seed, 4); + mlkem_cbd_eta2_avx2(vec2 + 1 * MLKEM_N, rand + 0 * ETA2_RAND_SIZE); + mlkem_cbd_eta2_avx2(vec2 + 2 * MLKEM_N, rand + 1 * ETA2_RAND_SIZE); + if (poly != NULL) { + mlkem_cbd_eta2_avx2(poly, rand + 2 * ETA2_RAND_SIZE); + } + + return 0; +} +#endif + +#if defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) +/* Get the noise/error by calculating random bytes and sampling to a binomial + * distribution. + * + * @param [in, out] prf Pseudo-random function object. + * @param [out] vec1 First Vector of polynomials. + * @param [out] vec2 Second Vector of polynomials. + * @param [out] poly Polynomial. + * @param [in] seed Seed to use when calculating random. + * @return 0 on success. + */ +static int mlkem_get_noise_k4_avx2(MLKEM_PRF_T* prf, sword16* vec1, + sword16* vec2, sword16* poly, byte* seed) +{ + int ret = 0; + byte rand[4 * ETA2_RAND_SIZE]; + + (void)prf; + + mlkem_get_noise_x4_eta2_avx2(rand, seed, 0); + mlkem_cbd_eta2_avx2(vec1 , rand + 0 * ETA2_RAND_SIZE); + mlkem_cbd_eta2_avx2(vec1 + 1 * MLKEM_N, rand + 1 * ETA2_RAND_SIZE); + mlkem_cbd_eta2_avx2(vec1 + 2 * MLKEM_N, rand + 2 * ETA2_RAND_SIZE); + mlkem_cbd_eta2_avx2(vec1 + 3 * MLKEM_N, rand + 3 * ETA2_RAND_SIZE); + mlkem_get_noise_x4_eta2_avx2(rand, seed, 4); + mlkem_cbd_eta2_avx2(vec2 , rand + 0 * ETA2_RAND_SIZE); + mlkem_cbd_eta2_avx2(vec2 + 1 * MLKEM_N, rand + 1 * ETA2_RAND_SIZE); + mlkem_cbd_eta2_avx2(vec2 + 2 * MLKEM_N, rand + 2 * ETA2_RAND_SIZE); + mlkem_cbd_eta2_avx2(vec2 + 3 * MLKEM_N, rand + 3 * ETA2_RAND_SIZE); + if (poly != NULL) { + seed[WC_ML_KEM_SYM_SZ] = 8; + ret = mlkem_get_noise_eta2_avx2(prf, poly, seed); + } + + return ret; +} +#endif +#endif /* USE_INTEL_SPEEDUP */ + +#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) + +#define PRF_RAND_SZ (2 * SHA3_256_BYTES) + +/* Get the noise/error by calculating random bytes. + * + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE,m,r) + * ... + * 14: e1[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * 17: e2[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * + * @param [out] rand Random number byte array. + * @param [in] seed Seed to generate random from. + * @param [in] o Offset of seed count. + */ +static void mlkem_get_noise_x3_eta2_aarch64(byte* rand, byte* seed, byte o) +{ + word64* state = (word64*)rand; + + state[0*25 + 4] = 0x1f00 + 0 + o; + state[1*25 + 4] = 0x1f00 + 1 + o; + state[2*25 + 4] = 0x1f00 + 2 + o; + + mlkem_shake256_blocksx3_seed_neon(state, seed); +} + +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) +/* Get the noise/error by calculating random bytes. + * + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE,m,r) + * ... + * 14: e1[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * 17: e2[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * + * @param [out] rand Random number byte array. + * @param [in] seed Seed to generate random from. + * @param [in] o Offset of seed count. + */ +static void mlkem_get_noise_x3_eta3_aarch64(byte* rand, byte* seed, byte o) +{ + word64 state[3 * 25]; + + state[0*25 + 4] = 0x1f00 + 0 + o; + state[1*25 + 4] = 0x1f00 + 1 + o; + state[2*25 + 4] = 0x1f00 + 2 + o; + + mlkem_shake256_blocksx3_seed_neon(state, seed); + XMEMCPY(rand + 0 * ETA3_RAND_SIZE, state + 0*25, SHA3_256_BYTES); + XMEMCPY(rand + 1 * ETA3_RAND_SIZE, state + 1*25, SHA3_256_BYTES); + XMEMCPY(rand + 2 * ETA3_RAND_SIZE, state + 2*25, SHA3_256_BYTES); + mlkem_sha3_blocksx3_neon(state); + rand += SHA3_256_BYTES; + XMEMCPY(rand + 0 * ETA3_RAND_SIZE, state + 0*25, + ETA3_RAND_SIZE - SHA3_256_BYTES); + XMEMCPY(rand + 1 * ETA3_RAND_SIZE, state + 1*25, + ETA3_RAND_SIZE - SHA3_256_BYTES); + XMEMCPY(rand + 2 * ETA3_RAND_SIZE, state + 2*25, + ETA3_RAND_SIZE - SHA3_256_BYTES); +} + +/* Get the noise/error by calculating random bytes. + * + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE,m,r) + * ... + * 14: e1[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * 17: e2[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * + * @param [out] rand Random number byte array. + * @param [in] seed Seed to generate random from. + * @param [in] o Offset of seed count. + * @return 0 on success. + */ +static void mlkem_get_noise_eta3_aarch64(byte* rand, byte* seed, byte o) +{ + word64 state[25]; + + state[0] = ((word64*)seed)[0]; + state[1] = ((word64*)seed)[1]; + state[2] = ((word64*)seed)[2]; + state[3] = ((word64*)seed)[3]; + state[4] = 0x1f00 + o; + XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5)); + state[16] = W64LIT(0x8000000000000000); + BlockSha3(state); + XMEMCPY(rand , state, SHA3_256_BYTES); + BlockSha3(state); + XMEMCPY(rand + SHA3_256_BYTES, state, ETA3_RAND_SIZE - SHA3_256_BYTES); +} + +/* Get the noise/error by calculating random bytes and sampling to a binomial + * distribution. + * + * @param [out] vec1 First Vector of polynomials. + * @param [out] vec2 Second Vector of polynomials. + * @param [out] poly Polynomial. + * @param [in] seed Seed to use when calculating random. + * @return 0 on success. + */ +static int mlkem_get_noise_k2_aarch64(sword16* vec1, sword16* vec2, + sword16* poly, byte* seed) +{ + int ret = 0; + byte rand[3 * 25 * 8]; + + mlkem_get_noise_x3_eta3_aarch64(rand, seed, 0); + mlkem_cbd_eta3(vec1 , rand + 0 * ETA3_RAND_SIZE); + mlkem_cbd_eta3(vec1 + MLKEM_N, rand + 1 * ETA3_RAND_SIZE); + if (poly == NULL) { + mlkem_cbd_eta3(vec2 , rand + 2 * ETA3_RAND_SIZE); + mlkem_get_noise_eta3_aarch64(rand, seed, 3); + mlkem_cbd_eta3(vec2 + MLKEM_N, rand ); + } + else { + mlkem_get_noise_x3_eta2_aarch64(rand, seed, 2); + mlkem_cbd_eta2(vec2 , rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec2 + MLKEM_N, rand + 1 * 25 * 8); + mlkem_cbd_eta2(poly , rand + 2 * 25 * 8); + } + + return ret; +} +#endif + +#if defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768) +/* Get the noise/error by calculating random bytes. + * + * FIPS 203, Algorithm 14: K-PKE.Encrypt(ek_PKE,m,r) + * ... + * 14: e1[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * 17: e2[i] <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) + * ... + * + * @param [out] rand Random number byte array. + * @param [in] seed Seed to generate random from. + * @param [in] o Offset of seed count. + * @return 0 on success. + */ +static void mlkem_get_noise_eta2_aarch64(byte* rand, byte* seed, byte o) +{ + word64* state = (word64*)rand; + + state[0] = ((word64*)seed)[0]; + state[1] = ((word64*)seed)[1]; + state[2] = ((word64*)seed)[2]; + state[3] = ((word64*)seed)[3]; + /* Transposed value same as not. */ + state[4] = 0x1f00 + o; + XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5)); + state[16] = W64LIT(0x8000000000000000); + BlockSha3(state); +} + +/* Get the noise/error by calculating random bytes and sampling to a binomial + * distribution. + * + * @param [out] vec1 First Vector of polynomials. + * @param [out] vec2 Second Vector of polynomials. + * @param [out] poly Polynomial. + * @param [in] seed Seed to use when calculating random. + * @return 0 on success. + */ +static int mlkem_get_noise_k3_aarch64(sword16* vec1, sword16* vec2, + sword16* poly, byte* seed) +{ + byte rand[3 * 25 * 8]; + + mlkem_get_noise_x3_eta2_aarch64(rand, seed, 0); + mlkem_cbd_eta2(vec1 , rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec1 + 1 * MLKEM_N, rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec1 + 2 * MLKEM_N, rand + 2 * 25 * 8); + mlkem_get_noise_x3_eta2_aarch64(rand, seed, 3); + mlkem_cbd_eta2(vec2 , rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec2 + 1 * MLKEM_N, rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec2 + 2 * MLKEM_N, rand + 2 * 25 * 8); + if (poly != NULL) { + mlkem_get_noise_eta2_aarch64(rand, seed, 6); + mlkem_cbd_eta2(poly , rand + 0 * 25 * 8); + } + + return 0; +} +#endif + +#if defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) +/* Get the noise/error by calculating random bytes and sampling to a binomial + * distribution. + * + * @param [out] vec1 First Vector of polynomials. + * @param [out] vec2 Second Vector of polynomials. + * @param [out] poly Polynomial. + * @param [in] seed Seed to use when calculating random. + * @return 0 on success. + */ +static int mlkem_get_noise_k4_aarch64(sword16* vec1, sword16* vec2, + sword16* poly, byte* seed) +{ + int ret = 0; + byte rand[3 * 25 * 8]; + + mlkem_get_noise_x3_eta2_aarch64(rand, seed, 0); + mlkem_cbd_eta2(vec1 , rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec1 + 1 * MLKEM_N, rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec1 + 2 * MLKEM_N, rand + 2 * 25 * 8); + mlkem_get_noise_x3_eta2_aarch64(rand, seed, 3); + mlkem_cbd_eta2(vec1 + 3 * MLKEM_N, rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec2 , rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec2 + 1 * MLKEM_N, rand + 2 * 25 * 8); + mlkem_get_noise_x3_eta2_aarch64(rand, seed, 6); + mlkem_cbd_eta2(vec2 + 2 * MLKEM_N, rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec2 + 3 * MLKEM_N, rand + 1 * 25 * 8); + if (poly != NULL) { + mlkem_cbd_eta2(poly, rand + 2 * 25 * 8); + } + + return ret; +} +#endif +#endif /* __aarch64__ && WOLFSSL_ARMASM */ + +#if !(defined(__aarch64__) && defined(WOLFSSL_ARMASM)) + +/* Get the noise/error by calculating random bytes and sampling to a binomial + * distribution. + * + * @param [in, out] prf Pseudo-random function object. + * @param [in] k Number of polynomials in vector. + * @param [out] vec1 First Vector of polynomials. + * @param [in] eta1 Size of noise/error integers with first vector. + * @param [out] vec2 Second Vector of polynomials. + * @param [in] eta2 Size of noise/error integers with second vector. + * @param [out] poly Polynomial. + * @param [in] seed Seed to use when calculating random. + * @return 0 on success. + */ +static int mlkem_get_noise_c(MLKEM_PRF_T* prf, int k, sword16* vec1, int eta1, + sword16* vec2, int eta2, sword16* poly, byte* seed) +{ + int ret = 0; + int i; + + /* First noise generation has a seed with 0x00 appended. */ + seed[WC_ML_KEM_SYM_SZ] = 0; + /* Generate noise as private key. */ + for (i = 0; (ret == 0) && (i < k); i++) { + /* Generate noise for each dimension of vector. */ + ret = mlkem_get_noise_eta1_c(prf, vec1 + i * MLKEM_N, seed, eta1); + /* Increment value of appended byte. */ + seed[WC_ML_KEM_SYM_SZ]++; + } + if ((ret == 0) && (vec2 != NULL)) { + /* Generate noise for error. */ + for (i = 0; (ret == 0) && (i < k); i++) { + /* Generate noise for each dimension of vector. */ + ret = mlkem_get_noise_eta1_c(prf, vec2 + i * MLKEM_N, seed, eta2); + /* Increment value of appended byte. */ + seed[WC_ML_KEM_SYM_SZ]++; + } + } + else { + seed[WC_ML_KEM_SYM_SZ] = 2 * k; + } + if ((ret == 0) && (poly != NULL)) { + /* Generating random error polynomial. */ + ret = mlkem_get_noise_eta2_c(prf, poly, seed); + } + + return ret; +} + +#endif /* __aarch64__ && WOLFSSL_ARMASM */ + +/* Get the noise/error by calculating random bytes and sampling to a binomial + * distribution. + * + * @param [in, out] prf Pseudo-random function object. + * @param [in] k Number of polynomials in vector. + * @param [out] vec1 First Vector of polynomials. + * @param [out] vec2 Second Vector of polynomials. + * @param [out] poly Polynomial. + * @param [in] seed Seed to use when calculating random. + * @return 0 on success. + */ +int mlkem_get_noise(MLKEM_PRF_T* prf, int k, sword16* vec1, sword16* vec2, + sword16* poly, byte* seed) +{ + int ret; + +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) + if (k == WC_ML_KEM_512_K) { +#if defined(WOLFSSL_ARMASM) && defined(__aarch64__) + ret = mlkem_get_noise_k2_aarch64(vec1, vec2, poly, seed); +#else + #ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + ret = mlkem_get_noise_k2_avx2(prf, vec1, vec2, poly, seed); + RESTORE_VECTOR_REGISTERS(); + } + else + #endif + if (poly == NULL) { + ret = mlkem_get_noise_c(prf, k, vec1, MLKEM_CBD_ETA3, vec2, + MLKEM_CBD_ETA3, NULL, seed); + } + else { + ret = mlkem_get_noise_c(prf, k, vec1, MLKEM_CBD_ETA3, vec2, + MLKEM_CBD_ETA2, poly, seed); + } +#endif + } + else +#endif +#if defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768) + if (k == WC_ML_KEM_768_K) { +#if defined(WOLFSSL_ARMASM) && defined(__aarch64__) + ret = mlkem_get_noise_k3_aarch64(vec1, vec2, poly, seed); +#else + #ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + ret = mlkem_get_noise_k3_avx2(vec1, vec2, poly, seed); + RESTORE_VECTOR_REGISTERS(); + } + else + #endif + { + ret = mlkem_get_noise_c(prf, k, vec1, MLKEM_CBD_ETA2, vec2, + MLKEM_CBD_ETA2, poly, seed); + } +#endif + } + else +#endif +#if defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) + if (k == WC_ML_KEM_1024_K) { +#if defined(WOLFSSL_ARMASM) && defined(__aarch64__) + ret = mlkem_get_noise_k4_aarch64(vec1, vec2, poly, seed); +#else + #ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + ret = mlkem_get_noise_k4_avx2(prf, vec1, vec2, poly, seed); + RESTORE_VECTOR_REGISTERS(); + } + else + #endif + { + ret = mlkem_get_noise_c(prf, k, vec1, MLKEM_CBD_ETA2, vec2, + MLKEM_CBD_ETA2, poly, seed); + } +#endif + } + else +#endif + { + ret = BAD_STATE_E; + } + + (void)prf; + + return ret; +} + +#if defined(WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM) || \ + defined(WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM) +/* Get the noise/error by calculating random bytes and sampling to a binomial + * distribution. + * + * @param [in, out] prf Pseudo-random function object. + * @param [in] k Number of polynomials in vector. + * @param [out] vec2 Second Vector of polynomials. + * @param [in] seed Seed to use when calculating random. + * @param [in] i Index of vector to generate. + * @param [in] make Indicates generation is for making a key. + * @return 0 on success. + */ +static int mlkem_get_noise_i(MLKEM_PRF_T* prf, int k, sword16* vec2, + byte* seed, int i, int make) +{ + int ret; + + /* Initialize the PRF (generating matrix A leaves it in uninitialized + * state). */ + mlkem_prf_init(prf); + + /* Set index of polynomial of second vector into seed. */ + seed[WC_ML_KEM_SYM_SZ] = k + i; +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) + if ((k == WC_ML_KEM_512_K) && make) { + ret = mlkem_get_noise_eta1_c(prf, vec2, seed, MLKEM_CBD_ETA3); + } + else +#endif + { + ret = mlkem_get_noise_eta1_c(prf, vec2, seed, MLKEM_CBD_ETA2); + } + + (void)make; + return ret; +} +#endif + +/******************************************************************************/ + +#if !(defined(__aarch64__) && defined(WOLFSSL_ARMASM)) +/* Compare two byte arrays of equal size. + * + * @param [in] a First array to compare. + * @param [in] b Second array to compare. + * @param [in] sz Size of arrays in bytes. + * @return 0 on success. + * @return -1 on failure. + */ +static int mlkem_cmp_c(const byte* a, const byte* b, int sz) +{ + int i; + byte r = 0; + + /* Constant time comparison of the encapsulated message and cipher text. */ + for (i = 0; i < sz; i++) { + r |= a[i] ^ b[i]; + } + return 0 - ((-(word32)r) >> 31); +} +#endif + +/* Compare two byte arrays of equal size. + * + * @param [in] a First array to compare. + * @param [in] b Second array to compare. + * @param [in] sz Size of arrays in bytes. + * @return 0 on success. + * @return -1 on failure. + */ +int mlkem_cmp(const byte* a, const byte* b, int sz) +{ +#if defined(__aarch64__) && defined(WOLFSSL_ARMASM) + return mlkem_cmp_neon(a, b, sz); +#else + int fail; + +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + fail = mlkem_cmp_avx2(a, b, sz); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + fail = mlkem_cmp_c(a, b, sz); + } + + return fail; +#endif +} + +/******************************************************************************/ + +#if !defined(WOLFSSL_ARMASM) + +/* Conditional subtraction of q to each coefficient of a polynomial. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in, out] p Polynomial. + */ +static MLKEM_NOINLINE void mlkem_csubq_c(sword16* p) +{ + unsigned int i; + + for (i = 0; i < MLKEM_N; ++i) { + sword16 t = p[i] - MLKEM_Q; + /* When top bit set, -ve number - need to add q back. */ + p[i] = ((t >> 15) & MLKEM_Q) + t; + } +} + +#elif defined(__aarch64__) + +/* Conditional subtraction of q to each coefficient of a polynomial. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in, out] p Polynomial. + */ +#define mlkem_csubq_c mlkem_csubq_neon + +#elif defined(WOLFSSL_ARMASM_THUMB2) + +/* Conditional subtraction of q to each coefficient of a polynomial. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in, out] p Polynomial. + */ +#define mlkem_csubq_c mlkem_thumb2_csubq + +#else + +/* Conditional subtraction of q to each coefficient of a polynomial. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in, out] p Polynomial. + */ +#define mlkem_csubq_c mlkem_arm32_csubq + +#endif + +/******************************************************************************/ + +#if defined(CONV_WITH_DIV) || !defined(WORD64_AVAILABLE) + +/* Compress value. + * + * Uses div operator that may be slow. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] v Vector of polynomials. + * @param [in] i Index of polynomial in vector. + * @param [in] j Index into polynomial. + * @param [in] k Offset from indices. + * @param [in] s Shift amount to apply to value being compressed. + * @param [in] m Mask to apply get the require number of bits. + * @return Compressed value. + */ +#define TO_COMP_WORD_VEC(v, i, j, k, s, m) \ + ((((word32)v[i * MLKEM_N + j + k] << s) + MLKEM_Q_HALF) / MLKEM_Q) & m + +/* Compress value to 10 bits. + * + * Uses mul instead of div. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] v Vector of polynomials. + * @param [in] i Index of polynomial in vector. + * @param [in] j Index into polynomial. + * @param [in] k Offset from indices. + * @return Compressed value. + */ +#define TO_COMP_WORD_10(v, i, j, k) \ + TO_COMP_WORD_VEC(v, i, j, k, 10, 0x3ff) + +/* Compress value to 11 bits. + * + * Uses mul instead of div. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] v Vector of polynomials. + * @param [in] i Index of polynomial in vector. + * @param [in] j Index into polynomial. + * @param [in] k Offset from indices. + * @return Compressed value. + */ +#define TO_COMP_WORD_11(v, i, j, k) \ + TO_COMP_WORD_VEC(v, i, j, k, 11, 0x7ff) + +#else + +/* Multiplier that does div q. + * ((1 << 53) + MLKEM_Q_HALF) / MLKEM_Q + */ +#define MLKEM_V53 0x275f6ed0176UL +/* Multiplier times half of q. + * MLKEM_V53 * (MLKEM_Q_HALF + 1) + */ +#define MLKEM_V53_HALF 0x10013afb768076UL + +/* Multiplier that does div q. + * ((1 << 54) + MLKEM_Q_HALF) / MLKEM_Q + */ +#define MLKEM_V54 0x4ebedda02ecUL +/* Multiplier times half of q. + * MLKEM_V54 * (MLKEM_Q_HALF + 1) + */ +#define MLKEM_V54_HALF 0x200275f6ed00ecUL + +/* Compress value to 10 bits. + * + * Uses mul instead of div. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] v Vector of polynomials. + * @param [in] i Index of polynomial in vector. + * @param [in] j Index into polynomial. + * @param [in] k Offset from indices. + * @return Compressed value. + */ +#define TO_COMP_WORD_10(v, i, j, k) \ + ((((MLKEM_V54 << 10) * (v)[(i) * MLKEM_N + (j) + (k)]) + \ + MLKEM_V54_HALF) >> 54) + +/* Compress value to 11 bits. + * + * Uses mul instead of div. + * Only works for values in range: 0..3228 + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] v Vector of polynomials. + * @param [in] i Index of polynomial in vector. + * @param [in] j Index into polynomial. + * @param [in] k Offset from indices. + * @return Compressed value. + */ +#define TO_COMP_WORD_11(v, i, j, k) \ + ((((MLKEM_V53 << 11) * (v)[(i) * MLKEM_N + (j) + (k)]) + \ + MLKEM_V53_HALF) >> 53) + +#endif /* CONV_WITH_DIV */ + +#if !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) || \ + !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) || \ + defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768) +/* Compress the vector of polynomials into a byte array with 10 bits each. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] b Array of bytes. + * @param [in] v Vector of polynomials. + * @param [in] k Number of polynomials in vector. + */ +static void mlkem_vec_compress_10_c(byte* r, sword16* v, unsigned int k) +{ + unsigned int i; + unsigned int j; + + for (i = 0; i < k; i++) { + /* Reduce each coefficient to mod q. */ + mlkem_csubq_c(v + i * MLKEM_N); + /* All values are now positive. */ + } + + /* Each polynomial. */ + for (i = 0; i < k; i++) { +#if defined(WOLFSSL_SMALL_STACK) || defined(WOLFSSL_MLKEM_NO_LARGE_CODE) || \ + defined(BIG_ENDIAN_ORDER) + /* Each 4 polynomial coefficients. */ + for (j = 0; j < MLKEM_N; j += 4) { + #ifdef WOLFSSL_MLKEM_SMALL + unsigned int l; + sword16 t[4]; + /* Compress four polynomial values to 10 bits each. */ + for (l = 0; l < 4; l++) { + t[l] = TO_COMP_WORD_10(v, i, j, l); + } + + /* Pack four 10-bit values into byte array. */ + r[ 0] = (t[0] >> 0); + r[ 1] = (t[0] >> 8) | (t[1] << 2); + r[ 2] = (t[1] >> 6) | (t[2] << 4); + r[ 3] = (t[2] >> 4) | (t[3] << 6); + r[ 4] = (t[3] >> 2); + #else + /* Compress four polynomial values to 10 bits each. */ + sword16 t0 = TO_COMP_WORD_10(v, i, j, 0); + sword16 t1 = TO_COMP_WORD_10(v, i, j, 1); + sword16 t2 = TO_COMP_WORD_10(v, i, j, 2); + sword16 t3 = TO_COMP_WORD_10(v, i, j, 3); + + /* Pack four 10-bit values into byte array. */ + r[ 0] = (t0 >> 0); + r[ 1] = (t0 >> 8) | (t1 << 2); + r[ 2] = (t1 >> 6) | (t2 << 4); + r[ 3] = (t2 >> 4) | (t3 << 6); + r[ 4] = (t3 >> 2); + #endif + + /* Move over set bytes. */ + r += 5; + } +#else + /* Each 16 polynomial coefficients. */ + for (j = 0; j < MLKEM_N; j += 16) { + /* Compress four polynomial values to 10 bits each. */ + sword16 t0 = TO_COMP_WORD_10(v, i, j, 0); + sword16 t1 = TO_COMP_WORD_10(v, i, j, 1); + sword16 t2 = TO_COMP_WORD_10(v, i, j, 2); + sword16 t3 = TO_COMP_WORD_10(v, i, j, 3); + sword16 t4 = TO_COMP_WORD_10(v, i, j, 4); + sword16 t5 = TO_COMP_WORD_10(v, i, j, 5); + sword16 t6 = TO_COMP_WORD_10(v, i, j, 6); + sword16 t7 = TO_COMP_WORD_10(v, i, j, 7); + sword16 t8 = TO_COMP_WORD_10(v, i, j, 8); + sword16 t9 = TO_COMP_WORD_10(v, i, j, 9); + sword16 t10 = TO_COMP_WORD_10(v, i, j, 10); + sword16 t11 = TO_COMP_WORD_10(v, i, j, 11); + sword16 t12 = TO_COMP_WORD_10(v, i, j, 12); + sword16 t13 = TO_COMP_WORD_10(v, i, j, 13); + sword16 t14 = TO_COMP_WORD_10(v, i, j, 14); + sword16 t15 = TO_COMP_WORD_10(v, i, j, 15); + + word32* r32 = (word32*)r; + /* Pack sixteen 10-bit values into byte array. */ + r32[0] = t0 | ((word32)t1 << 10) | ((word32)t2 << 20) | + ((word32)t3 << 30); + r32[1] = (t3 >> 2) | ((word32)t4 << 8) | ((word32)t5 << 18) | + ((word32)t6 << 28); + r32[2] = (t6 >> 4) | ((word32)t7 << 6) | ((word32)t8 << 16) | + ((word32)t9 << 26); + r32[3] = (t9 >> 6) | ((word32)t10 << 4) | ((word32)t11 << 14) | + ((word32)t12 << 24); + r32[4] = (t12 >> 8) | ((word32)t13 << 2) | ((word32)t14 << 12) | + ((word32)t15 << 22); + + /* Move over set bytes. */ + r += 20; + } +#endif + } +} + +/* Compress the vector of polynomials into a byte array with 10 bits each. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] b Array of bytes. + * @param [in] v Vector of polynomials. + * @param [in] k Number of polynomials in vector. + */ +void mlkem_vec_compress_10(byte* r, sword16* v, unsigned int k) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + mlkem_compress_10_avx2(r, v, k); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_vec_compress_10_c(r, v, k); + } +} +#endif + +#if defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) +/* Compress the vector of polynomials into a byte array with 11 bits each. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] b Array of bytes. + * @param [in] v Vector of polynomials. + */ +static void mlkem_vec_compress_11_c(byte* r, sword16* v) +{ + unsigned int i; + unsigned int j; +#ifdef WOLFSSL_MLKEM_SMALL + unsigned int k; +#endif + + for (i = 0; i < 4; i++) { + /* Reduce each coefficient to mod q. */ + mlkem_csubq_c(v + i * MLKEM_N); + /* All values are now positive. */ + } + + /* Each polynomial. */ + for (i = 0; i < 4; i++) { + /* Each 8 polynomial coefficients. */ + for (j = 0; j < MLKEM_N; j += 8) { + #ifdef WOLFSSL_MLKEM_SMALL + sword16 t[8]; + /* Compress eight polynomial values to 11 bits each. */ + for (k = 0; k < 8; k++) { + t[k] = TO_COMP_WORD_11(v, i, j, k); + } + + /* Pack eight 11-bit values into byte array. */ + r[ 0] = (t[0] >> 0); + r[ 1] = (t[0] >> 8) | (t[1] << 3); + r[ 2] = (t[1] >> 5) | (t[2] << 6); + r[ 3] = (t[2] >> 2); + r[ 4] = (t[2] >> 10) | (t[3] << 1); + r[ 5] = (t[3] >> 7) | (t[4] << 4); + r[ 6] = (t[4] >> 4) | (t[5] << 7); + r[ 7] = (t[5] >> 1); + r[ 8] = (t[5] >> 9) | (t[6] << 2); + r[ 9] = (t[6] >> 6) | (t[7] << 5); + r[10] = (t[7] >> 3); + #else + /* Compress eight polynomial values to 11 bits each. */ + sword16 t0 = TO_COMP_WORD_11(v, i, j, 0); + sword16 t1 = TO_COMP_WORD_11(v, i, j, 1); + sword16 t2 = TO_COMP_WORD_11(v, i, j, 2); + sword16 t3 = TO_COMP_WORD_11(v, i, j, 3); + sword16 t4 = TO_COMP_WORD_11(v, i, j, 4); + sword16 t5 = TO_COMP_WORD_11(v, i, j, 5); + sword16 t6 = TO_COMP_WORD_11(v, i, j, 6); + sword16 t7 = TO_COMP_WORD_11(v, i, j, 7); + + /* Pack eight 11-bit values into byte array. */ + r[ 0] = (t0 >> 0); + r[ 1] = (t0 >> 8) | (t1 << 3); + r[ 2] = (t1 >> 5) | (t2 << 6); + r[ 3] = (t2 >> 2); + r[ 4] = (t2 >> 10) | (t3 << 1); + r[ 5] = (t3 >> 7) | (t4 << 4); + r[ 6] = (t4 >> 4) | (t5 << 7); + r[ 7] = (t5 >> 1); + r[ 8] = (t5 >> 9) | (t6 << 2); + r[ 9] = (t6 >> 6) | (t7 << 5); + r[10] = (t7 >> 3); + #endif + + /* Move over set bytes. */ + r += 11; + } + } +} + +/* Compress the vector of polynomials into a byte array with 11 bits each. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] b Array of bytes. + * @param [in] v Vector of polynomials. + */ +void mlkem_vec_compress_11(byte* r, sword16* v) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + mlkem_compress_11_avx2(r, v, 4); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_vec_compress_11_c(r, v); + } +} +#endif +#endif /* !WOLFSSL_MLKEM_NO_ENCAPSULATE || !WOLFSSL_MLKEM_NO_DECAPSULATE */ + +#ifndef WOLFSSL_MLKEM_NO_DECAPSULATE +/* Decompress a 10 bit value. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] v Vector of polynomials. + * @param [in] i Index of polynomial in vector. + * @param [in] j Index into polynomial. + * @param [in] k Offset from indices. + * @param [in] t Value to decompress. + * @return Decompressed value. + */ +#define DECOMP_10(v, i, j, k, t) \ + v[(i) * MLKEM_N + 4 * (j) + (k)] = \ + (word16)((((word32)((t) & 0x3ff) * MLKEM_Q) + 512) >> 10) + +/* Decompress an 11 bit value. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] v Vector of polynomials. + * @param [in] i Index of polynomial in vector. + * @param [in] j Index into polynomial. + * @param [in] k Offset from indices. + * @param [in] t Value to decompress. + * @return Decompressed value. + */ +#define DECOMP_11(v, i, j, k, t) \ + v[(i) * MLKEM_N + 8 * (j) + (k)] = \ + (word16)((((word32)((t) & 0x7ff) * MLKEM_Q) + 1024) >> 11) + +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) || \ + defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768) +/* Decompress the byte array of packed 10 bits into vector of polynomials. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] v Vector of polynomials. + * @param [in] b Array of bytes. + * @param [in] k Number of polynomials in vector. + */ +static void mlkem_vec_decompress_10_c(sword16* v, const byte* b, unsigned int k) +{ + unsigned int i; + unsigned int j; +#ifdef WOLFSSL_MLKEM_SMALL + unsigned int l; +#endif + + /* Each polynomial. */ + for (i = 0; i < k; i++) { + /* Each 4 polynomial coefficients. */ + for (j = 0; j < MLKEM_N / 4; j++) { + #ifdef WOLFSSL_MLKEM_SMALL + word16 t[4]; + /* Extract out 4 values of 10 bits each. */ + t[0] = (b[0] >> 0) | ((word16)b[ 1] << 8); + t[1] = (b[1] >> 2) | ((word16)b[ 2] << 6); + t[2] = (b[2] >> 4) | ((word16)b[ 3] << 4); + t[3] = (b[3] >> 6) | ((word16)b[ 4] << 2); + b += 5; + + /* Decompress 4 values. */ + for (l = 0; l < 4; l++) { + DECOMP_10(v, i, j, l, t[l]); + } + #else + /* Extract out 4 values of 10 bits each. */ + sword16 t0 = (b[0] >> 0) | ((word16)b[ 1] << 8); + sword16 t1 = (b[1] >> 2) | ((word16)b[ 2] << 6); + sword16 t2 = (b[2] >> 4) | ((word16)b[ 3] << 4); + sword16 t3 = (b[3] >> 6) | ((word16)b[ 4] << 2); + b += 5; + + /* Decompress 4 values. */ + DECOMP_10(v, i, j, 0, t0); + DECOMP_10(v, i, j, 1, t1); + DECOMP_10(v, i, j, 2, t2); + DECOMP_10(v, i, j, 3, t3); + #endif + } + } +} + +/* Decompress the byte array of packed 10 bits into vector of polynomials. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] v Vector of polynomials. + * @param [in] b Array of bytes. + * @param [in] k Number of polynomials in vector. + */ +void mlkem_vec_decompress_10(sword16* v, const byte* b, unsigned int k) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + mlkem_decompress_10_avx2(v, b, k); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_vec_decompress_10_c(v, b, k); + } +} +#endif +#if defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) +/* Decompress the byte array of packed 11 bits into vector of polynomials. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] v Vector of polynomials. + * @param [in] b Array of bytes. + */ +static void mlkem_vec_decompress_11_c(sword16* v, const byte* b) +{ + unsigned int i; + unsigned int j; +#ifdef WOLFSSL_MLKEM_SMALL + unsigned int l; +#endif + + /* Each polynomial. */ + for (i = 0; i < 4; i++) { + /* Each 8 polynomial coefficients. */ + for (j = 0; j < MLKEM_N / 8; j++) { + #ifdef WOLFSSL_MLKEM_SMALL + word16 t[8]; + /* Extract out 8 values of 11 bits each. */ + t[0] = (b[0] >> 0) | ((word16)b[ 1] << 8); + t[1] = (b[1] >> 3) | ((word16)b[ 2] << 5); + t[2] = (b[2] >> 6) | ((word16)b[ 3] << 2) | + ((word16)b[4] << 10); + t[3] = (b[4] >> 1) | ((word16)b[ 5] << 7); + t[4] = (b[5] >> 4) | ((word16)b[ 6] << 4); + t[5] = (b[6] >> 7) | ((word16)b[ 7] << 1) | + ((word16)b[8] << 9); + t[6] = (b[8] >> 2) | ((word16)b[ 9] << 6); + t[7] = (b[9] >> 5) | ((word16)b[10] << 3); + b += 11; + + /* Decompress 8 values. */ + for (l = 0; l < 8; l++) { + DECOMP_11(v, i, j, l, t[l]); + } + #else + /* Extract out 8 values of 11 bits each. */ + sword16 t0 = (b[0] >> 0) | ((word16)b[ 1] << 8); + sword16 t1 = (b[1] >> 3) | ((word16)b[ 2] << 5); + sword16 t2 = (b[2] >> 6) | ((word16)b[ 3] << 2) | + ((word16)b[4] << 10); + sword16 t3 = (b[4] >> 1) | ((word16)b[ 5] << 7); + sword16 t4 = (b[5] >> 4) | ((word16)b[ 6] << 4); + sword16 t5 = (b[6] >> 7) | ((word16)b[ 7] << 1) | + ((word16)b[8] << 9); + sword16 t6 = (b[8] >> 2) | ((word16)b[ 9] << 6); + sword16 t7 = (b[9] >> 5) | ((word16)b[10] << 3); + b += 11; + + /* Decompress 8 values. */ + DECOMP_11(v, i, j, 0, t0); + DECOMP_11(v, i, j, 1, t1); + DECOMP_11(v, i, j, 2, t2); + DECOMP_11(v, i, j, 3, t3); + DECOMP_11(v, i, j, 4, t4); + DECOMP_11(v, i, j, 5, t5); + DECOMP_11(v, i, j, 6, t6); + DECOMP_11(v, i, j, 7, t7); + #endif + } + } +} + +/* Decompress the byte array of packed 11 bits into vector of polynomials. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] v Vector of polynomials. + * @param [in] b Array of bytes. + */ +void mlkem_vec_decompress_11(sword16* v, const byte* b) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + mlkem_decompress_11_avx2(v, b, 4); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_vec_decompress_11_c(v, b); + } +} +#endif +#endif /* !WOLFSSL_MLKEM_NO_DECAPSULATE */ + +#ifdef CONV_WITH_DIV + +/* Compress value. + * + * Uses div operator that may be slow. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] v Vector of polynomials. + * @param [in] i Index into polynomial. + * @param [in] j Offset from indices. + * @param [in] s Shift amount to apply to value being compressed. + * @param [in] m Mask to apply get the require number of bits. + * @return Compressed value. + */ +#define TO_COMP_WORD(v, i, j, s, m) \ + ((((word32)v[i + j] << s) + MLKEM_Q_HALF) / MLKEM_Q) & m + +/* Compress value to 4 bits. + * + * Uses mul instead of div. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] p Polynomial. + * @param [in] i Index into polynomial. + * @param [in] j Offset from indices. + * @return Compressed value. + */ +#define TO_COMP_WORD_4(p, i, j) \ + TO_COMP_WORD(p, i, j, 4, 0xf) + +/* Compress value to 5 bits. + * + * Uses mul instead of div. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] p Polynomial. + * @param [in] i Index into polynomial. + * @param [in] j Offset from indices. + * @return Compressed value. + */ +#define TO_COMP_WORD_5(p, i, j) \ + TO_COMP_WORD(p, i, j, 5, 0x1f) + +#else + +/* Multiplier that does div q. */ +#define MLKEM_V28 ((word32)(((1U << 28) + MLKEM_Q_HALF)) / MLKEM_Q) +/* Multiplier times half of q. */ +#define MLKEM_V28_HALF ((word32)(MLKEM_V28 * (MLKEM_Q_HALF + 1))) + +/* Multiplier that does div q. */ +#define MLKEM_V27 ((word32)(((1U << 27) + MLKEM_Q_HALF)) / MLKEM_Q) +/* Multiplier times half of q. */ +#define MLKEM_V27_HALF ((word32)(MLKEM_V27 * MLKEM_Q_HALF)) + +/* Compress value to 4 bits. + * + * Uses mul instead of div. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] p Polynomial. + * @param [in] i Index into polynomial. + * @param [in] j Offset from indices. + * @return Compressed value. + */ +#define TO_COMP_WORD_4(p, i, j) \ + ((((MLKEM_V28 << 4) * (p)[(i) + (j)]) + MLKEM_V28_HALF) >> 28) + +/* Compress value to 5 bits. + * + * Uses mul instead of div. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] p Polynomial. + * @param [in] i Index into polynomial. + * @param [in] j Offset from indices. + * @return Compressed value. + */ +#define TO_COMP_WORD_5(p, i, j) \ + ((((MLKEM_V27 << 5) * (p)[(i) + (j)]) + MLKEM_V27_HALF) >> 27) + +#endif /* CONV_WITH_DIV */ + +#if !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) || \ + !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) || \ + defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768) +/* Compress a polynomial into byte array - on coefficients into 4 bits. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] b Array of bytes. + * @param [in] p Polynomial. + */ +static void mlkem_compress_4_c(byte* b, sword16* p) +{ + unsigned int i; +#ifdef WOLFSSL_MLKEM_SMALL + unsigned int j; + byte t[8]; +#endif + + /* Reduce each coefficients to mod q. */ + mlkem_csubq_c(p); + /* All values are now positive. */ + + /* Each 8 polynomial coefficients. */ + for (i = 0; i < MLKEM_N; i += 8) { + #ifdef WOLFSSL_MLKEM_SMALL + /* Compress eight polynomial values to 4 bits each. */ + for (j = 0; j < 8; j++) { + t[j] = TO_COMP_WORD_4(p, i, j); + } + + b[0] = t[0] | (t[1] << 4); + b[1] = t[2] | (t[3] << 4); + b[2] = t[4] | (t[5] << 4); + b[3] = t[6] | (t[7] << 4); + #else + /* Compress eight polynomial values to 4 bits each. */ + byte t0 = TO_COMP_WORD_4(p, i, 0); + byte t1 = TO_COMP_WORD_4(p, i, 1); + byte t2 = TO_COMP_WORD_4(p, i, 2); + byte t3 = TO_COMP_WORD_4(p, i, 3); + byte t4 = TO_COMP_WORD_4(p, i, 4); + byte t5 = TO_COMP_WORD_4(p, i, 5); + byte t6 = TO_COMP_WORD_4(p, i, 6); + byte t7 = TO_COMP_WORD_4(p, i, 7); + + /* Pack eight 4-bit values into byte array. */ + b[0] = t0 | (t1 << 4); + b[1] = t2 | (t3 << 4); + b[2] = t4 | (t5 << 4); + b[3] = t6 | (t7 << 4); + #endif + + /* Move over set bytes. */ + b += 4; + } +} + +/* Compress a polynomial into byte array - on coefficients into 4 bits. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] b Array of bytes. + * @param [in] p Polynomial. + */ +void mlkem_compress_4(byte* b, sword16* p) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + mlkem_compress_4_avx2(b, p); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_compress_4_c(b, p); + } +} +#endif +#if defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) +/* Compress a polynomial into byte array - on coefficients into 5 bits. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] b Array of bytes. + * @param [in] p Polynomial. + */ +static void mlkem_compress_5_c(byte* b, sword16* p) +{ + unsigned int i; +#ifdef WOLFSSL_MLKEM_SMALL + unsigned int j; + byte t[8]; +#endif + + /* Reduce each coefficients to mod q. */ + mlkem_csubq_c(p); + /* All values are now positive. */ + + for (i = 0; i < MLKEM_N; i += 8) { + #ifdef WOLFSSL_MLKEM_SMALL + /* Compress eight polynomial values to 5 bits each. */ + for (j = 0; j < 8; j++) { + t[j] = TO_COMP_WORD_5(p, i, j); + } + + /* Pack 5 bits into byte array. */ + b[0] = (t[0] >> 0) | (t[1] << 5); + b[1] = (t[1] >> 3) | (t[2] << 2) | (t[3] << 7); + b[2] = (t[3] >> 1) | (t[4] << 4); + b[3] = (t[4] >> 4) | (t[5] << 1) | (t[6] << 6); + b[4] = (t[6] >> 2) | (t[7] << 3); + #else + /* Compress eight polynomial values to 5 bits each. */ + byte t0 = TO_COMP_WORD_5(p, i, 0); + byte t1 = TO_COMP_WORD_5(p, i, 1); + byte t2 = TO_COMP_WORD_5(p, i, 2); + byte t3 = TO_COMP_WORD_5(p, i, 3); + byte t4 = TO_COMP_WORD_5(p, i, 4); + byte t5 = TO_COMP_WORD_5(p, i, 5); + byte t6 = TO_COMP_WORD_5(p, i, 6); + byte t7 = TO_COMP_WORD_5(p, i, 7); + + /* Pack eight 5-bit values into byte array. */ + b[0] = (t0 >> 0) | (t1 << 5); + b[1] = (t1 >> 3) | (t2 << 2) | (t3 << 7); + b[2] = (t3 >> 1) | (t4 << 4); + b[3] = (t4 >> 4) | (t5 << 1) | (t6 << 6); + b[4] = (t6 >> 2) | (t7 << 3); + #endif + + /* Move over set bytes. */ + b += 5; + } +} + +/* Compress a polynomial into byte array - on coefficients into 5 bits. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] b Array of bytes. + * @param [in] p Polynomial. + */ +void mlkem_compress_5(byte* b, sword16* p) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + mlkem_compress_5_avx2(b, p); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_compress_5_c(b, p); + } +} +#endif +#endif /* !WOLFSSL_MLKEM_NO_ENCAPSULATE || !WOLFSSL_MLKEM_NO_DECAPSULATE */ + +#ifndef WOLFSSL_MLKEM_NO_DECAPSULATE +/* Decompress a 4 bit value. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] p Polynomial. + * @param [in] i Index into polynomial. + * @param [in] j Offset from indices. + * @param [in] t Value to decompress. + * @return Decompressed value. + */ +#define DECOMP_4(p, i, j, t) \ + p[(i) + (j)] = ((word16)((t) * MLKEM_Q) + 8) >> 4 + +/* Decompress a 5 bit value. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [in] p Polynomial. + * @param [in] i Index into polynomial. + * @param [in] j Offset from indices. + * @param [in] t Value to decompress. + * @return Decompressed value. + */ +#define DECOMP_5(p, i, j, t) \ + p[(i) + (j)] = (((word32)((t) & 0x1f) * MLKEM_Q) + 16) >> 5 + +#if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) || \ + defined(WOLFSSL_KYBER768) || defined(WOLFSSL_WC_ML_KEM_768) +/* Decompress the byte array of packed 4 bits into polynomial. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] p Polynomial. + * @param [in] b Array of bytes. + */ +static void mlkem_decompress_4_c(sword16* p, const byte* b) +{ + unsigned int i; + + /* 2 coefficients at a time. */ + for (i = 0; i < MLKEM_N; i += 2) { + /* 2 coefficients decompressed from one byte. */ + DECOMP_4(p, i, 0, b[0] & 0xf); + DECOMP_4(p, i, 1, b[0] >> 4); + b += 1; + } +} + +/* Decompress the byte array of packed 4 bits into polynomial. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] p Polynomial. + * @param [in] b Array of bytes. + */ +void mlkem_decompress_4(sword16* p, const byte* b) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + mlkem_decompress_4_avx2(p, b); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_decompress_4_c(p, b); + } +} +#endif +#if defined(WOLFSSL_KYBER1024) || defined(WOLFSSL_WC_ML_KEM_1024) +/* Decompress the byte array of packed 5 bits into polynomial. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] p Polynomial. + * @param [in] b Array of bytes. + */ +static void mlkem_decompress_5_c(sword16* p, const byte* b) +{ + unsigned int i; + + /* Each 8 polynomial coefficients. */ + for (i = 0; i < MLKEM_N; i += 8) { + #ifdef WOLFSSL_MLKEM_SMALL + unsigned int j; + byte t[8]; + + /* Extract out 8 values of 5 bits each. */ + t[0] = (b[0] >> 0); + t[1] = (b[0] >> 5) | (b[1] << 3); + t[2] = (b[1] >> 2); + t[3] = (b[1] >> 7) | (b[2] << 1); + t[4] = (b[2] >> 4) | (b[3] << 4); + t[5] = (b[3] >> 1); + t[6] = (b[3] >> 6) | (b[4] << 2); + t[7] = (b[4] >> 3); + b += 5; + + /* Decompress 8 values. */ + for (j = 0; j < 8; j++) { + DECOMP_5(p, i, j, t[j]); + } + #else + /* Extract out 8 values of 5 bits each. */ + byte t0 = (b[0] >> 0); + byte t1 = (b[0] >> 5) | (b[1] << 3); + byte t2 = (b[1] >> 2); + byte t3 = (b[1] >> 7) | (b[2] << 1); + byte t4 = (b[2] >> 4) | (b[3] << 4); + byte t5 = (b[3] >> 1); + byte t6 = (b[3] >> 6) | (b[4] << 2); + byte t7 = (b[4] >> 3); + b += 5; + + /* Decompress 8 values. */ + DECOMP_5(p, i, 0, t0); + DECOMP_5(p, i, 1, t1); + DECOMP_5(p, i, 2, t2); + DECOMP_5(p, i, 3, t3); + DECOMP_5(p, i, 4, t4); + DECOMP_5(p, i, 5, t5); + DECOMP_5(p, i, 6, t6); + DECOMP_5(p, i, 7, t7); + #endif + } +} + +/* Decompress the byte array of packed 5 bits into polynomial. + * + * FIPS 203, Section 4.2.1, Compression and decompression + * + * @param [out] p Polynomial. + * @param [in] b Array of bytes. + */ +void mlkem_decompress_5(sword16* p, const byte* b) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + mlkem_decompress_5_avx2(p, b); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_decompress_5_c(p, b); + } +} +#endif +#endif /* !WOLFSSL_MLKEM_NO_DECAPSULATE */ + +/******************************************************************************/ + +#if !(defined(__aarch64__) && defined(WOLFSSL_ARMASM)) +#if !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) || \ + !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) +/* Convert bit from byte to 0 or (MLKEM_Q + 1) / 2. + * + * Constant time implementation. + * XOR in mlkem_opt_blocker to ensure optimizer doesn't know what will be ANDed + * with MLKEM_Q_1_HALF and can't optimize to non-constant time code. + * + * FIPS 203, Algorithm 6: ByteDecode_d(B) + * + * @param [out] p Polynomial to hold converted value. + * @param [in] msg Message to get bit from byte from. + * @param [in] i Index of byte from message. + * @param [in] j Index of bit in byte. + */ +#define FROM_MSG_BIT(p, msg, i, j) \ + ((p)[8 * (i) + (j)] = (((sword16)0 - (sword16)(((msg)[i] >> (j)) & 1)) ^ \ + mlkem_opt_blocker) & MLKEM_Q_1_HALF) + +/* Convert message to polynomial. + * + * FIPS 203, Algorithm 6: ByteDecode_d(B) + * + * @param [out] p Polynomial. + * @param [in] msg Message as a byte array. + */ +static void mlkem_from_msg_c(sword16* p, const byte* msg) +{ + unsigned int i; + + /* For each byte of the message. */ + for (i = 0; i < MLKEM_N / 8; i++) { + #ifdef WOLFSSL_MLKEM_SMALL + unsigned int j; + /* For each bit of the message. */ + for (j = 0; j < 8; j++) { + FROM_MSG_BIT(p, msg, i, j); + } + #else + FROM_MSG_BIT(p, msg, i, 0); + FROM_MSG_BIT(p, msg, i, 1); + FROM_MSG_BIT(p, msg, i, 2); + FROM_MSG_BIT(p, msg, i, 3); + FROM_MSG_BIT(p, msg, i, 4); + FROM_MSG_BIT(p, msg, i, 5); + FROM_MSG_BIT(p, msg, i, 6); + FROM_MSG_BIT(p, msg, i, 7); + #endif + } +} + +/* Convert message to polynomial. + * + * FIPS 203, Algorithm 6: ByteDecode_d(B) + * + * @param [out] p Polynomial. + * @param [in] msg Message as a byte array. + */ +void mlkem_from_msg(sword16* p, const byte* msg) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + mlkem_from_msg_avx2(p, msg); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_from_msg_c(p, msg); + } +} +#endif + +#ifndef WOLFSSL_MLKEM_NO_DECAPSULATE +#ifdef CONV_WITH_DIV + +/* Convert to value to bit. + * + * Uses div operator that may be slow. + * + * FIPS 203, Algorithm 6: ByteEncode_d(F) + * + * @param [out] m Message. + * @param [in] p Polynomial. + * @param [in] i Index of byte in message. + * @param [in] j Index of bit in byte. + */ +#define TO_MSG_BIT(m, p, i, j) \ + m[i] |= (((((sword16)p[8 * i + j] << 1) + MLKEM_Q_HALF) / MLKEM_Q) & 1) << j + +#else + +/* Multiplier that does div q. */ +#define MLKEM_V31 (((1U << 31) + (MLKEM_Q / 2)) / MLKEM_Q) +/* 2 * multiplier that does div q. Only need bit 32 of result. */ +#define MLKEM_V31_2 ((word32)(MLKEM_V31 * 2)) +/* Multiplier times half of q. */ +#define MLKEM_V31_HALF ((word32)(MLKEM_V31 * MLKEM_Q_HALF)) + +/* Convert to value to bit. + * + * Uses mul instead of div. + * + * FIPS 203, Algorithm 6: ByteEncode_d(F) + * + * @param [out] m Message. + * @param [in] p Polynomial. + * @param [in] i Index of byte in message. + * @param [in] j Index of bit in byte. + */ +#define TO_MSG_BIT(m, p, i, j) \ + (m)[i] |= ((word32)((MLKEM_V31_2 * (p)[8 * (i) + (j)]) + \ + MLKEM_V31_HALF) >> 31) << (j) + +#endif /* CONV_WITH_DIV */ + +/* Convert polynomial to message. + * + * FIPS 203, Algorithm 6: ByteEncode_d(F) + * + * @param [out] msg Message as a byte array. + * @param [in] p Polynomial. + */ +static void mlkem_to_msg_c(byte* msg, sword16* p) +{ + unsigned int i; + + /* Reduce each coefficient to mod q. */ + mlkem_csubq_c(p); + /* All values are now in range. */ + + for (i = 0; i < MLKEM_N / 8; i++) { + #ifdef WOLFSSL_MLKEM_SMALL + unsigned int j; + msg[i] = 0; + for (j = 0; j < 8; j++) { + TO_MSG_BIT(msg, p, i, j); + } + #else + msg[i] = 0; + TO_MSG_BIT(msg, p, i, 0); + TO_MSG_BIT(msg, p, i, 1); + TO_MSG_BIT(msg, p, i, 2); + TO_MSG_BIT(msg, p, i, 3); + TO_MSG_BIT(msg, p, i, 4); + TO_MSG_BIT(msg, p, i, 5); + TO_MSG_BIT(msg, p, i, 6); + TO_MSG_BIT(msg, p, i, 7); + #endif + } +} + +/* Convert polynomial to message. + * + * FIPS 203, Algorithm 6: ByteEncode_d(F) + * + * @param [out] msg Message as a byte array. + * @param [in] p Polynomial. + */ +void mlkem_to_msg(byte* msg, sword16* p) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + /* Convert the polynomial into a array of bytes (message). */ + mlkem_to_msg_avx2(msg, p); + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_to_msg_c(msg, p); + } +} +#endif /* !WOLFSSL_MLKEM_NO_DECAPSULATE */ +#else +#if !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) || \ + !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) +/* Convert message to polynomial. + * + * FIPS 203, Algorithm 6: ByteDecode_d(B) + * + * @param [out] p Polynomial. + * @param [in] msg Message as a byte array. + */ +void mlkem_from_msg(sword16* p, const byte* msg) +{ + mlkem_from_msg_neon(p, msg); +} +#endif /* !WOLFSSL_MLKEM_NO_ENCAPSULATE || !WOLFSSL_MLKEM_NO_DECAPSULATE */ + +#ifndef WOLFSSL_MLKEM_NO_DECAPSULATE +/* Convert polynomial to message. + * + * FIPS 203, Algorithm 6: ByteEncode_d(F) + * + * @param [out] msg Message as a byte array. + * @param [in] p Polynomial. + */ +void mlkem_to_msg(byte* msg, sword16* p) +{ + mlkem_to_msg_neon(msg, p); +} +#endif /* WOLFSSL_MLKEM_NO_DECAPSULATE */ +#endif /* !(__aarch64__ && WOLFSSL_ARMASM) */ + +/******************************************************************************/ + +/* Convert bytes to polynomial. + * + * Consecutive 12 bits hold each coefficient of polynomial. + * Used in decoding private and public keys. + * + * FIPS 203, Algorithm 6: ByteDecode_d(B) + * + * @param [out] p Vector of polynomials. + * @param [in] b Array of bytes. + * @param [in] k Number of polynomials in vector. + */ +static void mlkem_from_bytes_c(sword16* p, const byte* b, int k) +{ + int i; + int j; + + for (j = 0; j < k; j++) { + for (i = 0; i < MLKEM_N / 2; i++) { + p[2 * i + 0] = ((b[3 * i + 0] >> 0) | + ((word16)b[3 * i + 1] << 8)) & 0xfff; + p[2 * i + 1] = ((b[3 * i + 1] >> 4) | + ((word16)b[3 * i + 2] << 4)) & 0xfff; + } + p += MLKEM_N; + b += WC_ML_KEM_POLY_SIZE; + } +} + +/* Convert bytes to polynomial. + * + * Consecutive 12 bits hold each coefficient of polynomial. + * Used in decoding private and public keys. + * + * FIPS 203, Algorithm 6: ByteDecode_d(B) + * + * @param [out] p Vector of polynomials. + * @param [in] b Array of bytes. + * @param [in] k Number of polynomials in vector. + */ +void mlkem_from_bytes(sword16* p, const byte* b, int k) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + int i; + + for (i = 0; i < k; i++) { + mlkem_from_bytes_avx2(p, b); + p += MLKEM_N; + b += WC_ML_KEM_POLY_SIZE; + } + + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_from_bytes_c(p, b, k); + } +} + +/* Convert polynomial to bytes. + * + * Consecutive 12 bits hold each coefficient of polynomial. + * Used in encoding private and public keys. + * + * FIPS 203, Algorithm 6: ByteEncode_d(F) + * + * @param [out] b Array of bytes. + * @param [in] p Polynomial. + * @param [in] k Number of polynomials in vector. + */ +static void mlkem_to_bytes_c(byte* b, sword16* p, int k) +{ + int i; + int j; + + /* Reduce each coefficient to mod q. */ + mlkem_csubq_c(p); + /* All values are now positive. */ + + for (j = 0; j < k; j++) { + for (i = 0; i < MLKEM_N / 2; i++) { + word16 t0 = p[2 * i]; + word16 t1 = p[2 * i + 1]; + b[3 * i + 0] = (t0 >> 0); + b[3 * i + 1] = (t0 >> 8) | t1 << 4; + b[3 * i + 2] = (t1 >> 4); + } + p += MLKEM_N; + b += WC_ML_KEM_POLY_SIZE; + } +} + +/* Convert polynomial to bytes. + * + * Consecutive 12 bits hold each coefficient of polynomial. + * Used in encoding private and public keys. + * + * FIPS 203, Algorithm 6: ByteEncode_d(F) + * + * @param [out] b Array of bytes. + * @param [in] p Polynomial. + * @param [in] k Number of polynomials in vector. + */ +void mlkem_to_bytes(byte* b, sword16* p, int k) +{ +#ifdef USE_INTEL_SPEEDUP + if (IS_INTEL_AVX2(cpuid_flags) && (SAVE_VECTOR_REGISTERS2() == 0)) { + int i; + + for (i = 0; i < k; i++) { + mlkem_to_bytes_avx2(b, p); + p += MLKEM_N; + b += WC_ML_KEM_POLY_SIZE; + } + + RESTORE_VECTOR_REGISTERS(); + } + else +#endif + { + mlkem_to_bytes_c(b, p, k); + } +} + +#endif /* WOLFSSL_WC_MLKEM */ diff --git a/src/wolfcrypt/src/wc_pkcs11.c b/src/wolfcrypt/src/wc_pkcs11.c index b3df75c..efacd74 100644 --- a/src/wolfcrypt/src/wc_pkcs11.c +++ b/src/wolfcrypt/src/wc_pkcs11.c @@ -1,6 +1,6 @@ /* wc_pkcs11.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #ifdef HAVE_PKCS11 @@ -32,9 +28,7 @@ #endif #include -#include #include -#include #ifndef NO_RSA #include #endif diff --git a/src/wolfcrypt/src/wc_port.c b/src/wolfcrypt/src/wc_port.c index 2ee85e3..a757852 100644 --- a/src/wolfcrypt/src/wc_port.c +++ b/src/wolfcrypt/src/wc_port.c @@ -1,6 +1,6 @@ /* port.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,20 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif +#include #ifdef __APPLE__ #include #endif -#include -#include -#include -#include -#include #ifdef HAVE_ECC #include #endif @@ -658,11 +650,13 @@ int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name) if (name) *name = NULL; + if (ctx != NULL) + XMEMSET(ctx, 0, sizeof(ReadDirCtx)); + if (ctx == NULL || path == NULL) { return BAD_FUNC_ARG; } - XMEMSET(ctx, 0, sizeof(ReadDirCtx)); pathLen = (int)XSTRLEN(path); #ifdef USE_WINDOWS_API @@ -1041,6 +1035,15 @@ int z_fs_close(XFILE file) return ret; } +/* Rewind the file pointer to the beginning of the file */ +/* This is not a 'rewind' is not supported in Zephyr so */ +/* use fs_seek to move the file pointer to the beginning of the file */ +/* calling it z_fs_rewind to avoid future conflicts if rewind is added */ +int z_fs_rewind(XFILE file) +{ + return fs_seek(file, 0, FS_SEEK_SET); +} + #endif /* !NO_FILESYSTEM && !WOLFSSL_ZEPHYR */ #if !defined(WOLFSSL_USER_MUTEX) @@ -1657,6 +1660,99 @@ int wolfSSL_HwPkMutexUnLock(void) return 0; } +#elif defined(__WATCOMC__) + + int wc_InitMutex(wolfSSL_Mutex* m) + { + #ifdef __OS2__ + DosCreateMutexSem( NULL, m, 0, FALSE ); + #elif defined(__NT__) + InitializeCriticalSection(m); + #elif defined(__LINUX__) + if (pthread_mutex_init(m, NULL) ) + return BAD_MUTEX_E; + #endif + return 0; + } + + int wc_FreeMutex(wolfSSL_Mutex* m) + { + #ifdef __OS2__ + DosCloseMutexSem(*m); + #elif defined(__NT__) + DeleteCriticalSection(m); + #elif defined(__LINUX__) + if (pthread_mutex_destroy(m) ) + return BAD_MUTEX_E; + #endif + return 0; + } + + int wc_LockMutex(wolfSSL_Mutex* m) + { + #ifdef __OS2__ + DosRequestMutexSem(*m, SEM_INDEFINITE_WAIT); + #elif defined(__NT__) + EnterCriticalSection(m); + #elif defined(__LINUX__) + if (pthread_mutex_lock(m) ) + return BAD_MUTEX_E; + #endif + return 0; + } + + int wc_UnLockMutex(wolfSSL_Mutex* m) + { + #ifdef __OS2__ + DosReleaseMutexSem(*m); + #elif defined(__NT__) + LeaveCriticalSection(m); + #elif defined(__LINUX__) + if (pthread_mutex_unlock(m) ) + return BAD_MUTEX_E; + #endif + return 0; + } + + #if defined(WOLFSSL_USE_RWLOCK) && defined(__LINUX__) + + int wc_InitRwLock(wolfSSL_RwLock* m) + { + if (pthread_rwlock_init(m, NULL) ) + return BAD_MUTEX_E; + return 0; + } + + int wc_FreeRwLock(wolfSSL_RwLock* m) + { + if (pthread_rwlock_destroy(m) ) + return BAD_MUTEX_E; + return 0; + } + + int wc_LockRwLock_Wr(wolfSSL_RwLock* m) + { + if (pthread_rwlock_wrlock(m) ) + return BAD_MUTEX_E; + return 0; + } + + int wc_LockRwLock_Rd(wolfSSL_RwLock* m) + { + if (pthread_rwlock_rdlock(m) ) + return BAD_MUTEX_E; + return 0; + } + + int wc_UnLockRwLock(wolfSSL_RwLock* m) + { + if (pthread_rwlock_unlock(m) == 0) + return BAD_MUTEX_E; + return 0; + } + + #endif + #elif defined(FREERTOS) || defined(FREERTOS_TCP) || \ defined(FREESCALE_FREE_RTOS) @@ -2422,6 +2518,10 @@ int wolfSSL_HwPkMutexUnLock(void) int wc_InitMutex(wolfSSL_Mutex* m) { + #if (defined(HAVE_FIPS) && FIPS_VERSION_EQ(5,2)) + if (wolfCrypt_GetMode_fips() == FIPS_MODE_INIT) + return 0; + #endif if (_mutex_init(m, NULL) == MQX_EOK) return 0; else @@ -2438,6 +2538,13 @@ int wolfSSL_HwPkMutexUnLock(void) int wc_LockMutex(wolfSSL_Mutex* m) { + #if (defined(HAVE_FIPS) && FIPS_VERSION_EQ(5,2)) + if (m->VALID != MUTEX_VALID) { + if (_mutex_init(m, NULL) != MQX_EOK) + return BAD_MUTEX_E; + } + #endif + if (_mutex_lock(m) == MQX_EOK) return 0; else @@ -2446,6 +2553,13 @@ int wolfSSL_HwPkMutexUnLock(void) int wc_UnLockMutex(wolfSSL_Mutex* m) { + #if (defined(HAVE_FIPS) && FIPS_VERSION_EQ(5,2)) + if (m->VALID != MUTEX_VALID) { + if (_mutex_init(m, NULL) != MQX_EOK) + return BAD_MUTEX_E; + } + #endif + if (_mutex_unlock(m) == MQX_EOK) return 0; else @@ -2710,7 +2824,9 @@ int wolfSSL_HwPkMutexUnLock(void) #elif defined(WOLFSSL_CMSIS_RTOS) - #define CMSIS_NMUTEX 10 + #ifndef CMSIS_NMUTEX + #define CMSIS_NMUTEX 10 + #endif osMutexDef(wolfSSL_mt0); osMutexDef(wolfSSL_mt1); osMutexDef(wolfSSL_mt2); osMutexDef(wolfSSL_mt3); osMutexDef(wolfSSL_mt4); osMutexDef(wolfSSL_mt5); osMutexDef(wolfSSL_mt6); osMutexDef(wolfSSL_mt7); osMutexDef(wolfSSL_mt8); @@ -2726,6 +2842,11 @@ int wolfSSL_HwPkMutexUnLock(void) int wc_InitMutex(wolfSSL_Mutex* m) { int i; + + if(!osKernelRunning()) { + return 0; + } + for (i=0; imutex, 0, FALSE ); + DosCreateEventSem( NULL, &cond->cond, DCE_POSTONE, FALSE ); + #elif defined(__NT__) + cond->cond = CreateEventA(NULL, FALSE, FALSE, NULL); + if (cond->cond == NULL) + return MEMORY_E; + + if (wc_InitMutex(&cond->mutex) != 0) { + if (CloseHandle(cond->cond) == 0) + return MEMORY_E; + return MEMORY_E; + } + #elif defined(__LINUX__) + if (pthread_mutex_init(&cond->mutex, NULL) != 0) + return MEMORY_E; + + if (pthread_cond_init(&cond->cond, NULL) != 0) { + /* Keep compilers happy that we are using the return code */ + if (pthread_mutex_destroy(&cond->mutex) != 0) + return MEMORY_E; + return MEMORY_E; + } + #endif + return 0; + } + + int wolfSSL_CondFree(COND_TYPE* cond) + { + if (cond == NULL) + return BAD_FUNC_ARG; + #if defined(__OS2__) + DosCloseMutexSem(cond->mutex); + DosCloseEventSem(cond->cond); + #elif defined(__NT__) + if (CloseHandle(cond->cond) == 0) + return MEMORY_E; + #elif defined(__LINUX__) + if (pthread_mutex_destroy(&cond->mutex) != 0) + return MEMORY_E; + + if (pthread_cond_destroy(&cond->cond) != 0) + return MEMORY_E; + #endif + return 0; + } + + int wolfSSL_CondStart(COND_TYPE* cond) + { + if (cond == NULL) + return BAD_FUNC_ARG; + #if defined(__OS2__) + #elif defined(__NT__) + if (wc_LockMutex(&cond->mutex) != 0) + return BAD_MUTEX_E; + #elif defined(__LINUX__) + if (pthread_mutex_lock(&cond->mutex) != 0) + return BAD_MUTEX_E; + #endif + return 0; + } + + int wolfSSL_CondSignal(COND_TYPE* cond) + { + if (cond == NULL) + return BAD_FUNC_ARG; + #if defined(__OS2__) + #elif defined(__NT__) + if (wc_UnLockMutex(&cond->mutex) != 0) + return BAD_MUTEX_E; + + if (SetEvent(cond->cond) == 0) + return MEMORY_E; + + if (wc_LockMutex(&cond->mutex) != 0) + return BAD_MUTEX_E; + #elif defined(__LINUX__) + if (pthread_cond_signal(&cond->cond) != 0) + return MEMORY_E; + #endif + return 0; + } + + int wolfSSL_CondWait(COND_TYPE* cond) + { + if (cond == NULL) + return BAD_FUNC_ARG; + #if defined(__OS2__) + #elif defined(__NT__) + if (wc_UnLockMutex(&cond->mutex) != 0) + return BAD_MUTEX_E; + + if (WaitForSingleObject(cond->cond, INFINITE) == WAIT_FAILED) + return MEMORY_E; + + if (wc_LockMutex(&cond->mutex) != 0) + return BAD_MUTEX_E; + #elif defined(__LINUX__) + if (pthread_cond_wait(&cond->cond, &cond->mutex) != 0) + return MEMORY_E; + #endif + return 0; + } + + int wolfSSL_CondEnd(COND_TYPE* cond) + { + if (cond == NULL) + return BAD_FUNC_ARG; + #if defined(__OS2__) + #elif defined(__NT__) + if (wc_UnLockMutex(&cond->mutex) != 0) + return BAD_MUTEX_E; + #elif defined(__LINUX__) + if (pthread_mutex_unlock(&cond->mutex) != 0) + return BAD_MUTEX_E; + #endif + return 0; + } + #endif /* WOLFSSL_COND */ + + +#elif defined(USE_WINDOWS_API) && !defined(WOLFSSL_PTHREADS) && \ !defined(_WIN32_WCE) int wolfSSL_NewThread(THREAD_TYPE* thread, THREAD_CB cb, void* arg) diff --git a/src/wolfcrypt/src/wc_xmss.c b/src/wolfcrypt/src/wc_xmss.c index 6546597..51b308b 100644 --- a/src/wolfcrypt/src/wc_xmss.c +++ b/src/wolfcrypt/src/wc_xmss.c @@ -1,6 +1,6 @@ /* wc_xmss.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,13 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include -#include -#include +#include #ifdef WOLFSSL_HAVE_XMSS #include diff --git a/src/wolfcrypt/src/wc_xmss_impl.c b/src/wolfcrypt/src/wc_xmss_impl.c index 80ca967..15b2184 100644 --- a/src/wolfcrypt/src/wc_xmss_impl.c +++ b/src/wolfcrypt/src/wc_xmss_impl.c @@ -1,6 +1,6 @@ /* wc_xmss_impl.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -29,13 +29,7 @@ * (https://ece.engr.uvic.ca/~raltawy/SAC2021/9.pdf) */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include -#include -#include +#include #include #include @@ -2653,6 +2647,9 @@ static int wc_xmss_bds_state_alloc(const XmssParams* params, BdsState** bds) if (*bds == NULL) { ret = MEMORY_E; } + else { + XMEMSET(*bds, 0, sizeof(BdsState) * cnt); + } } return ret; @@ -2675,7 +2672,7 @@ static void wc_xmss_bds_state_free(BdsState* bds) * @param [out] bds BDS states. * @param [out] wots_sigs WOTS signatures when XMSS^MT. */ -static void wc_xmss_bds_state_load(const XmssState* state, byte* sk, +static int wc_xmss_bds_state_load(const XmssState* state, byte* sk, BdsState* bds, byte** wots_sigs) { const XmssParams* params = state->params; @@ -2689,6 +2686,9 @@ static void wc_xmss_bds_state_load(const XmssState* state, byte* sk, /* Skip past standard SK = idx || wots_sk || SK_PRF || root || SEED; */ sk += params->idx_len + 4 * n; + if (2 * (int)params->d - 1 <= 0) + return WC_FAILURE; + for (i = 0; i < 2 * (int)params->d - 1; i++) { /* Set pointers into SK. */ bds[i].stack = sk; @@ -2715,6 +2715,8 @@ static void wc_xmss_bds_state_load(const XmssState* state, byte* sk, if (wots_sigs != NULL) { *wots_sigs = sk; } + + return 0; } /* Store the BDS state into the secret/private key. @@ -2723,7 +2725,7 @@ static void wc_xmss_bds_state_load(const XmssState* state, byte* sk, * @param [in, out] sk Secret/private key. * @param [in] bds BDS states. */ -static void wc_xmss_bds_state_store(const XmssState* state, byte* sk, +static int wc_xmss_bds_state_store(const XmssState* state, byte* sk, BdsState* bds) { int i; @@ -2743,15 +2745,20 @@ static void wc_xmss_bds_state_store(const XmssState* state, byte* sk, /* Ignore standard SK = idx || wots_sk || SK_PRF || root || SEED; */ sk += params->idx_len + 4 * n; + if (2 * (int)params->d - 1 <= 0) + return WC_FAILURE; + for (i = 0; i < 2 * (int)params->d - 1; i++) { /* Skip pointers into sk. */ sk += skip; /* Save values - big-endian encoded. */ - c32to24(bds[i].next, sk); + c32to24(bds[i].next, sk); /* NOLINT(clang-analyzer-core.CallAndMessage) */ sk += 3; sk[0] = bds[i].offset; sk += 1; } + + return 0; } /******************************************** @@ -2821,6 +2828,10 @@ static void wc_xmss_bds_next_idx(XmssState* state, BdsState* bds, /* HDSS, Section 4.5, 1: AUTH[h] = v[h][1], h = 0,...,H-1. * Cache left node if on authentication path. */ if ((i >> h) == 1) { + if (bds->authPath == NULL) { + state->ret = WC_FAILURE; + return; + } XMEMCPY(bds->authPath + h * n, node, n); } /* This is a right node. */ @@ -2900,8 +2911,10 @@ static void wc_xmss_bds_treehash_initial(XmssState* state, BdsState* bds, bds->offset = 0; bds->next = 0; /* Reset the hash tree status. */ - for (i = 0; i < hsk; i++) { - wc_xmss_bds_state_treehash_init(bds, i); + if (bds->treeHash != NULL) { + for (i = 0; i < hsk; i++) { + wc_xmss_bds_state_treehash_init(bds, i); + } } /* Copy hash address into local. */ @@ -3036,6 +3049,11 @@ static word8 wc_xmss_bds_treehash_updates(XmssState* state, BdsState* bds, const word8 hs = params->sub_h; const word8 hsk = params->sub_h - params->bds_k; + if (bds->treeHash == NULL) { + state->ret = WC_FAILURE; + return 0; + } + while (updates > 0) { word8 minH = hs; word8 h = hsk; @@ -3106,6 +3124,10 @@ static void wc_xmss_bds_update(XmssState* state, BdsState* bds, HashAddress addrCopy; XMSS_ADDR_OTS_SET_SUBTREE(addrCopy, addr); + if (bds->height == NULL) { + state->ret = WC_FAILURE; + return; + } wc_xmss_bds_next_idx(state, bds, sk_seed, pk_seed, addrCopy, bds->next, bds->height, &bds->offset, &sp); bds->offset++; @@ -3162,6 +3184,11 @@ static void wc_xmss_bds_auth_path(XmssState* state, BdsState* bds, byte* node = state->encMsg; word8 parent; + if ((bds->keep == NULL) || (bds->authPath == NULL)) { + state->ret = WC_FAILURE; + return; + } + /* Step 1. Find the height of first left node in authentication path. */ tau = wc_xmss_lowest_zero_bit_index(leafIdx, hs, &parent); if (tau == 0) { @@ -3297,6 +3324,10 @@ int wc_xmss_keygen(XmssState* state, const unsigned char* seed, if (ret == 0) #endif { + /* Setup pointers into sk - assumes sk is initialized to zeros. */ + ret = wc_xmss_bds_state_load(state, sk, bds, NULL); + } + if (ret == 0) { /* Offsets into seed. */ const byte* seed_priv = seed; const byte* seed_pub = seed + 2 * n; @@ -3306,9 +3337,6 @@ int wc_xmss_keygen(XmssState* state, const unsigned char* seed, /* Offsets into public key. */ byte* pk_seed = pk + n; - /* Setup pointers into sk - assumes sk is initialized to zeros. */ - wc_xmss_bds_state_load(state, sk, bds, NULL); - /* Set first index to 0 in private key. idx_len always 4. */ *sk_idx = 0; /* Set private key seed and private key for PRF in to private key. */ @@ -3333,7 +3361,7 @@ int wc_xmss_keygen(XmssState* state, const unsigned char* seed, XMEMCPY(sk_root, pk_root, 2 * n); /* Store BDS state back into secret/private key. */ - wc_xmss_bds_state_store(state, sk, bds); + ret = wc_xmss_bds_state_store(state, sk, bds); } #ifdef WOLFSSL_SMALL_STACK @@ -3412,8 +3440,9 @@ int wc_xmss_sign(XmssState* state, const unsigned char* m, word32 mlen, #endif { /* Load the BDS state from secret/private key. */ - wc_xmss_bds_state_load(state, sk, bds, NULL); - + ret = wc_xmss_bds_state_load(state, sk, bds, NULL); + } + if (ret == 0) { /* Copy the index into the signature data: Sig = idx_sig || ... */ *((word32*)sig) = *((word32*)sk); /* Read index from the secret key. */ @@ -3490,7 +3519,7 @@ int wc_xmss_sign(XmssState* state, const unsigned char* m, word32 mlen, } if (ret == 0) { /* Store BDS state back into secret/private key. */ - wc_xmss_bds_state_store(state, sk, bds); + ret = wc_xmss_bds_state_store(state, sk, bds); } #ifdef WOLFSSL_SMALL_STACK @@ -3580,14 +3609,15 @@ int wc_xmssmt_keygen(XmssState* state, const unsigned char* seed, /* Allocate memory for BDS states and tree hash instances. */ ret = wc_xmss_bds_state_alloc(params, &bds); + if (ret == 0) { + /* Load the BDS state from secret/private key. */ + ret = wc_xmss_bds_state_load(state, sk, bds, &wots_sigs); + } if (ret == 0) { /* Offsets into seed. */ const byte* seed_priv = seed; const byte* seed_pub = seed + 2 * params->n; - /* Load the BDS state from secret/private key. */ - wc_xmss_bds_state_load(state, sk, bds, &wots_sigs); - /* Set first index to 0 in private key. */ XMEMSET(sk, 0, params->idx_len); /* Set private key seed and private key for PRF in to private key. */ @@ -3630,7 +3660,7 @@ int wc_xmssmt_keygen(XmssState* state, const unsigned char* seed, XMEMCPY(sk_root, pk_root, 2 * n); /* Store BDS state back into secret/private key. */ - wc_xmss_bds_state_store(state, sk, bds); + ret = wc_xmss_bds_state_store(state, sk, bds); } /* Dispose of allocated data of BDS states. */ @@ -3825,10 +3855,16 @@ static int wc_xmssmt_sign_msg(XmssState* state, BdsState* bds, XmssIdx idx, } if (ret == 0) { word8 i; + byte *authPath; sig += params->wots_sig_len; /* Add authentication path. */ - XMEMCPY(sig, bds[BDS_IDX(idx, 0, hs, params->d)].authPath, hs * n); + authPath = bds[BDS_IDX(idx, 0, hs, params->d)].authPath; + if (authPath == NULL) { + state->ret = WC_FAILURE; + return state->ret; + } + XMEMCPY(sig, authPath, hs * n); sig += hs * n; /* Remaining iterations from storage. */ @@ -3838,7 +3874,12 @@ static int wc_xmssmt_sign_msg(XmssState* state, BdsState* bds, XmssIdx idx, params->wots_sig_len); sig += params->wots_sig_len; /* Add authentication path (auth) and calc new root. */ - XMEMCPY(sig, bds[BDS_IDX(idx, i, hs, params->d)].authPath, hs * n); + authPath = bds[BDS_IDX(idx, i, hs, params->d)].authPath; + if (authPath == NULL) { + state->ret = WC_FAILURE; + return state->ret; + } + XMEMCPY(sig, authPath, hs * n); sig += hs * n; } ret = state->ret; @@ -4000,8 +4041,9 @@ int wc_xmssmt_sign(XmssState* state, const unsigned char* m, word32 mlen, ret = wc_xmss_bds_state_alloc(params, &bds); if (ret == 0) { /* Load the BDS state from secret/private key. */ - wc_xmss_bds_state_load(state, sk, bds, &wots_sigs); - + ret = wc_xmss_bds_state_load(state, sk, bds, &wots_sigs); + } + if (ret == 0) { /* Copy the index into the signature data: Sig_MT = idx_sig. */ XMEMCPY(sig_mt, sk, idx_len); @@ -4032,7 +4074,7 @@ int wc_xmssmt_sign(XmssState* state, const unsigned char* m, word32 mlen, if (ret == 0) { /* Store BDS state back into secret/private key. */ - wc_xmss_bds_state_store(state, sk, bds); + ret = wc_xmss_bds_state_store(state, sk, bds); } /* Dispose of allocated data of BDS states. */ diff --git a/src/wolfcrypt/src/wolfevent.c b/src/wolfcrypt/src/wolfevent.c index bf155c1..34d5740 100644 --- a/src/wolfcrypt/src/wolfevent.c +++ b/src/wolfcrypt/src/wolfevent.c @@ -1,6 +1,6 @@ /* wolfevent.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,18 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif - -#include - +#include #ifdef HAVE_WOLF_EVENT #include #include -#include #include diff --git a/src/wolfcrypt/src/wolfmath.c b/src/wolfcrypt/src/wolfmath.c index 9a6e312..9f14d01 100644 --- a/src/wolfcrypt/src/wolfmath.c +++ b/src/wolfcrypt/src/wolfmath.c @@ -1,6 +1,6 @@ /* wolfmath.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -26,15 +26,9 @@ * NO_BIG_INT: Disable support for all multi-precision math libraries */ -#ifdef HAVE_CONFIG_H - #include -#endif +#include -/* in case user set USE_FAST_MATH there */ -#include #include -#include -#include #ifdef WOLFSSL_ASYNC_CRYPT #include diff --git a/src/wolfssl-arduino.cpp b/src/wolfssl-arduino.cpp new file mode 100644 index 0000000..3d3c787 --- /dev/null +++ b/src/wolfssl-arduino.cpp @@ -0,0 +1,33 @@ +/* wolfssl-arduino.cpp + * + * 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 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include "wolfssl.h" + +/* Function to allow wolfcrypt to use Arduino Serial.print for debug messages. + * See wolfssl/wolfcrypt/logging.c */ + +int wolfSSL_Arduino_Serial_Print(const char* const s) +{ + /* Reminder: Serial.print is only available in C++ */ + Serial.println(F(s)); + return 0; +}; diff --git a/src/wolfssl.h b/src/wolfssl.h index c7e39d4..8b29806 100644 --- a/src/wolfssl.h +++ b/src/wolfssl.h @@ -1,6 +1,6 @@ /* wolfssl.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -22,6 +22,7 @@ /* Edit with caution. This is an Arduino-library specific header for wolfSSL */ #ifndef WOLFSSL_USER_SETTINGS + /* Should already be defined in settings.h for #if defined(ARDUINO) */ #define WOLFSSL_USER_SETTINGS #endif @@ -39,9 +40,10 @@ #include #include -int wolfSSL_Arduino_Serial_Print(const char *const s) -{ - /* See wolfssl/wolfcrypt/logging.c */ - Serial.println(F(s)); - return 0; -}; +#ifndef WOLFSSL_ARDUINO_H +#define WOLFSSL_ARDUINO_H + +/* Declare a helper function to be used in wolfssl/wolfcrypt/logging.c */ +int wolfSSL_Arduino_Serial_Print(const char* const s); + +#endif /* WOLFSSL_ARDUINO_H */ diff --git a/src/wolfssl/bio.c b/src/wolfssl/bio.c index b265456..0b52a6c 100644 --- a/src/wolfssl/bio.c +++ b/src/wolfssl/bio.c @@ -1,6 +1,6 @@ /* bio.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,11 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ -#ifdef HAVE_CONFIG_H - #include -#endif +#include -#include #if defined(OPENSSL_EXTRA) && !defined(_WIN32) && !defined(_GNU_SOURCE) /* turn on GNU extensions for XVASPRINTF with wolfSSL_BIO_printf */ #define _GNU_SOURCE 1 @@ -142,7 +139,7 @@ static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len) return WOLFSSL_BIO_ERROR; } - XMEMCPY(buf, bio->mem_buf->data + bio->rdIdx, sz); + XMEMCPY(buf, bio->mem_buf->data + bio->rdIdx, (size_t)sz); bio->rdIdx += sz; if (bio->rdIdx >= bio->wrSz) { @@ -167,14 +164,14 @@ static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len) /* Resize the memory so we are not taking up more than necessary. * memmove reverts internally to memcpy if areas don't overlap */ XMEMMOVE(bio->mem_buf->data, bio->mem_buf->data + bio->rdIdx, - bio->wrSz - bio->rdIdx); + (long unsigned int)bio->wrSz - (size_t)bio->rdIdx); bio->wrSz -= bio->rdIdx; bio->rdIdx = 0; /* Resize down to WOLFSSL_BIO_RESIZE_THRESHOLD for fewer * allocations. */ if (wolfSSL_BUF_MEM_resize(bio->mem_buf, - bio->wrSz > WOLFSSL_BIO_RESIZE_THRESHOLD ? bio->wrSz : - WOLFSSL_BIO_RESIZE_THRESHOLD) == 0) { + bio->wrSz > WOLFSSL_BIO_RESIZE_THRESHOLD ? + (size_t)bio->wrSz : WOLFSSL_BIO_RESIZE_THRESHOLD) == 0) { WOLFSSL_MSG("wolfSSL_BUF_MEM_resize error"); return WOLFSSL_BIO_ERROR; } @@ -389,6 +386,10 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) #endif break; + case WOLFSSL_BIO_NULL: + ret = 0; + break; + } /* switch */ } @@ -564,7 +565,7 @@ static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data, WOLFSSL_MSG("Error in wolfSSL_BIO_nwrite"); return sz1; } - XMEMCPY(buf, data, sz1); + XMEMCPY(buf, data, (size_t)sz1); data = (char*)data + sz1; len -= sz1; @@ -572,7 +573,7 @@ static int wolfSSL_BIO_BIO_write(WOLFSSL_BIO* bio, const void* data, /* try again to see if maybe we wrapped around the ring buffer */ sz2 = wolfSSL_BIO_nwrite(bio, &buf, len); if (sz2 > 0) { - XMEMCPY(buf, data, sz2); + XMEMCPY(buf, data, (size_t)sz2); sz1 += sz2; if (len > sz2) bio->flags |= WOLFSSL_BIO_FLAG_WRITE|WOLFSSL_BIO_FLAG_RETRY; @@ -610,8 +611,8 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data, if (len == 0) return WOLFSSL_SUCCESS; /* Return early to make logic simpler */ - if (wolfSSL_BUF_MEM_grow_ex(bio->mem_buf, bio->wrSz + len, 0) - == 0) { + if (wolfSSL_BUF_MEM_grow_ex(bio->mem_buf, ((size_t)bio->wrSz) + + ((size_t)len), 0) == 0) { WOLFSSL_MSG("Error growing memory area"); return WOLFSSL_FAILURE; } @@ -621,7 +622,7 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data, return WOLFSSL_FAILURE; } - XMEMCPY(bio->mem_buf->data + bio->wrSz, data, len); + XMEMCPY(bio->mem_buf->data + bio->wrSz, data, (size_t)len); bio->ptr.mem_buf_data = (byte *)bio->mem_buf->data; bio->num.length = bio->mem_buf->max; bio->wrSz += len; @@ -813,6 +814,10 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) #endif break; + case WOLFSSL_BIO_NULL: + ret = len; + break; + } /* switch */ } @@ -1138,7 +1143,7 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz) ret = wolfSSL_BIO_nread(bio, &c, cSz); if (ret > 0 && ret < sz) { - XMEMCPY(buf, c, ret); + XMEMCPY(buf, c, (size_t)ret); } break; } @@ -1161,6 +1166,10 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz) break; #endif /* WOLFCRYPT_ONLY */ + case WOLFSSL_BIO_NULL: + ret = 0; + break; + default: WOLFSSL_MSG("BIO type not supported yet with wolfSSL_BIO_gets"); } @@ -1256,13 +1265,13 @@ size_t wolfSSL_BIO_wpending(const WOLFSSL_BIO *bio) return 0; if (bio->type == WOLFSSL_BIO_MEMORY) { - return bio->wrSz; + return (size_t)bio->wrSz; } /* type BIO_BIO then check paired buffer */ if (bio->type == WOLFSSL_BIO_BIO && bio->pair != NULL) { WOLFSSL_BIO* pair = bio->pair; - return pair->wrIdx; + return (size_t)pair->wrIdx; } return 0; @@ -1308,12 +1317,12 @@ size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio) #ifndef WOLFCRYPT_ONLY if (bio->type == WOLFSSL_BIO_SSL && bio->ptr.ssl != NULL) { - return (long)wolfSSL_pending(bio->ptr.ssl); + return (size_t)wolfSSL_pending(bio->ptr.ssl); } #endif if (bio->type == WOLFSSL_BIO_MEMORY) { - return bio->wrSz - bio->rdIdx; + return (size_t)(bio->wrSz - bio->rdIdx); } /* type BIO_BIO then check paired buffer */ @@ -1322,11 +1331,12 @@ size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio) if (pair->wrIdx > 0 && pair->wrIdx <= pair->rdIdx) { /* in wrap around state where beginning of buffer is being * overwritten */ - return pair->wrSz - pair->rdIdx + pair->wrIdx; + return ((size_t)pair->wrSz) - ((size_t)pair->rdIdx) + + ((size_t)pair->wrIdx); } else { /* simple case where has not wrapped around */ - return pair->wrIdx - pair->rdIdx; + return (size_t)(pair->wrIdx - pair->rdIdx); } } return 0; @@ -1423,7 +1433,7 @@ int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size) XFREE(bio->ptr.mem_buf_data, bio->heap, DYNAMIC_TYPE_OPENSSL); } - bio->ptr.mem_buf_data = (byte*)XMALLOC(size, bio->heap, + bio->ptr.mem_buf_data = (byte*)XMALLOC((size_t)size, bio->heap, DYNAMIC_TYPE_OPENSSL); if (bio->ptr.mem_buf_data == NULL) { WOLFSSL_MSG("Memory allocation error"); @@ -1439,7 +1449,7 @@ int wolfSSL_BIO_set_write_buf_size(WOLFSSL_BIO *bio, long size) return WOLFSSL_FAILURE; } bio->wrSz = (int)size; - bio->num.length = size; + bio->num.length = (size_t)size; bio->wrIdx = 0; bio->rdIdx = 0; if (bio->mem_buf != NULL) { @@ -1908,7 +1918,7 @@ long wolfSSL_BIO_set_mem_eof_return(WOLFSSL_BIO *bio, int v) int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio) { - int len; + int len = 0; #ifndef NO_FILESYSTEM long memSz = 0; XFILE file; @@ -2309,6 +2319,15 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) return &meth; } + WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_null(void) + { + static WOLFSSL_BIO_METHOD meth = + WOLFSSL_BIO_METHOD_INIT(WOLFSSL_BIO_NULL); + + WOLFSSL_ENTER("wolfSSL_BIO_s_null"); + + return &meth; + } WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void) { @@ -2353,7 +2372,6 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) WOLFSSL_ENTER("wolfSSL_BIO_new_dgram"); if (bio) { - bio->type = WOLFSSL_BIO_DGRAM; bio->shutdown = (byte)closeF; bio->num.fd = (SOCKET_T)fd; } @@ -2381,10 +2399,11 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) else port = str + XSTRLEN(str); /* point to null terminator */ - bio->ip = (char*)XMALLOC((port - str) + 1, /* +1 for null char */ + bio->ip = (char*)XMALLOC( + (size_t)(port - str) + 1, /* +1 for null char */ bio->heap, DYNAMIC_TYPE_OPENSSL); if (bio->ip != NULL) { - XMEMCPY(bio->ip, str, port - str); + XMEMCPY(bio->ip, str, (size_t)(port - str)); bio->ip[port - str] = '\0'; bio->type = WOLFSSL_BIO_SOCKET; } @@ -2770,9 +2789,23 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) } else { size_t currLen = XSTRLEN(b->ip); + #ifdef WOLFSSL_NO_REALLOC + char* tmp = NULL; + #endif + if (currLen != newLen) { + #ifdef WOLFSSL_NO_REALLOC + tmp = b->ip; + b->ip = (char*)XMALLOC(newLen+1, b->heap, DYNAMIC_TYPE_OPENSSL); + if (b->ip != NULL && tmp != NULL) { + XMEMCPY(b->ip, tmp, newLen); + XFREE(tmp, b->heap, DYNAMIC_TYPE_OPENSSL); + tmp = NULL; + } + #else b->ip = (char*)XREALLOC(b->ip, newLen + 1, b->heap, DYNAMIC_TYPE_OPENSSL); + #endif if (b->ip == NULL) { WOLFSSL_MSG("Hostname realloc failed."); return WOLFSSL_FAILURE; @@ -2926,7 +2959,7 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio) bio->wrSz = len; bio->ptr.mem_buf_data = (byte *)bio->mem_buf->data; if (len > 0 && bio->ptr.mem_buf_data != NULL) { - XMEMCPY(bio->ptr.mem_buf_data, buf, len); + XMEMCPY(bio->ptr.mem_buf_data, buf, (size_t)len); bio->flags |= WOLFSSL_BIO_FLAG_MEM_RDONLY; bio->wrSzReset = bio->wrSz; } @@ -3295,11 +3328,11 @@ int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args) count = XVSNPRINTF(NULL, 0, format, args); if (count >= 0) { - pt = (char*)XMALLOC(count + 1, bio->heap, + pt = (char*)XMALLOC((size_t)count + 1, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); if (pt != NULL) { - count = XVSNPRINTF(pt, count + 1, format, copy); + count = XVSNPRINTF(pt, (size_t)count + 1, format, copy); if (count >= 0) { ret = wolfSSL_BIO_write(bio, pt, count); @@ -3369,18 +3402,20 @@ int wolfSSL_BIO_dump(WOLFSSL_BIO *bio, const char *buf, int length) o = 7; for (i = 0; i < BIO_DUMP_LINE_LEN; i++) { if (i < length) - (void)XSNPRINTF(line + o, (int)sizeof(line) - o, + (void)XSNPRINTF(line + o, (size_t)((int)sizeof(line) - o), "%02x ", (unsigned char)buf[i]); else - (void)XSNPRINTF(line + o, (int)sizeof(line) - o, " "); + (void)XSNPRINTF(line + o, (size_t)((int)sizeof(line) - o), + " "); if (i == 7) - (void)XSNPRINTF(line + o + 2, (int)sizeof(line) - (o + 2), "-"); + (void)XSNPRINTF(line + o + 2, (size_t)((int)sizeof(line) - + (o + 2)), "-"); o += 3; } - (void)XSNPRINTF(line + o, (int)sizeof(line) - o, " "); + (void)XSNPRINTF(line + o, (size_t)((int)sizeof(line) - o), " "); o += 2; for (i = 0; (i < BIO_DUMP_LINE_LEN) && (i < length); i++) { - (void)XSNPRINTF(line + o, (int)sizeof(line) - o, "%c", + (void)XSNPRINTF(line + o, (size_t)((int)sizeof(line) - o), "%c", ((31 < buf[i]) && (buf[i] < 127)) ? buf[i] : '.'); o++; } diff --git a/src/wolfssl/callbacks.h b/src/wolfssl/callbacks.h index dc3ad89..a75e483 100644 --- a/src/wolfssl/callbacks.h +++ b/src/wolfssl/callbacks.h @@ -1,6 +1,6 @@ /* callbacks.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/crl.h b/src/wolfssl/crl.h index cdf52f3..56f5003 100644 --- a/src/wolfssl/crl.h +++ b/src/wolfssl/crl.h @@ -1,6 +1,6 @@ /* crl.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/error-ssl.h b/src/wolfssl/error-ssl.h index 2d4d802..bc3e641 100644 --- a/src/wolfssl/error-ssl.h +++ b/src/wolfssl/error-ssl.h @@ -1,6 +1,6 @@ /* error-ssl.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/evp.c b/src/wolfssl/evp.c index c3eb12e..7054f80 100644 --- a/src/wolfssl/evp.c +++ b/src/wolfssl/evp.c @@ -1,6 +1,6 @@ /* evp.c * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -19,12 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ - -#ifdef HAVE_CONFIG_H - #include -#endif - -#include +#include #if !defined(WOLFSSL_EVP_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN @@ -52,67 +47,67 @@ static const struct s_ent { const char *name; } md_tbl[] = { #ifndef NO_MD4 - {WC_HASH_TYPE_MD4, WC_NID_md4, "MD4"}, + {WC_HASH_TYPE_MD4, WC_NID_md4, WC_SN_md4}, #endif /* NO_MD4 */ #ifndef NO_MD5 - {WC_HASH_TYPE_MD5, WC_NID_md5, "MD5"}, + {WC_HASH_TYPE_MD5, WC_NID_md5, WC_SN_md5}, #endif /* NO_MD5 */ #ifndef NO_SHA - {WC_HASH_TYPE_SHA, WC_NID_sha1, "SHA1"}, + {WC_HASH_TYPE_SHA, WC_NID_sha1, WC_SN_sha1}, {WC_HASH_TYPE_SHA, WC_NID_sha1, "SHA"}, /* Leave for backwards compatibility */ #endif /* NO_SHA */ #ifdef WOLFSSL_SHA224 - {WC_HASH_TYPE_SHA224, WC_NID_sha224, "SHA224"}, + {WC_HASH_TYPE_SHA224, WC_NID_sha224, WC_SN_sha224}, #endif /* WOLFSSL_SHA224 */ #ifndef NO_SHA256 - {WC_HASH_TYPE_SHA256, WC_NID_sha256, "SHA256"}, + {WC_HASH_TYPE_SHA256, WC_NID_sha256, WC_SN_sha256}, #endif #ifdef WOLFSSL_SHA384 - {WC_HASH_TYPE_SHA384, WC_NID_sha384, "SHA384"}, + {WC_HASH_TYPE_SHA384, WC_NID_sha384, WC_SN_sha384}, #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA512 - {WC_HASH_TYPE_SHA512, WC_NID_sha512, "SHA512"}, + {WC_HASH_TYPE_SHA512, WC_NID_sha512, WC_SN_sha512}, #endif /* WOLFSSL_SHA512 */ #if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224) - {WC_HASH_TYPE_SHA512_224, WC_NID_sha512_224, "SHA512_224"}, + {WC_HASH_TYPE_SHA512_224, WC_NID_sha512_224, WC_SN_sha512_224}, #endif /* WOLFSSL_SHA512 && !WOLFSSL_NOSHA512_224 */ #if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256) - {WC_HASH_TYPE_SHA512_256, WC_NID_sha512_256, "SHA512_256"}, + {WC_HASH_TYPE_SHA512_256, WC_NID_sha512_256, WC_SN_sha512_256}, #endif /* WOLFSSL_SHA512 && !WOLFSSL_NOSHA512_256 */ #ifndef WOLFSSL_NOSHA3_224 - {WC_HASH_TYPE_SHA3_224, WC_NID_sha3_224, "SHA3_224"}, + {WC_HASH_TYPE_SHA3_224, WC_NID_sha3_224, WC_SN_sha3_224}, #endif #ifndef WOLFSSL_NOSHA3_256 - {WC_HASH_TYPE_SHA3_256, WC_NID_sha3_256, "SHA3_256"}, + {WC_HASH_TYPE_SHA3_256, WC_NID_sha3_256, WC_SN_sha3_256}, #endif #ifndef WOLFSSL_NOSHA3_384 - {WC_HASH_TYPE_SHA3_384, WC_NID_sha3_384, "SHA3_384"}, + {WC_HASH_TYPE_SHA3_384, WC_NID_sha3_384, WC_SN_sha3_384}, #endif #ifndef WOLFSSL_NOSHA3_512 - {WC_HASH_TYPE_SHA3_512, WC_NID_sha3_512, "SHA3_512"}, + {WC_HASH_TYPE_SHA3_512, WC_NID_sha3_512, WC_SN_sha3_512}, #endif #ifdef WOLFSSL_SM3 - {WC_HASH_TYPE_SM3, WC_NID_sm3, "SM3"}, + {WC_HASH_TYPE_SM3, WC_NID_sm3, WC_SN_sm3}, #endif /* WOLFSSL_SHA512 */ #ifdef HAVE_BLAKE2 - {WC_HASH_TYPE_BLAKE2B, WC_NID_blake2b512, "BLAKE2B512"}, + {WC_HASH_TYPE_BLAKE2B, WC_NID_blake2b512, WC_SN_blake2b512}, #endif #ifdef HAVE_BLAKE2S - {WC_HASH_TYPE_BLAKE2S, WC_NID_blake2s256, "BLAKE2S256"}, + {WC_HASH_TYPE_BLAKE2S, WC_NID_blake2s256, WC_SN_blake2s256}, #endif #ifdef WOLFSSL_SHAKE128 - {WC_HASH_TYPE_SHAKE128, WC_NID_shake128, "SHAKE128"}, + {WC_HASH_TYPE_SHAKE128, WC_NID_shake128, WC_SN_shake128}, #endif #ifdef WOLFSSL_SHAKE256 - {WC_HASH_TYPE_SHAKE256, WC_NID_shake256, "SHAKE256"}, + {WC_HASH_TYPE_SHAKE256, WC_NID_shake256, WC_SN_shake256}, #endif {WC_HASH_TYPE_NONE, 0, NULL} }; @@ -1059,6 +1054,14 @@ int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, } switch (ctx->cipherType) { + case WC_NULL_CIPHER_TYPE: + if (out == NULL) { + WOLFSSL_MSG("Bad argument"); + return WOLFSSL_FAILURE; + } + XMEMMOVE(out, in, inl); + *outl = inl; + return WOLFSSL_SUCCESS; #if !defined(NO_AES) && defined(HAVE_AESGCM) case WC_AES_128_GCM_TYPE: case WC_AES_192_GCM_TYPE: @@ -2046,6 +2049,165 @@ static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher) else return 0; } +/* Getter function for cipher type string + * + * cipherType cipherType enum value to get string for + * + * Returns string representation of the cipher type or NULL if not found + */ +const char* wolfSSL_EVP_CIPHER_type_string(unsigned int cipherType) +{ + WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_type_string"); + + switch (cipherType) { +#ifndef NO_DES3 + case WC_DES_CBC_TYPE: return EVP_DES_CBC; + case WC_DES_EDE3_CBC_TYPE: return EVP_DES_EDE3_CBC; + case WC_DES_ECB_TYPE: return EVP_DES_ECB; + case WC_DES_EDE3_ECB_TYPE: return EVP_DES_EDE3_ECB; +#endif +#if !defined(NO_AES) + #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_CBC_TYPE: return EVP_AES_128_CBC; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_CBC_TYPE: return EVP_AES_192_CBC; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_CBC_TYPE: return EVP_AES_256_CBC; + #endif + #endif /* HAVE_AES_CBC || WOLFSSL_AES_DIRECT */ + #if defined(WOLFSSL_AES_CFB) + #ifndef WOLFSSL_NO_AES_CFB_1_8 + #ifdef WOLFSSL_AES_128 + case WC_AES_128_CFB1_TYPE: return EVP_AES_128_CFB1; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_CFB1_TYPE: return EVP_AES_192_CFB1; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_CFB1_TYPE: return EVP_AES_256_CFB1; + #endif + #ifdef WOLFSSL_AES_128 + case WC_AES_128_CFB8_TYPE: return EVP_AES_128_CFB8; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_CFB8_TYPE: return EVP_AES_192_CFB8; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_CFB8_TYPE: return EVP_AES_256_CFB8; + #endif + #endif /* !WOLFSSL_NO_AES_CFB_1_8 */ + #ifdef WOLFSSL_AES_128 + case WC_AES_128_CFB128_TYPE: return EVP_AES_128_CFB128; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_CFB128_TYPE: return EVP_AES_192_CFB128; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_CFB128_TYPE: return EVP_AES_256_CFB128; + #endif + #endif /* WOLFSSL_AES_CFB */ + #if defined(WOLFSSL_AES_OFB) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_OFB_TYPE: return EVP_AES_128_OFB; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_OFB_TYPE: return EVP_AES_192_OFB; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_OFB_TYPE: return EVP_AES_256_OFB; + #endif + #endif /* WOLFSSL_AES_OFB */ + #if defined(WOLFSSL_AES_XTS) && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_XTS_TYPE: return EVP_AES_128_XTS; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_XTS_TYPE: return EVP_AES_256_XTS; + #endif + #endif /* WOLFSSL_AES_XTS && (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) */ + #if defined(HAVE_AESGCM) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_GCM_TYPE: return EVP_AES_128_GCM; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_GCM_TYPE: return EVP_AES_192_GCM; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_GCM_TYPE: return EVP_AES_256_GCM; + #endif + #endif /* HAVE_AESGCM */ + #if defined(HAVE_AESCCM) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_CCM_TYPE: return EVP_AES_128_CCM; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_CCM_TYPE: return EVP_AES_192_CCM; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_CCM_TYPE: return EVP_AES_256_CCM; + #endif + #endif /* HAVE_AESCCM */ + #if defined(WOLFSSL_AES_COUNTER) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_CTR_TYPE: return EVP_AES_128_CTR; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_CTR_TYPE: return EVP_AES_192_CTR; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_CTR_TYPE: return EVP_AES_256_CTR; + #endif + #endif /* WOLFSSL_AES_COUNTER */ + #if defined(HAVE_AES_ECB) + #ifdef WOLFSSL_AES_128 + case WC_AES_128_ECB_TYPE: return EVP_AES_128_ECB; + #endif + #ifdef WOLFSSL_AES_192 + case WC_AES_192_ECB_TYPE: return EVP_AES_192_ECB; + #endif + #ifdef WOLFSSL_AES_256 + case WC_AES_256_ECB_TYPE: return EVP_AES_256_ECB; + #endif + #endif /* HAVE_AES_ECB */ +#endif /* !NO_AES */ +#if defined(HAVE_ARIA) + case WC_ARIA_128_GCM_TYPE: return EVP_ARIA_128_GCM; + case WC_ARIA_192_GCM_TYPE: return EVP_ARIA_192_GCM; + case WC_ARIA_256_GCM_TYPE: return EVP_ARIA_256_GCM; +#endif /* HAVE_ARIA */ +#ifndef NO_RC4 + case WC_ARC4_TYPE: return EVP_ARC4; +#endif +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) + case WC_CHACHA20_POLY1305_TYPE: return EVP_CHACHA20_POLY1305; +#endif +#ifdef HAVE_CHACHA + case WC_CHACHA20_TYPE: return EVP_CHACHA20; +#endif +#ifdef WOLFSSL_SM4_ECB + case WC_SM4_ECB_TYPE: return EVP_SM4_ECB; +#endif +#ifdef WOLFSSL_SM4_CBC + case WC_SM4_CBC_TYPE: return EVP_SM4_CBC; +#endif +#ifdef WOLFSSL_SM4_CTR + case WC_SM4_CTR_TYPE: return EVP_SM4_CTR; +#endif +#ifdef WOLFSSL_SM4_GCM + case WC_SM4_GCM_TYPE: return EVP_SM4_GCM; +#endif +#ifdef WOLFSSL_SM4_CCM + case WC_SM4_CCM_TYPE: return EVP_SM4_CCM; +#endif + case WC_NULL_CIPHER_TYPE: return EVP_NULL; + default: + return NULL; + } +} + int wolfSSL_EVP_CIPHER_block_size(const WOLFSSL_EVP_CIPHER *cipher) { if (cipher == NULL) @@ -2633,7 +2795,7 @@ int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_ return WOLFSSL_FAILURE; } if (ctx->pkey->hkdfMode == WOLFSSL_EVP_PKEY_HKDEF_MODE_EXTRACT_AND_EXPAND) { - if (wc_HKDF(hkdfHashType, ctx->pkey->hkdfKey, ctx->pkey->hkdfKeySz, + if (wc_HKDF((int)hkdfHashType, ctx->pkey->hkdfKey, ctx->pkey->hkdfKeySz, ctx->pkey->hkdfSalt, ctx->pkey->hkdfSaltSz, ctx->pkey->hkdfInfo, ctx->pkey->hkdfInfoSz, key, (word32)*keylen) != 0) { @@ -2642,7 +2804,7 @@ int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_ } } else if (ctx->pkey->hkdfMode == WOLFSSL_EVP_PKEY_HKDEF_MODE_EXTRACT_ONLY) { - if (wc_HKDF_Extract(hkdfHashType, ctx->pkey->hkdfSalt, + if (wc_HKDF_Extract((int)hkdfHashType, ctx->pkey->hkdfSalt, ctx->pkey->hkdfSaltSz, ctx->pkey->hkdfKey, ctx->pkey->hkdfKeySz, key) != 0) { WOLFSSL_MSG("wc_HKDF_Extract failed."); @@ -2659,7 +2821,7 @@ int wolfSSL_EVP_PKEY_derive(WOLFSSL_EVP_PKEY_CTX *ctx, unsigned char *key, size_ } } else if (ctx->pkey->hkdfMode == WOLFSSL_EVP_PKEY_HKDEF_MODE_EXPAND_ONLY) { - if (wc_HKDF_Expand(hkdfHashType, ctx->pkey->hkdfKey, + if (wc_HKDF_Expand((int)hkdfHashType, ctx->pkey->hkdfKey, ctx->pkey->hkdfKeySz, ctx->pkey->hkdfInfo, ctx->pkey->hkdfInfoSz, key, (word32)*keylen) != 0) { @@ -3316,14 +3478,44 @@ int wolfSSL_EVP_PKEY_verify(WOLFSSL_EVP_PKEY_CTX *ctx, const unsigned char *sig, */ int wolfSSL_EVP_PKEY_bits(const WOLFSSL_EVP_PKEY *pkey) { - int bytes; + int ret = 0; - if (pkey == NULL) return 0; - WOLFSSL_ENTER("wolfSSL_EVP_PKEY_bits"); - if ((bytes = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey)) ==0) return 0; - if (bytes < 0) + if (pkey == NULL) return 0; - return bytes*8; + + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_bits"); + + switch (pkey->type) { +#ifndef NO_RSA + case WC_EVP_PKEY_RSA: + ret = (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(pkey->rsa)); + break; +#endif /* !NO_RSA */ + +#ifndef NO_DSA + case WC_EVP_PKEY_DSA: + if (pkey->dsa == NULL || + (!pkey->dsa->exSet && + SetDsaExternal(pkey->dsa) != WOLFSSL_SUCCESS)) + break; + ret = wolfSSL_BN_num_bytes(pkey->dsa->p); + break; +#endif + +#ifdef HAVE_ECC + case WC_EVP_PKEY_EC: + if (pkey->ecc == NULL || pkey->ecc->internal == NULL) { + WOLFSSL_MSG("No ECC key has been set"); + break; + } + ret = wc_ecc_size((ecc_key*)(pkey->ecc->internal)); + break; +#endif /* HAVE_ECC */ + + default: + break; + } + return ret > 0 ? ret * 8 : 0; } @@ -3530,12 +3722,11 @@ int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx, return ret; } -/* Get the size in bytes for WOLFSSL_EVP_PKEY key +/* Get the maximum suitable size for the operations that can be done with pkey * * pkey WOLFSSL_EVP_PKEY structure to get key size of * - * returns the size of a key on success which is the maximum size of a - * signature + * returns the recommended size of buffers */ int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey) { @@ -3563,7 +3754,7 @@ int wolfSSL_EVP_PKEY_size(WOLFSSL_EVP_PKEY *pkey) WOLFSSL_MSG("No ECC key has been set"); break; } - return wc_ecc_size((ecc_key*)(pkey->ecc->internal)); + return wc_ecc_sig_size((ecc_key*)(pkey->ecc->internal)); #endif /* HAVE_ECC */ default: @@ -3732,7 +3923,6 @@ int wolfSSL_EVP_PKEY_missing_parameters(WOLFSSL_EVP_PKEY *pkey) int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b) { int ret = -1; /* failure */ - int a_sz = 0, b_sz = 0; if (a == NULL || b == NULL) return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); @@ -3745,40 +3935,47 @@ int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b) switch (a->type) { #ifndef NO_RSA case WC_EVP_PKEY_RSA: - a_sz = (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(a->rsa)); - b_sz = (int)wolfSSL_RSA_size((const WOLFSSL_RSA*)(b->rsa)); + if (wolfSSL_RSA_size((const WOLFSSL_RSA*)(a->rsa)) <= 0 || + wolfSSL_RSA_size((const WOLFSSL_RSA*)(b->rsa)) <= 0) { + return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); + } + + if (mp_cmp(&((RsaKey*)a->rsa->internal)->n, + &((RsaKey*)b->rsa->internal)->n) != MP_EQ) { + return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); + } + + if (mp_cmp(&((RsaKey*)a->rsa->internal)->e, + &((RsaKey*)b->rsa->internal)->e) != MP_EQ) { + return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); + } break; #endif /* !NO_RSA */ #ifdef HAVE_ECC case WC_EVP_PKEY_EC: if (a->ecc == NULL || a->ecc->internal == NULL || - b->ecc == NULL || b->ecc->internal == NULL) { + b->ecc == NULL || b->ecc->internal == NULL || + wc_ecc_size((ecc_key*)a->ecc->internal) <= 0 || + wc_ecc_size((ecc_key*)b->ecc->internal) <= 0 || + a->ecc->group == NULL || b->ecc->group == NULL) { return ret; } - a_sz = wc_ecc_size((ecc_key*)(a->ecc->internal)); - b_sz = wc_ecc_size((ecc_key*)(b->ecc->internal)); + + /* check curve */ + if (a->ecc->group->curve_idx != b->ecc->group->curve_idx) { + return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); + } + + if (wc_ecc_cmp_point(&((ecc_key*)a->ecc->internal)->pubkey, + &((ecc_key*)b->ecc->internal)->pubkey) != 0) { + return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); + } break; #endif /* HAVE_ECC */ default: return WS_RETURN_CODE(ret, -2); } /* switch (a->type) */ - /* check size */ - if (a_sz <= 0 || b_sz <= 0 || a_sz != b_sz) { - return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); - } - - /* check public key size */ - if (a->pkey_sz > 0 && b->pkey_sz > 0 && a->pkey_sz != b->pkey_sz) { - return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); - } - - /* check public key */ - if (a->pkey.ptr && b->pkey.ptr) { - if (XMEMCMP(a->pkey.ptr, b->pkey.ptr, (size_t)a->pkey_sz) != 0) { - return WS_RETURN_CODE(ret, WOLFSSL_FAILURE); - } - } #if defined(WOLFSSL_ERROR_CODE_OPENSSL) ret = 1; /* the keys match */ #else @@ -3795,18 +3992,11 @@ int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EVP_PKEY *b) static int DH_param_check(WOLFSSL_DH* dh_key) { int ret = WOLFSSL_SUCCESS; - WOLFSSL_BN_CTX* ctx = NULL; WOLFSSL_BIGNUM *num1 = NULL; WOLFSSL_BIGNUM *num2 = NULL; WOLFSSL_ENTER("DH_param_check"); - ctx = wolfSSL_BN_CTX_new(); - if (ctx == NULL) { - WOLFSSL_MSG("failed to allocate memory"); - return WOLFSSL_FAILURE; - } - num1 = wolfSSL_BN_new(); num2 = wolfSSL_BN_new(); if (num1 == NULL || num2 == NULL) { @@ -3840,7 +4030,7 @@ static int DH_param_check(WOLFSSL_DH* dh_key) dh_key->q != NULL) { if (ret == WOLFSSL_SUCCESS && - wolfSSL_BN_mod_exp(num1, dh_key->g, dh_key->q, dh_key->p, ctx) + wolfSSL_BN_mod_exp(num1, dh_key->g, dh_key->q, dh_key->p, NULL) == WC_NO_ERR_TRACE(WOLFSSL_FAILURE)) { WOLFSSL_MSG("BN_mod_exp failed"); @@ -3855,7 +4045,7 @@ static int DH_param_check(WOLFSSL_DH* dh_key) #if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) /* test if the number q is prime. */ if (ret == WOLFSSL_SUCCESS && - (wolfSSL_BN_is_prime_ex(dh_key->q, 64, ctx, NULL) <= 0)) { + (wolfSSL_BN_is_prime_ex(dh_key->q, 64, NULL, NULL) <= 0)) { WOLFSSL_MSG("dh_key->q is not prime or error during check."); ret = WOLFSSL_FAILURE; } /* else TODO check q div q - 1. need BN_div */ @@ -3863,7 +4053,6 @@ static int DH_param_check(WOLFSSL_DH* dh_key) } /* clean up */ - wolfSSL_BN_CTX_free(ctx); wolfSSL_BN_free(num1); wolfSSL_BN_free(num2); @@ -4043,9 +4232,13 @@ int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret, pkey->ecc); if (ecdsaSig == NULL) return WOLFSSL_FAILURE; + /* get signature length only */ ret = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, NULL); - if (ret <= 0 || ret > (int)*siglen) + if (ret <= 0 || ret > (int)*siglen) { + wolfSSL_ECDSA_SIG_free(ecdsaSig); return WOLFSSL_FAILURE; + } + /* perform validation of signature */ ret = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sigret); wolfSSL_ECDSA_SIG_free(ecdsaSig); if (ret <= 0 || ret > (int)*siglen) @@ -4262,69 +4455,69 @@ static int wolfssl_evp_md_to_hash_type(const WOLFSSL_EVP_MD *type, int ret = 0; #ifndef NO_SHA256 - if (XSTRCMP(type, "SHA256") == 0) { + if (XSTRCMP(type, WC_SN_sha256) == 0) { *hashType = WC_SHA256; } else #endif #ifndef NO_SHA - if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, "SHA1") == 0)) { + if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, WC_SN_sha1) == 0)) { *hashType = WC_SHA; } else #endif /* NO_SHA */ #ifdef WOLFSSL_SHA224 - if (XSTRCMP(type, "SHA224") == 0) { + if (XSTRCMP(type, WC_SN_sha224) == 0) { *hashType = WC_SHA224; } else #endif #ifdef WOLFSSL_SHA384 - if (XSTRCMP(type, "SHA384") == 0) { + if (XSTRCMP(type, WC_SN_sha384) == 0) { *hashType = WC_SHA384; } else #endif #ifdef WOLFSSL_SHA512 - if (XSTRCMP(type, "SHA512") == 0) { + if (XSTRCMP(type, WC_SN_sha512) == 0) { *hashType = WC_SHA512; } else #endif #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 - if (XSTRCMP(type, "SHA3_224") == 0) { + if (XSTRCMP(type, WC_SN_sha3_224) == 0) { *hashType = WC_SHA3_224; } else #endif #ifndef WOLFSSL_NOSHA3_256 - if (XSTRCMP(type, "SHA3_256") == 0) { + if (XSTRCMP(type, WC_SN_sha3_256) == 0) { *hashType = WC_SHA3_256; } else #endif #ifndef WOLFSSL_NOSHA3_384 - if (XSTRCMP(type, "SHA3_384") == 0) { + if (XSTRCMP(type, WC_SN_sha3_384) == 0) { *hashType = WC_SHA3_384; } else #endif #ifndef WOLFSSL_NOSHA3_512 - if (XSTRCMP(type, "SHA3_512") == 0) { + if (XSTRCMP(type, WC_SN_sha3_512) == 0) { *hashType = WC_SHA3_512; } else #endif #endif #ifdef WOLFSSL_SM3 - if (XSTRCMP(type, "SM3") == 0) { + if (XSTRCMP(type, WC_SN_sm3) == 0) { *hashType = WC_SM3; } else #endif #ifndef NO_MD5 - if (XSTRCMP(type, "MD5") == 0) { + if (XSTRCMP(type, WC_SN_md5) == 0) { *hashType = WC_MD5; } else @@ -4644,7 +4837,9 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, ctx->pctx->pkey->ecc); if (ecdsaSig == NULL) break; - len = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig); + len = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, NULL); + if (len > 0 && (size_t)len <= *siglen) + len = wolfSSL_i2d_ECDSA_SIG(ecdsaSig, &sig); wolfSSL_ECDSA_SIG_free(ecdsaSig); if (len == 0) break; @@ -4867,6 +5062,7 @@ int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen, { const char *nostring = ""; int ret = 0; + enum wc_HashType pbkdf2HashType; if (pass == NULL) { passlen = 0; @@ -4875,8 +5071,10 @@ int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen, passlen = (int)XSTRLEN(pass); } + pbkdf2HashType = EvpMd2MacType(digest); + ret = wc_PBKDF2((byte*)out, (byte*)pass, passlen, (byte*)salt, saltlen, - iter, keylen, EvpMd2MacType(digest)); + iter, keylen, pbkdf2HashType); if (ret == 0) return WOLFSSL_SUCCESS; else @@ -6299,14 +6497,16 @@ void wolfSSL_EVP_init(void) case WC_AES_256_OFB_TYPE: #endif wc_AesFree(&ctx->cipher.aes); - ctx->flags &= ~WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + ctx->flags &= + (unsigned long)~WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; break; #if defined(WOLFSSL_AES_XTS) && \ (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) case WC_AES_128_XTS_TYPE: case WC_AES_256_XTS_TYPE: wc_AesXtsFree(&ctx->cipher.xts); - ctx->flags &= ~WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; + ctx->flags &= + (unsigned long)~WOLFSSL_EVP_CIPH_LOW_LEVEL_INITED; break; #endif #endif /* AES */ @@ -6875,7 +7075,7 @@ void wolfSSL_EVP_init(void) ret = wc_AriaInitCrypt(&ctx->cipher.aria, MC_ALGID_ARIA_256BITKEY); break; default: - WOLFSSL_MSG("Not implemented cipherType"); + WOLFSSL_MSG("Unimplemented cipherType"); return WOLFSSL_NOT_IMPLEMENTED; /* This should never happen */ } if (ret != 0) { @@ -8258,9 +8458,9 @@ void wolfSSL_EVP_init(void) } #endif /* !NO_AES || !NO_DES3 */ - static int IsCipherTypeAEAD(unsigned char cipherType) + static int IsCipherTypeAEAD(unsigned int type) { - switch (cipherType) { + switch (type) { case WC_AES_128_GCM_TYPE: case WC_AES_192_GCM_TYPE: case WC_AES_256_GCM_TYPE: @@ -9367,22 +9567,22 @@ int wolfSSL_EVP_MD_pkey_type(const WOLFSSL_EVP_MD* type) WOLFSSL_ENTER("wolfSSL_EVP_MD_pkey_type"); if (type != NULL) { - if (XSTRCMP(type, "MD5") == 0) { + if (XSTRCMP(type, WC_SN_md5) == 0) { ret = WC_NID_md5WithRSAEncryption; } - else if (XSTRCMP(type, "SHA1") == 0) { + else if (XSTRCMP(type, WC_SN_sha1) == 0) { ret = WC_NID_sha1WithRSAEncryption; } - else if (XSTRCMP(type, "SHA224") == 0) { + else if (XSTRCMP(type, WC_SN_sha224) == 0) { ret = WC_NID_sha224WithRSAEncryption; } - else if (XSTRCMP(type, "SHA256") == 0) { + else if (XSTRCMP(type, WC_SN_sha256) == 0) { ret = WC_NID_sha256WithRSAEncryption; } - else if (XSTRCMP(type, "SHA384") == 0) { + else if (XSTRCMP(type, WC_SN_sha384) == 0) { ret = WC_NID_sha384WithRSAEncryption; } - else if (XSTRCMP(type, "SHA512") == 0) { + else if (XSTRCMP(type, WC_SN_sha512) == 0) { ret = WC_NID_sha512WithRSAEncryption; } } @@ -9936,54 +10136,44 @@ static const struct alias { const char *alias; } digest_alias_tbl[] = { - {"MD4", "md4"}, - {"MD5", "md5"}, - {"SHA1", "sha1"}, - {"SHA1", "SHA"}, - {"SHA224", "sha224"}, - {"SHA256", "sha256"}, - {"SHA384", "sha384"}, - {"SHA512", "sha512"}, - {"SHA512_224", "sha512_224"}, - {"SHA3_224", "sha3_224"}, - {"SHA3_256", "sha3_256"}, - {"SHA3_384", "sha3_384"}, - {"SHA3_512", "sha3_512"}, - {"SM3", "sm3"}, - {"BLAKE2B512", "blake2b512"}, - {"BLAKE2S256", "blake2s256"}, - {"SHAKE128", "shake128"}, - {"SHAKE256", "shake256"}, + {WC_SN_md4, "md4"}, + {WC_SN_md5, "md5"}, + {WC_SN_sha1, "sha1"}, + {WC_SN_sha1, "SHA"}, + {WC_SN_sha224, "sha224"}, + {WC_SN_sha256, "sha256"}, + {WC_SN_sha384, "sha384"}, + {WC_SN_sha512, "sha512"}, + {WC_SN_sha512_224, "sha512_224"}, + {WC_SN_sha3_224, "sha3_224"}, + {WC_SN_sha3_256, "sha3_256"}, + {WC_SN_sha3_384, "sha3_384"}, + {WC_SN_sha3_512, "sha3_512"}, + {WC_SN_sm3, "sm3"}, + {WC_SN_blake2b512, "blake2b512"}, + {WC_SN_blake2s256, "blake2s256"}, + {WC_SN_shake128, "shake128"}, + {WC_SN_shake256, "shake256"}, { NULL, NULL} }; const WOLFSSL_EVP_MD *wolfSSL_EVP_get_digestbyname(const char *name) { - char nameUpper[15]; /* 15 bytes should be enough for any name */ - size_t i; - const struct alias *al; const struct s_ent *ent; - for (i = 0; i < sizeof(nameUpper) && name[i] != '\0'; i++) { - nameUpper[i] = (char)XTOUPPER((unsigned char) name[i]); - } - if (i < sizeof(nameUpper)) - nameUpper[i] = '\0'; - else - return NULL; - - name = nameUpper; - for (al = digest_alias_tbl; al->name != NULL; al++) + for (al = digest_alias_tbl; al->name != NULL; al++) { if(XSTRCMP(name, al->alias) == 0) { name = al->name; break; } + } - for (ent = md_tbl; ent->name != NULL; ent++) + for (ent = md_tbl; ent->name != NULL; ent++) { if(XSTRCMP(name, ent->name) == 0) { return (WOLFSSL_EVP_MD *)ent->name; } + } return NULL; } @@ -10017,7 +10207,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_md4(void) { WOLFSSL_ENTER("EVP_md4"); - return wolfSSL_EVP_get_digestbyname("MD4"); + return wolfSSL_EVP_get_digestbyname(WC_SN_md4); } #endif /* !NO_MD4 */ @@ -10028,7 +10218,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void) { WOLFSSL_ENTER("EVP_md5"); - return wolfSSL_EVP_get_digestbyname("MD5"); + return wolfSSL_EVP_get_digestbyname(WC_SN_md5); } #endif /* !NO_MD5 */ @@ -10040,8 +10230,8 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) */ const WOLFSSL_EVP_MD* wolfSSL_EVP_blake2b512(void) { - WOLFSSL_ENTER("EVP_blake2b512"); - return wolfSSL_EVP_get_digestbyname("BLAKE2b512"); + WOLFSSL_ENTER("wolfSSL_EVP_blake2b512"); + return wolfSSL_EVP_get_digestbyname(WC_SN_blake2b512); } #endif @@ -10080,7 +10270,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void) { WOLFSSL_ENTER("EVP_sha1"); - return wolfSSL_EVP_get_digestbyname("SHA1"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha1); } #endif /* NO_SHA */ @@ -10089,7 +10279,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha224(void) { WOLFSSL_ENTER("EVP_sha224"); - return wolfSSL_EVP_get_digestbyname("SHA224"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha224); } #endif /* WOLFSSL_SHA224 */ @@ -10098,7 +10288,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void) { WOLFSSL_ENTER("EVP_sha256"); - return wolfSSL_EVP_get_digestbyname("SHA256"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha256); } #ifdef WOLFSSL_SHA384 @@ -10106,7 +10296,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void) { WOLFSSL_ENTER("EVP_sha384"); - return wolfSSL_EVP_get_digestbyname("SHA384"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha384); } #endif /* WOLFSSL_SHA384 */ @@ -10116,7 +10306,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void) { WOLFSSL_ENTER("EVP_sha512"); - return wolfSSL_EVP_get_digestbyname("SHA512"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha512); } #ifndef WOLFSSL_NOSHA512_224 @@ -10124,7 +10314,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512_224(void) { WOLFSSL_ENTER("EVP_sha512_224"); - return wolfSSL_EVP_get_digestbyname("SHA512_224"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha512_224); } #endif /* !WOLFSSL_NOSHA512_224 */ @@ -10133,7 +10323,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512_256(void) { WOLFSSL_ENTER("EVP_sha512_256"); - return wolfSSL_EVP_get_digestbyname("SHA512_256"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha512_256); } #endif /* !WOLFSSL_NOSHA512_224 */ @@ -10145,7 +10335,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_224(void) { WOLFSSL_ENTER("EVP_sha3_224"); - return wolfSSL_EVP_get_digestbyname("SHA3_224"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha3_224); } #endif /* WOLFSSL_NOSHA3_224 */ @@ -10154,7 +10344,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_256(void) { WOLFSSL_ENTER("EVP_sha3_256"); - return wolfSSL_EVP_get_digestbyname("SHA3_256"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha3_256); } #endif /* WOLFSSL_NOSHA3_256 */ @@ -10162,7 +10352,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_384(void) { WOLFSSL_ENTER("EVP_sha3_384"); - return wolfSSL_EVP_get_digestbyname("SHA3_384"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha3_384); } #endif /* WOLFSSL_NOSHA3_384 */ @@ -10170,7 +10360,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_512(void) { WOLFSSL_ENTER("EVP_sha3_512"); - return wolfSSL_EVP_get_digestbyname("SHA3_512"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sha3_512); } #endif /* WOLFSSL_NOSHA3_512 */ @@ -10196,7 +10386,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) const WOLFSSL_EVP_MD* wolfSSL_EVP_sm3(void) { WOLFSSL_ENTER("EVP_sm3"); - return wolfSSL_EVP_get_digestbyname("SM3"); + return wolfSSL_EVP_get_digestbyname(WC_SN_sm3); } #endif /* WOLFSSL_SM3 */ @@ -10482,17 +10672,21 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) /* Not an error since an unused struct could be free'd or * reset. */ break; - case WC_HASH_TYPE_MD2: - case WC_HASH_TYPE_MD4: - case WC_HASH_TYPE_MD5_SHA: - case WC_HASH_TYPE_BLAKE2B: - case WC_HASH_TYPE_BLAKE2S: #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128) case WC_HASH_TYPE_SHAKE128: + wc_Shake128_Free(&ctx->hash.digest.shake); + break; #endif #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE256) case WC_HASH_TYPE_SHAKE256: + wc_Shake256_Free(&ctx->hash.digest.shake); + break; #endif + case WC_HASH_TYPE_MD2: + case WC_HASH_TYPE_MD4: + case WC_HASH_TYPE_MD5_SHA: + case WC_HASH_TYPE_BLAKE2B: + case WC_HASH_TYPE_BLAKE2S: default: ret = WOLFSSL_FAILURE; break; @@ -10526,76 +10720,92 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) XMEMSET(&ctx->hash.digest, 0, sizeof(WOLFSSL_Hasher)); } else #ifndef NO_SHA - if ((XSTRCMP(md, "SHA") == 0) || (XSTRCMP(md, "SHA1") == 0)) { + if ((XSTRCMP(md, "SHA") == 0) || (XSTRCMP(md, WC_SN_sha1) == 0)) { ret = wolfSSL_SHA_Init(&(ctx->hash.digest.sha)); } else #endif #ifndef NO_SHA256 - if (XSTRCMP(md, "SHA256") == 0) { + if (XSTRCMP(md, WC_SN_sha256) == 0) { ret = wolfSSL_SHA256_Init(&(ctx->hash.digest.sha256)); } else #endif #ifdef WOLFSSL_SHA224 - if (XSTRCMP(md, "SHA224") == 0) { + if (XSTRCMP(md, WC_SN_sha224) == 0) { ret = wolfSSL_SHA224_Init(&(ctx->hash.digest.sha224)); } else #endif #ifdef WOLFSSL_SHA384 - if (XSTRCMP(md, "SHA384") == 0) { + if (XSTRCMP(md, WC_SN_sha384) == 0) { ret = wolfSSL_SHA384_Init(&(ctx->hash.digest.sha384)); } else #endif #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \ defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224) - if (XSTRCMP(md, "SHA512_224") == 0) { + if (XSTRCMP(md, WC_SN_sha512_224) == 0) { ret = wolfSSL_SHA512_224_Init(&(ctx->hash.digest.sha512)); } else #endif #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) && \ defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256) - if (XSTRCMP(md, "SHA512_256") == 0) { + if (XSTRCMP(md, WC_SN_sha512_256) == 0) { ret = wolfSSL_SHA512_256_Init(&(ctx->hash.digest.sha512)); } else #endif #ifdef WOLFSSL_SHA512 - if (XSTRCMP(md, "SHA512") == 0) { + if (XSTRCMP(md, WC_SN_sha512) == 0) { ret = wolfSSL_SHA512_Init(&(ctx->hash.digest.sha512)); } else #endif #ifndef NO_MD4 - if (XSTRCMP(md, "MD4") == 0) { + if (XSTRCMP(md, WC_SN_md4) == 0) { wolfSSL_MD4_Init(&(ctx->hash.digest.md4)); } else #endif #ifndef NO_MD5 - if (XSTRCMP(md, "MD5") == 0) { + if (XSTRCMP(md, WC_SN_md5) == 0) { ret = wolfSSL_MD5_Init(&(ctx->hash.digest.md5)); } else #endif #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 - if (XSTRCMP(md, "SHA3_224") == 0) { + if (XSTRCMP(md, WC_SN_sha3_224) == 0) { ret = wolfSSL_SHA3_224_Init(&(ctx->hash.digest.sha3_224)); } else #endif #ifndef WOLFSSL_NOSHA3_256 - if (XSTRCMP(md, "SHA3_256") == 0) { + if (XSTRCMP(md, WC_SN_sha3_256) == 0) { ret = wolfSSL_SHA3_256_Init(&(ctx->hash.digest.sha3_256)); } else #endif #ifndef WOLFSSL_NOSHA3_384 - if (XSTRCMP(md, "SHA3_384") == 0) { + if (XSTRCMP(md, WC_SN_sha3_384) == 0) { ret = wolfSSL_SHA3_384_Init(&(ctx->hash.digest.sha3_384)); } else #endif #ifndef WOLFSSL_NOSHA3_512 - if (XSTRCMP(md, "SHA3_512") == 0) { + if (XSTRCMP(md, WC_SN_sha3_512) == 0) { ret = wolfSSL_SHA3_512_Init(&(ctx->hash.digest.sha3_512)); } else #endif + #ifdef WOLFSSL_SHAKE128 + if (XSTRCMP(md, WC_SN_shake128) == 0) { + if (wc_InitShake128(&(ctx->hash.digest.shake), NULL, + INVALID_DEVID) != 0) { + ret = WOLFSSL_FAILURE; + } + } else + #endif + #ifdef WOLFSSL_SHAKE256 + if (XSTRCMP(md, WC_SN_shake256) == 0) { + if (wc_InitShake256(&(ctx->hash.digest.shake), NULL, + INVALID_DEVID) != 0) { + ret = WOLFSSL_FAILURE; + } + } else + #endif #endif #ifdef WOLFSSL_SM3 - if (XSTRCMP(md, "SM3") == 0) { + if (XSTRCMP(md, WC_SN_sm3) == 0) { ret = wc_InitSm3(&ctx->hash.digest.sm3, NULL, INVALID_DEVID); if (ret == 0) { ret = WOLFSSL_SUCCESS; @@ -10723,17 +10933,28 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) } break; #endif - case WC_HASH_TYPE_NONE: - case WC_HASH_TYPE_MD2: - case WC_HASH_TYPE_MD5_SHA: - case WC_HASH_TYPE_BLAKE2B: - case WC_HASH_TYPE_BLAKE2S: #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128) case WC_HASH_TYPE_SHAKE128: + if (wc_Shake128_Update(&ctx->hash.digest.shake, + (const byte*)data, (word32)sz) == 0) { + + ret = WOLFSSL_SUCCESS; + } + break; #endif #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE256) case WC_HASH_TYPE_SHAKE256: + if (wc_Shake256_Update(&ctx->hash.digest.shake, + (const byte*)data, (word32)sz) == 0) { + ret = WOLFSSL_SUCCESS; + } + break; #endif + case WC_HASH_TYPE_NONE: + case WC_HASH_TYPE_MD2: + case WC_HASH_TYPE_MD5_SHA: + case WC_HASH_TYPE_BLAKE2B: + case WC_HASH_TYPE_BLAKE2S: default: return WOLFSSL_FAILURE; } @@ -10742,14 +10963,11 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) } /* WOLFSSL_SUCCESS on ok */ - int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md, - unsigned int* s) + static int wolfSSL_EVP_DigestFinal_Common(WOLFSSL_EVP_MD_CTX* ctx, + unsigned char* md, unsigned int* s, enum wc_HashType macType) { int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE); - enum wc_HashType macType; - WOLFSSL_ENTER("EVP_DigestFinal"); - macType = EvpMd2MacType(wolfSSL_EVP_MD_CTX_md(ctx)); switch (macType) { case WC_HASH_TYPE_MD4: #ifndef NO_MD4 @@ -10847,23 +11065,84 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) } if (s) *s = WC_SM3_DIGEST_SIZE; break; + #endif + #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128) + case WC_HASH_TYPE_SHAKE128: + if (wc_Shake128_Final(&ctx->hash.digest.shake, md, *s) == 0) { + ret = WOLFSSL_SUCCESS; + } + break; + #endif + #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE256) + case WC_HASH_TYPE_SHAKE256: + if (wc_Shake256_Final(&ctx->hash.digest.shake, md, *s) == 0) { + ret = WOLFSSL_SUCCESS; + } + break; #endif case WC_HASH_TYPE_NONE: case WC_HASH_TYPE_MD2: case WC_HASH_TYPE_MD5_SHA: case WC_HASH_TYPE_BLAKE2B: case WC_HASH_TYPE_BLAKE2S: + default: + return WOLFSSL_FAILURE; + } + + return ret; + } + + int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md, + unsigned int* s) + { + enum wc_HashType macType; + + WOLFSSL_ENTER("wolfSSL_EVP_DigestFinal"); + macType = EvpMd2MacType(wolfSSL_EVP_MD_CTX_md(ctx)); + switch (macType) { + case WC_HASH_TYPE_MD4: + case WC_HASH_TYPE_MD5: + case WC_HASH_TYPE_SHA: + case WC_HASH_TYPE_SHA224: + case WC_HASH_TYPE_SHA256: + case WC_HASH_TYPE_SHA384: + case WC_HASH_TYPE_SHA512: + #ifndef WOLFSSL_NOSHA512_224 + case WC_HASH_TYPE_SHA512_224: + #endif /* !WOLFSSL_NOSHA512_224 */ + #ifndef WOLFSSL_NOSHA512_256 + case WC_HASH_TYPE_SHA512_256: + #endif /* !WOLFSSL_NOSHA512_256 */ + case WC_HASH_TYPE_SHA3_224: + case WC_HASH_TYPE_SHA3_256: + case WC_HASH_TYPE_SHA3_384: + case WC_HASH_TYPE_SHA3_512: + #ifdef WOLFSSL_SM3 + case WC_HASH_TYPE_SM3: + #endif + case WC_HASH_TYPE_NONE: + case WC_HASH_TYPE_MD2: + case WC_HASH_TYPE_MD5_SHA: + case WC_HASH_TYPE_BLAKE2B: + case WC_HASH_TYPE_BLAKE2S: + break; + #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128) case WC_HASH_TYPE_SHAKE128: + *s = 16; /* if mixing up XOF with plain digest 128 bit is + * default for SHAKE128 */ + break; #endif #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE256) case WC_HASH_TYPE_SHAKE256: + *s = 32; /* if mixing up XOF with plain digest 256 bit is + * default for SHAKE256 */ + break; #endif default: return WOLFSSL_FAILURE; } - - return ret; + return wolfSSL_EVP_DigestFinal_Common(ctx, md, s, macType); } /* WOLFSSL_SUCCESS on ok */ @@ -10874,6 +11153,46 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type) return wolfSSL_EVP_DigestFinal(ctx, md, s); } + + /* XOF stands for extendable-output functions. This is used for algos such + * as SHAKE256. + * + * returns 1 (WOLFSSL_SUCCESS) on success and 0 (WOLFSSL_FAILURE) on fail */ + int wolfSSL_EVP_DigestFinalXOF(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *md, + size_t sz) + { + unsigned int len; + enum wc_HashType macType; + + WOLFSSL_ENTER("wolfSSL_EVP_DigestFinalXOF"); + len = (unsigned int)sz; + + macType = EvpMd2MacType(wolfSSL_EVP_MD_CTX_md(ctx)); + return wolfSSL_EVP_DigestFinal_Common(ctx, md, &len, macType); + } + + + unsigned long wolfSSL_EVP_MD_flags(const WOLFSSL_EVP_MD *md) + { + enum wc_HashType macType; + + macType = EvpMd2MacType(md); + switch ((int)macType) { + case WC_HASH_TYPE_BLAKE2B: + case WC_HASH_TYPE_BLAKE2S: + #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128) + case WC_HASH_TYPE_SHAKE128: + #endif + #if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE256) + case WC_HASH_TYPE_SHAKE256: + #endif + return WOLFSSL_EVP_MD_FLAG_XOF; + default: + return 0; + } + } + + void wolfSSL_EVP_cleanup(void) { /* nothing to do here */ @@ -10884,6 +11203,10 @@ const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id) WOLFSSL_MSG("wolfSSL_get_digestbynid"); switch(id) { +#ifndef NO_MD4 + case WC_NID_md4: + return wolfSSL_EVP_md4(); +#endif #ifndef NO_MD5 case WC_NID_md5: return wolfSSL_EVP_md5(); @@ -10928,64 +11251,64 @@ int wolfSSL_EVP_MD_block_size(const WOLFSSL_EVP_MD* type) } #ifndef NO_SHA - if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, "SHA1") == 0)) { + if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, WC_SN_sha1) == 0)) { return WC_SHA_BLOCK_SIZE; } else #endif #ifndef NO_SHA256 - if (XSTRCMP(type, "SHA256") == 0) { + if (XSTRCMP(type, WC_SN_sha256) == 0) { return WC_SHA256_BLOCK_SIZE; } else #endif #ifndef NO_MD4 - if (XSTRCMP(type, "MD4") == 0) { + if (XSTRCMP(type, WC_SN_md4) == 0) { return WC_MD4_BLOCK_SIZE; } else #endif #ifndef NO_MD5 - if (XSTRCMP(type, "MD5") == 0) { + if (XSTRCMP(type, WC_SN_md5) == 0) { return WC_MD5_BLOCK_SIZE; } else #endif #ifdef WOLFSSL_SHA224 - if (XSTRCMP(type, "SHA224") == 0) { + if (XSTRCMP(type, WC_SN_sha224) == 0) { return WC_SHA224_BLOCK_SIZE; } else #endif #ifdef WOLFSSL_SHA384 - if (XSTRCMP(type, "SHA384") == 0) { + if (XSTRCMP(type, WC_SN_sha384) == 0) { return WC_SHA384_BLOCK_SIZE; } else #endif #ifdef WOLFSSL_SHA512 - if (XSTRCMP(type, "SHA512") == 0) { + if (XSTRCMP(type, WC_SN_sha512) == 0) { return WC_SHA512_BLOCK_SIZE; } else #endif #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 - if (XSTRCMP(type, "SHA3_224") == 0) { + if (XSTRCMP(type, WC_SN_sha3_224) == 0) { return WC_SHA3_224_BLOCK_SIZE; } else #endif #ifndef WOLFSSL_NOSHA3_256 - if (XSTRCMP(type, "SHA3_256") == 0) { + if (XSTRCMP(type, WC_SN_sha3_256) == 0) { return WC_SHA3_256_BLOCK_SIZE; } else #endif #ifndef WOLFSSL_NOSHA3_384 - if (XSTRCMP(type, "SHA3_384") == 0) { + if (XSTRCMP(type, WC_SN_sha3_384) == 0) { return WC_SHA3_384_BLOCK_SIZE; } else #endif #ifndef WOLFSSL_NOSHA3_512 - if (XSTRCMP(type, "SHA3_512") == 0) { + if (XSTRCMP(type, WC_SN_sha3_512) == 0) { return WC_SHA3_512_BLOCK_SIZE; - } + } else #endif #endif /* WOLFSSL_SHA3 */ #ifdef WOLFSSL_SM3 - if (XSTRCMP(type, "SM3") == 0) { + if (XSTRCMP(type, WC_SN_sm3) == 0) { return WC_SM3_BLOCK_SIZE; } else #endif @@ -11003,74 +11326,74 @@ int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* type) } #ifndef NO_SHA - if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, "SHA1") == 0)) { + if ((XSTRCMP(type, "SHA") == 0) || (XSTRCMP(type, WC_SN_sha1) == 0)) { return WC_SHA_DIGEST_SIZE; } else #endif #ifndef NO_SHA256 - if (XSTRCMP(type, "SHA256") == 0) { + if (XSTRCMP(type, WC_SN_sha256) == 0) { return WC_SHA256_DIGEST_SIZE; } else #endif #ifndef NO_MD4 - if (XSTRCMP(type, "MD4") == 0) { + if (XSTRCMP(type, WC_SN_md4) == 0) { return WC_MD4_DIGEST_SIZE; } else #endif #ifndef NO_MD5 - if (XSTRCMP(type, "MD5") == 0) { + if (XSTRCMP(type, WC_SN_md5) == 0) { return WC_MD5_DIGEST_SIZE; } else #endif #ifdef WOLFSSL_SHA224 - if (XSTRCMP(type, "SHA224") == 0) { + if (XSTRCMP(type, WC_SN_sha224) == 0) { return WC_SHA224_DIGEST_SIZE; } else #endif #ifdef WOLFSSL_SHA384 - if (XSTRCMP(type, "SHA384") == 0) { + if (XSTRCMP(type, WC_SN_sha384) == 0) { return WC_SHA384_DIGEST_SIZE; } else #endif #ifdef WOLFSSL_SHA512 - if (XSTRCMP(type, "SHA512") == 0) { + if (XSTRCMP(type, WC_SN_sha512) == 0) { return WC_SHA512_DIGEST_SIZE; } else #ifndef WOLFSSL_NOSHA512_224 - if (XSTRCMP(type, "SHA512_224") == 0) { + if (XSTRCMP(type, WC_SN_sha512_224) == 0) { return WC_SHA512_224_DIGEST_SIZE; } else #endif #ifndef WOLFSSL_NOSHA512_256 - if (XSTRCMP(type, "SHA512_256") == 0) { + if (XSTRCMP(type, WC_SN_sha512_256) == 0) { return WC_SHA512_256_DIGEST_SIZE; } else #endif #endif #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 - if (XSTRCMP(type, "SHA3_224") == 0) { + if (XSTRCMP(type, WC_SN_sha3_224) == 0) { return WC_SHA3_224_DIGEST_SIZE; } else #endif #ifndef WOLFSSL_NOSHA3_256 - if (XSTRCMP(type, "SHA3_256") == 0) { + if (XSTRCMP(type, WC_SN_sha3_256) == 0) { return WC_SHA3_256_DIGEST_SIZE; } else #endif #ifndef WOLFSSL_NOSHA3_384 - if (XSTRCMP(type, "SHA3_384") == 0) { + if (XSTRCMP(type, WC_SN_sha3_384) == 0) { return WC_SHA3_384_DIGEST_SIZE; } else #endif #ifndef WOLFSSL_NOSHA3_512 - if (XSTRCMP(type, "SHA3_512") == 0) { + if (XSTRCMP(type, WC_SN_sha3_512) == 0) { return WC_SHA3_512_DIGEST_SIZE; } else #endif #endif /* WOLFSSL_SHA3 */ #ifdef WOLFSSL_SM3 - if (XSTRCMP(type, "SM3") == 0) { + if (XSTRCMP(type, WC_SN_sm3) == 0) { return WC_SM3_DIGEST_SIZE; } #endif @@ -12182,7 +12505,7 @@ int wolfSSL_EVP_PKEY_print_public(WOLFSSL_BIO* out, case WC_EVP_PKEY_RSA: #if !defined(NO_RSA) - keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8; + keybits = wolfSSL_EVP_PKEY_bits((WOLFSSL_EVP_PKEY*)pkey); res = PrintPubKeyRSA( out, (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */ @@ -12198,7 +12521,7 @@ int wolfSSL_EVP_PKEY_print_public(WOLFSSL_BIO* out, case WC_EVP_PKEY_EC: #if defined(HAVE_ECC) - keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8; + keybits = wolfSSL_EVP_PKEY_bits((WOLFSSL_EVP_PKEY*)pkey); res = PrintPubKeyEC( out, (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */ @@ -12214,7 +12537,7 @@ int wolfSSL_EVP_PKEY_print_public(WOLFSSL_BIO* out, case WC_EVP_PKEY_DSA: #if !defined(NO_DSA) - keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8; + keybits = wolfSSL_EVP_PKEY_bits((WOLFSSL_EVP_PKEY*)pkey); res = PrintPubKeyDSA( out, (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */ @@ -12230,7 +12553,7 @@ int wolfSSL_EVP_PKEY_print_public(WOLFSSL_BIO* out, case WC_EVP_PKEY_DH: #if defined(WOLFSSL_DH_EXTRA) - keybits = wolfSSL_EVP_PKEY_size((WOLFSSL_EVP_PKEY*)pkey) * 8; + keybits = wolfSSL_EVP_PKEY_bits((WOLFSSL_EVP_PKEY*)pkey); res = PrintPubKeyDH( out, (byte*)(pkey->pkey.ptr), /* buffer for pkey raw data */ @@ -12263,64 +12586,64 @@ int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp, } #ifndef NO_SHA - if ((XSTRCMP("SHA", evp) == 0) || (XSTRCMP("SHA1", evp) == 0)) { + if ((XSTRCMP("SHA", evp) == 0) || (XSTRCMP(WC_SN_sha1, evp) == 0)) { hash = WC_HASH_TYPE_SHA; } else #endif #ifdef WOLFSSL_SHA224 - if (XSTRCMP("SHA224", evp) == 0) { + if (XSTRCMP(WC_SN_sha224, evp) == 0) { hash = WC_HASH_TYPE_SHA224; } else #endif #ifndef NO_SHA256 - if (XSTRCMP("SHA256", evp) == 0) { + if (XSTRCMP(WC_SN_sha256, evp) == 0) { hash = WC_HASH_TYPE_SHA256; } else #endif #ifdef WOLFSSL_SHA384 - if (XSTRCMP("SHA384", evp) == 0) { + if (XSTRCMP(WC_SN_sha384, evp) == 0) { hash = WC_HASH_TYPE_SHA384; } else #endif #ifdef WOLFSSL_SHA512 - if (XSTRCMP("SHA512", evp) == 0) { + if (XSTRCMP(WC_SN_sha512, evp) == 0) { hash = WC_HASH_TYPE_SHA512; } else #ifndef WOLFSSL_NOSHA512_224 - if (XSTRCMP("SHA512_224", evp) == 0) { + if (XSTRCMP(WC_SN_sha512_224, evp) == 0) { hash = WC_HASH_TYPE_SHA512_224; } else #endif #ifndef WOLFSSL_NOSHA512_256 - if (XSTRCMP("SHA512_256", evp) == 0) { + if (XSTRCMP(WC_SN_sha512_256, evp) == 0) { hash = WC_HASH_TYPE_SHA512_256; } else #endif #endif #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 - if (XSTRCMP("SHA3_224", evp) == 0) { + if (XSTRCMP(WC_SN_sha3_224, evp) == 0) { hash = WC_HASH_TYPE_SHA3_224; } else #endif #ifndef WOLFSSL_NOSHA3_256 - if (XSTRCMP("SHA3_256", evp) == 0) { + if (XSTRCMP(WC_SN_sha3_256, evp) == 0) { hash = WC_HASH_TYPE_SHA3_256; } else #endif #ifndef WOLFSSL_NOSHA3_384 - if (XSTRCMP("SHA3_384", evp) == 0) { + if (XSTRCMP(WC_SN_sha3_384, evp) == 0) { hash = WC_HASH_TYPE_SHA3_384; } else #endif #ifndef WOLFSSL_NOSHA3_512 - if (XSTRCMP("SHA3_512", evp) == 0) { + if (XSTRCMP(WC_SN_sha3_512, evp) == 0) { hash = WC_HASH_TYPE_SHA3_512; } else #endif #endif /* WOLFSSL_SHA3 */ #ifdef WOLFSSL_SM3 - if (XSTRCMP("SM3", evp) == 0) { + if (XSTRCMP(WC_SN_sm3, evp) == 0) { hash = WC_HASH_TYPE_SM3; } else #endif @@ -12330,12 +12653,12 @@ int wolfSSL_EVP_get_hashinfo(const WOLFSSL_EVP_MD* evp, } else #endif #ifndef NO_MD4 - if (XSTRCMP("MD4", evp) == 0) { + if (XSTRCMP(WC_SN_md4, evp) == 0) { hash = WC_HASH_TYPE_MD4; } else #endif #ifndef NO_MD5 - if (XSTRCMP("MD5", evp) == 0) { + if (XSTRCMP(WC_SN_md5, evp) == 0) { hash = WC_HASH_TYPE_MD5; } else #endif diff --git a/src/wolfssl/internal.h b/src/wolfssl/internal.h index 37a381a..9cdbdb6 100644 --- a/src/wolfssl/internal.h +++ b/src/wolfssl/internal.h @@ -1,6 +1,6 @@ /* internal.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -151,15 +151,25 @@ #include #endif -#ifdef USE_WINDOWS_API +#ifdef __WATCOMC__ + #if defined(__OS2__) + #elif defined(__NT__) + #define _WINSOCKAPI_ /* block inclusion of winsock.h header file */ + #include + #undef _WINSOCKAPI_ /* undefine it for MINGW winsock2.h header file */ + #elif defined(__LINUX__) + #ifndef SINGLE_THREADED + #define WOLFSSL_PTHREADS + #include + #endif + #endif +#elif defined(USE_WINDOWS_API) #ifdef WOLFSSL_GAME_BUILD #include "system/xtl.h" #else - #if defined(_WIN32_WCE) || defined(WIN32_LEAN_AND_MEAN) - /* On WinCE winsock2.h must be included before windows.h */ - #include - #endif + #define _WINSOCKAPI_ /* block inclusion of winsock.h header file */ #include + #undef _WINSOCKAPI_ /* undefine it for MINGW winsock2.h header file */ #endif #elif defined(THREADX) #ifndef SINGLE_THREADED @@ -232,7 +242,7 @@ #endif #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) #ifdef FUSION_RTOS - #include + #include #else #include /* for close of BIO */ #endif @@ -1827,20 +1837,23 @@ enum Misc { SM2_SA_MAJOR = 7, /* Most significant byte for SM2 with SM3 */ SM2_SA_MINOR = 8, /* Least significant byte for SM2 with SM3 */ - PQC_SA_MAJOR = 0xFE,/* Most significant byte used with PQC sig algs */ + FALCON_SA_MAJOR = 0xFE,/* Most significant byte used with falcon sig algs */ + DILITHIUM_SA_MAJOR = 0x09,/* Most significant byte used with dilithium sig algs */ - /* These values for falcon and dilithium match what OQS has defined. */ + /* These values for falcon match what OQS has defined. */ FALCON_LEVEL1_SA_MAJOR = 0xFE, FALCON_LEVEL1_SA_MINOR = 0xAE, FALCON_LEVEL5_SA_MAJOR = 0xFE, FALCON_LEVEL5_SA_MINOR = 0xB1, - DILITHIUM_LEVEL2_SA_MAJOR = 0xFE, - DILITHIUM_LEVEL2_SA_MINOR = 0xD0, - DILITHIUM_LEVEL3_SA_MAJOR = 0xFE, - DILITHIUM_LEVEL3_SA_MINOR = 0xD1, - DILITHIUM_LEVEL5_SA_MAJOR = 0xFE, - DILITHIUM_LEVEL5_SA_MINOR = 0xD2, + /* these values for MLDSA (Dilithium) correspond to what is proposed in the + * IETF. */ + DILITHIUM_LEVEL2_SA_MAJOR = 0x09, + DILITHIUM_LEVEL2_SA_MINOR = 0x04, + DILITHIUM_LEVEL3_SA_MAJOR = 0x09, + DILITHIUM_LEVEL3_SA_MINOR = 0x05, + DILITHIUM_LEVEL5_SA_MAJOR = 0x09, + DILITHIUM_LEVEL5_SA_MINOR = 0x06, MIN_RSA_SHA512_PSS_BITS = 512 * 2 + 8 * 8, /* Min key size */ MIN_RSA_SHA384_PSS_BITS = 384 * 2 + 8 * 8, /* Min key size */ @@ -1893,15 +1906,17 @@ enum Misc { #define AEAD_AUTH_DATA_SZ 13 #endif -#define WOLFSSL_NAMED_GROUP_IS_FFHDE(group) \ - (MIN_FFHDE_GROUP <= (group) && (group) <= MAX_FFHDE_GROUP) -#ifdef WOLFSSL_HAVE_KYBER -#define WOLFSSL_NAMED_GROUP_IS_PQC(group) \ - ((WOLFSSL_PQC_SIMPLE_MIN <= (group) && (group) <= WOLFSSL_PQC_SIMPLE_MAX) || \ - (WOLFSSL_PQC_HYBRID_MIN <= (group) && (group) <= WOLFSSL_PQC_HYBRID_MAX)) +#define WOLFSSL_NAMED_GROUP_IS_FFDHE(group) \ + (WOLFSSL_FFDHE_START <= (group) && (group) <= WOLFSSL_FFDHE_END) +#ifdef WOLFSSL_HAVE_MLKEM +WOLFSSL_LOCAL int NamedGroupIsPqc(int group); +WOLFSSL_LOCAL int NamedGroupIsPqcHybrid(int group); +#define WOLFSSL_NAMED_GROUP_IS_PQC(group) NamedGroupIsPqc(group) +#define WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(group) NamedGroupIsPqcHybrid(group) #else -#define WOLFSSL_NAMED_GROUP_IS_PQC(group) ((void)(group), 0) -#endif /* WOLFSSL_HAVE_KYBER */ +#define WOLFSSL_NAMED_GROUP_IS_PQC(group) ((void)(group), 0) +#define WOLFSSL_NAMED_GROUP_IS_PQC_HYBRID(group) ((void)(group), 0) +#endif /* WOLFSSL_HAVE_MLKEM */ /* minimum Downgrade Minor version */ #ifndef WOLFSSL_MIN_DOWNGRADE @@ -2207,7 +2222,7 @@ WOLFSSL_LOCAL int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, WOLFSSL_LOCAL int DoTls13Finished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size, word32 totalSz, int sniff); #endif -WOLFSSL_LOCAL int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx, +WOLFSSL_TEST_VIS int DoApplicationData(WOLFSSL* ssl, byte* input, word32* inOutIdx, int sniff); /* TLS v1.3 needs these */ WOLFSSL_LOCAL int HandleTlsResumption(WOLFSSL* ssl, Suites* clSuites); @@ -2420,8 +2435,7 @@ typedef struct CipherSuite { #endif } CipherSuite; -/* use wolfSSL_API visibility to be able to test in tests/api.c */ -WOLFSSL_API void InitSuitesHashSigAlgo(byte* hashSigAlgo, int have, +WOLFSSL_TEST_VIS void InitSuitesHashSigAlgo(byte* hashSigAlgo, int have, int tls1_2, int keySz, word16* len); WOLFSSL_LOCAL int AllocateCtxSuites(WOLFSSL_CTX* ctx); WOLFSSL_LOCAL int AllocateSuites(WOLFSSL* ssl); @@ -2622,6 +2636,9 @@ struct WOLFSSL_CRL { THREAD_TYPE tid; /* monitoring thread */ wolfSSL_CRL_mfd_t mfd; int setup; /* thread is setup predicate */ +#endif +#ifdef OPENSSL_ALL + wolfSSL_Ref ref; #endif void* heap; /* heap hint for dynamic memory */ }; @@ -3099,6 +3116,7 @@ typedef struct RpkState { #endif /* HAVE_RPK */ #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) +#define ECH_ACCEPT_CONFIRMATION_SZ 8 typedef enum { ECH_TYPE_OUTER = 0, @@ -3133,11 +3151,13 @@ typedef struct WOLFSSL_EchConfig { typedef struct WOLFSSL_ECH { Hpke* hpke; + HpkeBaseContext* hpkeContext; const byte* aad; void* ephemeralKey; WOLFSSL_EchConfig* echConfig; byte* innerClientHello; byte* outerClientPayload; + byte* confBuf; EchCipherSuite cipherSuite; word16 aadLen; word16 paddingLen; @@ -3148,12 +3168,17 @@ typedef struct WOLFSSL_ECH { byte type; byte configId; byte enc[HPKE_Npk_MAX]; + byte innerCount; } WOLFSSL_ECH; WOLFSSL_LOCAL int EchConfigGetSupportedCipherSuite(WOLFSSL_EchConfig* config); WOLFSSL_LOCAL int TLSX_FinalizeEch(WOLFSSL_ECH* ech, byte* aad, word32 aadLen); + +WOLFSSL_LOCAL int SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap, + const byte* echConfigs, word32 echConfigsLen); + WOLFSSL_LOCAL int GetEchConfig(WOLFSSL_EchConfig* config, byte* output, word32* outputLen); @@ -3368,9 +3393,9 @@ WOLFSSL_LOCAL int TLSX_CSR2_ForceRequest(WOLFSSL* ssl); #endif #if defined(WOLFSSL_PUBLIC_ASN) && defined(HAVE_PK_CALLBACKS) -/* Internal callback guarded by WOLFSSL_PUBLIC_ASN because of DecodedCert. */ +/* Internal callback guarded by WOLFSSL_TEST_VIS because of DecodedCert. */ typedef int (*CallbackProcessPeerCert)(WOLFSSL* ssl, DecodedCert* p_cert); -WOLFSSL_API void wolfSSL_CTX_SetProcessPeerCertCb(WOLFSSL_CTX* ctx, +WOLFSSL_TEST_VIS void wolfSSL_CTX_SetProcessPeerCertCb(WOLFSSL_CTX* ctx, CallbackProcessPeerCert cb); #endif /* DecodedCert && HAVE_PK_CALLBACKS */ @@ -3589,9 +3614,9 @@ typedef struct KeyShareEntry { word32 keyLen; /* Key size (bytes) */ byte* pubKey; /* Public key */ word32 pubKeyLen; /* Public key length */ -#if !defined(NO_DH) || defined(WOLFSSL_HAVE_KYBER) - byte* privKey; /* Private key - DH and PQ KEMs only */ - word32 privKeyLen;/* Only for PQ KEMs. */ +#if !defined(NO_DH) || defined(WOLFSSL_HAVE_MLKEM) + byte* privKey; /* Private key */ + word32 privKeyLen;/* Private key length - PQC only */ #endif #ifdef WOLFSSL_ASYNC_CRYPT int lastRet; @@ -4143,6 +4168,8 @@ struct WOLFSSL_CTX { CallbackGenPreMaster GenPreMasterCb; /* User generate master secret handler */ CallbackGenMasterSecret GenMasterCb; + /* User generate Extended master secret handler */ + CallbackGenExtMasterSecret GenExtMasterCb; /* User generate session key handler */ CallbackGenSessionKey GenSessionKeyCb; /* User setting encrypt keys handler */ @@ -4672,8 +4699,7 @@ WOLFSSL_LOCAL WOLFSSL_SESSION* wolfSSL_GetSession( WOLFSSL* ssl, byte* masterSecret, byte restoreSessionCerts); WOLFSSL_LOCAL void SetupSession(WOLFSSL* ssl); WOLFSSL_LOCAL void AddSession(WOLFSSL* ssl); -/* use wolfSSL_API visibility to be able to test in tests/api.c */ -WOLFSSL_API int AddSessionToCache(WOLFSSL_CTX* ctx, +WOLFSSL_TEST_VIS int AddSessionToCache(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* addSession, const byte* id, byte idSz, int* sessionIndex, int side, word16 useTicket, ClientSession** clientCacheEntry); #ifndef NO_CLIENT_CACHE @@ -4689,8 +4715,7 @@ WOLFSSL_LOCAL int TlsSessionCacheGetAndRdLock(const byte *id, WOLFSSL_LOCAL int TlsSessionCacheGetAndWrLock(const byte *id, WOLFSSL_SESSION **sess, word32 *lockedRow, byte side); WOLFSSL_LOCAL void EvictSessionFromCache(WOLFSSL_SESSION* session); -/* WOLFSSL_API to test it in tests/api.c */ -WOLFSSL_API int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output); +WOLFSSL_TEST_VIS int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output); WOLFSSL_LOCAL int wolfSSL_SetSession(WOLFSSL* ssl, WOLFSSL_SESSION* session); WOLFSSL_LOCAL void wolfSSL_FreeSession(WOLFSSL_CTX* ctx, WOLFSSL_SESSION* session); @@ -4799,9 +4824,9 @@ typedef struct Buffers { buffer clearOutputBuffer; buffer sig; /* signature data */ buffer digest; /* digest data */ - int prevSent; /* previous plain text bytes sent + word32 prevSent; /* previous plain text bytes sent when got WANT_WRITE */ - int plainSz; /* plain text bytes in buffer to send + word32 plainSz; /* plain text bytes in buffer to send when got WANT_WRITE */ byte weOwnCert; /* SSL own cert flag */ byte weOwnCertChain; /* SSL own cert chain flag */ @@ -5072,7 +5097,8 @@ struct Options { word16 useDtlsCID:1; #endif /* WOLFSSL_DTLS_CID */ #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) - word16 useEch:1; /* Do we have a valid config */ + word16 useEch:1; + word16 echAccepted:1; byte disableECH:1; /* Did the user disable ech */ #endif #ifdef WOLFSSL_SEND_HRR_COOKIE @@ -5385,6 +5411,7 @@ struct WOLFSSL_X509 { byte keyUsageCrit:1; byte extKeyUsageCrit:1; byte subjKeyIdSet:1; + byte pathLengthSet:1; byte subjKeyIdCrit:1; byte basicConstSet:1; @@ -5437,6 +5464,10 @@ struct WOLFSSL_X509 { /* Alternative Signature Value */ byte *altSigValDer; int altSigValLen; + + byte sapkiCrit:1; + byte altSigAlgCrit:1; + byte altSigValCrit:1; #endif /* WOLFSSL_DUAL_ALG_CERTS */ }; @@ -5780,16 +5811,16 @@ struct WOLFSSL { WOLFSSL_CTX* initial_ctx; /* preserve session key materials */ #endif Suites* suites; /* Only need during handshake. Can be NULL when - * re-using the context's object. When WOLFSSL + * reusing the context's object. When WOLFSSL * object needs separate instance of suites use * AllocateSuites(). */ -#ifdef OPENSSL_EXTRA - const Suites* clSuites; -#endif + Suites* clSuites; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \ defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) WOLF_STACK_OF(WOLFSSL_CIPHER)* suitesStack; /* stack of available cipher * suites */ + WOLF_STACK_OF(WOLFSSL_CIPHER)* clSuitesStack; /* stack of client cipher + * suites */ #endif Arrays* arrays; #ifdef WOLFSSL_TLS13 @@ -5799,6 +5830,7 @@ struct WOLFSSL { HS_Hashes* hsHashes; #if defined(WOLFSSL_TLS13) && defined(HAVE_ECH) HS_Hashes* hsHashesEch; + HS_Hashes* hsHashesEchInner; #endif void* IOCB_ReadCtx; void* IOCB_WriteCtx; @@ -6118,12 +6150,10 @@ struct WOLFSSL { void* ocspIOCtx; byte ocspProducedDate[MAX_DATE_SZ]; int ocspProducedDateFormat; - #ifdef OPENSSL_EXTRA + #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) byte* ocspResp; int ocspRespSz; - #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) - char* url; - #endif + char* url; #endif #if defined(WOLFSSL_TLS13) && defined(HAVE_CERTIFICATE_STATUS_REQUEST) word32 response_idx; @@ -6190,6 +6220,7 @@ struct WOLFSSL { #endif /* NO_RSA */ void* GenPreMasterCtx; /* Generate Premaster Callback Context */ void* GenMasterCtx; /* Generate Master Callback Context */ + void* GenExtMasterCtx; /* Generate Extended Master Callback Context */ void* GenSessionKeyCtx; /* Generate Session Key Callback Context */ void* EncryptKeysCtx; /* Set Encrypt keys Callback Context */ void* TlsFinishedCtx; /* Generate Tls Finished Callback Context */ @@ -6224,6 +6255,7 @@ struct WOLFSSL { #if defined(OPENSSL_EXTRA) WOLFSSL_STACK* supportedCiphers; /* Used in wolfSSL_get_ciphers_compat */ WOLFSSL_STACK* peerCertChain; /* Used in wolfSSL_get_peer_cert_chain */ + WOLFSSL_STACK* verifiedChain; /* peer cert chain to CA */ #ifdef KEEP_OUR_CERT WOLFSSL_STACK* ourCertChain; /* Used in wolfSSL_add1_chain_cert */ #endif @@ -6347,7 +6379,7 @@ WOLFSSL_LOCAL int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup); WOLFSSL_LOCAL int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup); WOLFSSL_LOCAL int ReinitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup); WOLFSSL_LOCAL void FreeSSL(WOLFSSL* ssl, void* heap); -WOLFSSL_API void wolfSSL_ResourceFree(WOLFSSL* ssl); /* Micrium uses */ +WOLFSSL_TEST_VIS void wolfSSL_ResourceFree(WOLFSSL* ssl); /* Micrium uses */ #ifndef OPENSSL_COEXIST #define SSL_ResourceFree wolfSSL_ResourceFree #endif @@ -6496,7 +6528,7 @@ WOLFSSL_LOCAL int DoClientTicket_ex(const WOLFSSL* ssl, PreSharedKey* psk, WOLFSSL_LOCAL int DoClientTicket(WOLFSSL* ssl, const byte* input, word32 len); #endif /* HAVE_SESSION_TICKET */ -WOLFSSL_LOCAL int SendData(WOLFSSL* ssl, const void* data, int sz); +WOLFSSL_LOCAL int SendData(WOLFSSL* ssl, const void* data, size_t sz); #ifdef WOLFSSL_THREADED_CRYPT WOLFSSL_LOCAL int SendAsyncData(WOLFSSL* ssl); #endif @@ -6517,7 +6549,7 @@ WOLFSSL_LOCAL int SendHelloRequest(WOLFSSL* ssl); WOLFSSL_LOCAL int SendCertificateStatus(WOLFSSL* ssl); WOLFSSL_LOCAL int SendServerKeyExchange(WOLFSSL* ssl); WOLFSSL_LOCAL int SendBuffered(WOLFSSL* ssl); -WOLFSSL_LOCAL int ReceiveData(WOLFSSL* ssl, byte* output, int sz, int peek); +WOLFSSL_LOCAL int ReceiveData(WOLFSSL* ssl, byte* output, size_t sz, int peek); WOLFSSL_LOCAL int SendFinished(WOLFSSL* ssl); WOLFSSL_LOCAL int RetrySendAlert(WOLFSSL* ssl); WOLFSSL_LOCAL int SendAlert(WOLFSSL* ssl, int severity, int type); @@ -6713,18 +6745,15 @@ WOLFSSL_LOCAL word32 MacSize(const WOLFSSL* ssl); #ifdef WOLFSSL_DTLS WOLFSSL_LOCAL DtlsMsg* DtlsMsgNew(word32 sz, byte tx, void* heap); WOLFSSL_LOCAL void DtlsMsgDelete(DtlsMsg* item, void* heap); - /* Use WOLFSSL_API to enable src/api.c testing */ - WOLFSSL_API void DtlsMsgListDelete(DtlsMsg* head, void* heap); + WOLFSSL_TEST_VIS void DtlsMsgListDelete(DtlsMsg* head, void* heap); WOLFSSL_LOCAL void DtlsTxMsgListClean(WOLFSSL* ssl); WOLFSSL_LOCAL int DtlsMsgSet(DtlsMsg* msg, word32 seq, word16 epoch, const byte* data, byte type, word32 fragOffset, word32 fragSz, void* heap, word32 totalLen, byte encrypted); - /* Use WOLFSSL_API to enable src/api.c testing */ - WOLFSSL_API DtlsMsg* DtlsMsgFind(DtlsMsg* head, word16 epoch, word32 seq); + WOLFSSL_TEST_VIS DtlsMsg* DtlsMsgFind(DtlsMsg* head, word16 epoch, word32 seq); - /* Use WOLFSSL_API to enable src/api.c testing */ - WOLFSSL_API void DtlsMsgStore(WOLFSSL* ssl, word16 epoch, word32 seq, + WOLFSSL_TEST_VIS void DtlsMsgStore(WOLFSSL* ssl, word16 epoch, word32 seq, const byte* data, word32 dataSz, byte type, word32 fragOffset, word32 fragSz, void* heap); @@ -6914,8 +6943,7 @@ WOLFSSL_LOCAL int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, int sizeOnly, int asyncOkay, int epochOrder); #ifdef WOLFSSL_TLS13 -/* Use WOLFSSL_API to use this function in tests/api.c */ -WOLFSSL_API int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input, +WOLFSSL_TEST_VIS int BuildTls13Message(WOLFSSL* ssl, byte* output, int outSz, const byte* input, int inSz, int type, int hashOutput, int sizeOnly, int asyncOkay); WOLFSSL_LOCAL int Tls13UpdateKeys(WOLFSSL* ssl); #endif @@ -6972,7 +7000,7 @@ WOLFSSL_LOCAL word32 nid2oid(int nid, int grp); #endif #ifdef WOLFSSL_DTLS -WOLFSSL_API int wolfSSL_DtlsUpdateWindow(word16 cur_hi, word32 cur_lo, +WOLFSSL_TEST_VIS int wolfSSL_DtlsUpdateWindow(word16 cur_hi, word32 cur_lo, word16* next_hi, word32* next_lo, word32 *window); WOLFSSL_LOCAL int DtlsUpdateWindow(WOLFSSL* ssl); WOLFSSL_LOCAL void DtlsResetState(WOLFSSL *ssl); @@ -6982,8 +7010,7 @@ WOLFSSL_LOCAL void DtlsSetSeqNumForReply(WOLFSSL* ssl); #ifdef WOLFSSL_DTLS13 -/* Use WOLFSSL_API to use this function in tests/api.c */ -WOLFSSL_API struct Dtls13Epoch* Dtls13GetEpoch(WOLFSSL* ssl, +WOLFSSL_TEST_VIS struct Dtls13Epoch* Dtls13GetEpoch(WOLFSSL* ssl, w64wrapper epochNumber); WOLFSSL_LOCAL void Dtls13SetOlderEpochSide(WOLFSSL* ssl, w64wrapper epochNumber, int side); @@ -7019,6 +7046,7 @@ WOLFSSL_LOCAL int Dtls13HandshakeSend(WOLFSSL* ssl, byte* output, word16 output_size, word16 length, enum HandShakeType handshake_type, int hash_output); WOLFSSL_LOCAL int Dtls13RecordRecvd(WOLFSSL* ssl); +WOLFSSL_TEST_VIS int Dtls13CheckEpoch(WOLFSSL* ssl, enum HandShakeType type); WOLFSSL_LOCAL int Dtls13HandshakeRecv(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 totalSz); WOLFSSL_LOCAL int Dtls13HandshakeAddHeader(WOLFSSL* ssl, byte* output, @@ -7032,7 +7060,10 @@ WOLFSSL_LOCAL int Dtls13ReconstructEpochNumber(WOLFSSL* ssl, byte epochBits, w64wrapper* epoch); WOLFSSL_LOCAL int Dtls13ReconstructSeqNumber(WOLFSSL* ssl, Dtls13UnifiedHdrInfo* hdrInfo, w64wrapper* out); +WOLFSSL_TEST_VIS int Dtls13WriteAckMessage(WOLFSSL* ssl, + Dtls13RecordNumber* recordNumberList, word32* length); WOLFSSL_LOCAL int SendDtls13Ack(WOLFSSL* ssl); +WOLFSSL_TEST_VIS int Dtls13RtxAddAck(WOLFSSL* ssl, w64wrapper epoch, w64wrapper seq); WOLFSSL_LOCAL int Dtls13RtxProcessingCertificate(WOLFSSL* ssl, byte* input, word32 inputSize); WOLFSSL_LOCAL int Dtls13HashHandshake(WOLFSSL* ssl, const byte* input, @@ -7073,9 +7104,8 @@ typedef struct CRYPTO_EX_cb_ctx { struct CRYPTO_EX_cb_ctx* next; } CRYPTO_EX_cb_ctx; -/* use wolfSSL_API visibility to be able to clear in tests/api.c */ -WOLFSSL_API extern CRYPTO_EX_cb_ctx* crypto_ex_cb_ctx_session; -WOLFSSL_API void crypto_ex_cb_free(CRYPTO_EX_cb_ctx* cb_ctx); +WOLFSSL_TEST_VIS extern CRYPTO_EX_cb_ctx* crypto_ex_cb_ctx_session; +WOLFSSL_TEST_VIS void crypto_ex_cb_free(CRYPTO_EX_cb_ctx* cb_ctx); WOLFSSL_LOCAL void crypto_ex_cb_setup_new_data(void *new_obj, CRYPTO_EX_cb_ctx* cb_ctx, WOLFSSL_CRYPTO_EX_DATA* ex_data); WOLFSSL_LOCAL void crypto_ex_cb_free_data(void *obj, CRYPTO_EX_cb_ctx* cb_ctx, @@ -7157,6 +7187,7 @@ WOLFSSL_LOCAL int TranslateErrorToAlert(int err); #if defined(OPENSSL_EXTRA) || defined(WOLFSSL_WPAS_SMALL) WOLFSSL_LOCAL void* wolfssl_sk_pop_type(WOLFSSL_STACK* sk, WOLF_STACK_TYPE type); +WOLFSSL_LOCAL void* wolfSSL_sk_pop_node(WOLFSSL_STACK* sk, int idx); WOLFSSL_LOCAL WOLFSSL_STACK* wolfssl_sk_new_type(WOLF_STACK_TYPE type); WOLFSSL_LOCAL int wolfssl_asn1_obj_set(WOLFSSL_ASN1_OBJECT* obj, diff --git a/src/wolfssl/ocsp.h b/src/wolfssl/ocsp.h index f2e234f..69b5c14 100644 --- a/src/wolfssl/ocsp.h +++ b/src/wolfssl/ocsp.h @@ -1,6 +1,6 @@ /* ocsp.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/aes.h b/src/wolfssl/openssl/aes.h index 25110c8..4710f72 100644 --- a/src/wolfssl/openssl/aes.h +++ b/src/wolfssl/openssl/aes.h @@ -1,6 +1,6 @@ /* aes.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/asn1.h b/src/wolfssl/openssl/asn1.h index 5b4f25a..b9e2c19 100644 --- a/src/wolfssl/openssl/asn1.h +++ b/src/wolfssl/openssl/asn1.h @@ -1,6 +1,6 @@ /* asn1.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -39,6 +39,7 @@ #define d2i_ASN1_OBJECT wolfSSL_d2i_ASN1_OBJECT #define c2i_ASN1_OBJECT wolfSSL_c2i_ASN1_OBJECT +#define V_ASN1_BIT_STRING WOLFSSL_V_ASN1_BIT_STRING #define V_ASN1_INTEGER WOLFSSL_V_ASN1_INTEGER #define V_ASN1_NEG WOLFSSL_V_ASN1_NEG #define V_ASN1_NEG_INTEGER WOLFSSL_V_ASN1_NEG_INTEGER @@ -218,11 +219,11 @@ typedef struct WOLFSSL_ASN1_ITEM WOLFSSL_ASN1_ITEM; mtype##_member_data, \ sizeof(mtype##_member_data) / sizeof(WOLFSSL_ASN1_TEMPLATE), \ sizeof(mtype) ,\ - OFFSETOF(mtype, type) \ + WC_OFFSETOF(mtype, type) \ }; #define ASN1_TYPE(type, member, tag, first_byte, exp, seq) \ - OFFSETOF(type, member), tag, first_byte, exp, seq + WC_OFFSETOF(type, member), tag, first_byte, exp, seq /* Function callbacks need to be defined immediately otherwise we will * incorrectly expand the type. Ex: ASN1_INTEGER -> WOLFSSL_ASN1_INTEGER */ diff --git a/src/wolfssl/openssl/asn1t.h b/src/wolfssl/openssl/asn1t.h index e74ee26..2a52b3b 100644 --- a/src/wolfssl/openssl/asn1t.h +++ b/src/wolfssl/openssl/asn1t.h @@ -1,6 +1,6 @@ /* asn1t.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/bio.h b/src/wolfssl/openssl/bio.h index cf6571b..73214ab 100644 --- a/src/wolfssl/openssl/bio.h +++ b/src/wolfssl/openssl/bio.h @@ -1,6 +1,6 @@ /* bio.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -104,6 +104,7 @@ #endif #define BIO_int_ctrl wolfSSL_BIO_int_ctrl #define BIO_reset wolfSSL_BIO_reset +#define BIO_s_null wolfSSL_BIO_s_null #define BIO_s_file wolfSSL_BIO_s_file #define BIO_s_bio wolfSSL_BIO_s_bio #define BIO_s_socket wolfSSL_BIO_s_socket diff --git a/src/wolfssl/openssl/bn.h b/src/wolfssl/openssl/bn.h index ed8ae43..45411f5 100644 --- a/src/wolfssl/openssl/bn.h +++ b/src/wolfssl/openssl/bn.h @@ -1,6 +1,6 @@ /* bn.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -40,7 +40,7 @@ typedef struct WOLFSSL_BIGNUM { int neg; /* openssh deference */ void *internal; /* our big num */ -#if !defined(NO_BIG_INT) || defined(WOLFSSL_SP_MATH) +#if !defined(NO_BIG_INT) mp_int mpi; #endif } WOLFSSL_BIGNUM; @@ -77,8 +77,15 @@ typedef struct WOLFSSL_BIGNUM { #define WOLFSSL_BN_MAX_VAL ((BN_ULONG)-1) -typedef struct WOLFSSL_BN_CTX WOLFSSL_BN_CTX; -typedef struct WOLFSSL_BN_GENCB WOLFSSL_BN_GENCB; +struct WOLFSSL_BN_CTX_LIST { + WOLFSSL_BIGNUM* bn; + struct WOLFSSL_BN_CTX_LIST* next; +}; +typedef struct WOLFSSL_BN_CTX { + struct WOLFSSL_BN_CTX_LIST* list; +} WOLFSSL_BN_CTX; +typedef struct WOLFSSL_BN_MONT_CTX WOLFSSL_BN_MONT_CTX; +typedef struct WOLFSSL_BN_GENCB WOLFSSL_BN_GENCB; WOLFSSL_API WOLFSSL_BN_CTX* wolfSSL_BN_CTX_new(void); WOLFSSL_API void wolfSSL_BN_CTX_init(WOLFSSL_BN_CTX* ctx); @@ -151,6 +158,7 @@ WOLFSSL_API int wolfSSL_BN_lshift(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* bn, WOLFSSL_API int wolfSSL_BN_add_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w); WOLFSSL_API int wolfSSL_BN_sub_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w); WOLFSSL_API int wolfSSL_BN_mul_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w); +WOLFSSL_API int wolfSSL_BN_div_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w); WOLFSSL_API int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n); WOLFSSL_API int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n); WOLFSSL_API int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w); @@ -184,6 +192,13 @@ WOLFSSL_API WOLFSSL_BIGNUM *wolfSSL_BN_mod_inverse( const WOLFSSL_BIGNUM *n, WOLFSSL_BN_CTX *ctx); +WOLFSSL_API WOLFSSL_BN_MONT_CTX* wolfSSL_BN_MONT_CTX_new(void); +WOLFSSL_API void wolfSSL_BN_MONT_CTX_free(WOLFSSL_BN_MONT_CTX *mont); +WOLFSSL_API int wolfSSL_BN_MONT_CTX_set(WOLFSSL_BN_MONT_CTX *mont, + const WOLFSSL_BIGNUM *mod, WOLFSSL_BN_CTX *ctx); +WOLFSSL_API int wolfSSL_BN_mod_exp_mont_word(WOLFSSL_BIGNUM *r, + WOLFSSL_BN_ULONG a, const WOLFSSL_BIGNUM *p, const WOLFSSL_BIGNUM *m, + WOLFSSL_BN_CTX *ctx, WOLFSSL_BN_MONT_CTX *mont); #if !defined(OPENSSL_COEXIST) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) @@ -194,13 +209,19 @@ WOLFSSL_API WOLFSSL_BIGNUM *wolfSSL_BN_mod_inverse( #define BN_RAND_BOTTOM_ANY WOLFSSL_BN_RAND_BOTTOM_ANY #define BN_RAND_BOTTOM_ODD WOLFSSL_BN_RAND_BOTTOM_ODD -typedef WOLFSSL_BIGNUM BIGNUM; -typedef WOLFSSL_BN_CTX BN_CTX; -typedef WOLFSSL_BN_GENCB BN_GENCB; +typedef WOLFSSL_BIGNUM BIGNUM; +typedef WOLFSSL_BN_CTX BN_CTX; +typedef WOLFSSL_BN_MONT_CTX BN_MONT_CTX; +typedef WOLFSSL_BN_GENCB BN_GENCB; +#ifndef NO_WOLFSSL_BN_CTX #define BN_CTX_new wolfSSL_BN_CTX_new #define BN_CTX_init wolfSSL_BN_CTX_init #define BN_CTX_free wolfSSL_BN_CTX_free +#else +#define BN_CTX_new() ((BN_CTX*)-1) +#define BN_CTX_free(x) ((void)(x)) +#endif #define BN_new wolfSSL_BN_new #if !defined(USE_INTEGER_HEAP_MATH) && !defined(HAVE_WOLF_BIGINT) @@ -228,6 +249,8 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_mod wolfSSL_BN_mod #define BN_mod_exp wolfSSL_BN_mod_exp +#define BN_mod_exp_mont(a,b,c,d,e,f) \ + ((void)(f), wolfSSL_BN_mod_exp((a),(b),(c),(d),(e))) #define BN_mod_mul wolfSSL_BN_mod_mul #define BN_sub wolfSSL_BN_sub #define BN_mul wolfSSL_BN_mul @@ -257,6 +280,7 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_add_word wolfSSL_BN_add_word #define BN_mul_word wolfSSL_BN_mul_word #define BN_sub_word wolfSSL_BN_sub_word +#define BN_div_word wolfSSL_BN_div_word #define BN_add wolfSSL_BN_add #define BN_mod_add wolfSSL_BN_mod_add #define BN_set_word wolfSSL_BN_set_word @@ -290,6 +314,11 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_prime_checks 0 +#define BN_MONT_CTX_new wolfSSL_BN_MONT_CTX_new +#define BN_MONT_CTX_free wolfSSL_BN_MONT_CTX_free +#define BN_MONT_CTX_set wolfSSL_BN_MONT_CTX_set +#define BN_mod_exp_mont_word wolfSSL_BN_mod_exp_mont_word + #endif /* !OPENSSL_COEXIST && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ diff --git a/src/wolfssl/openssl/buffer.h b/src/wolfssl/openssl/buffer.h index c4195cf..548d744 100644 --- a/src/wolfssl/openssl/buffer.h +++ b/src/wolfssl/openssl/buffer.h @@ -1,6 +1,6 @@ /* buffer.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/camellia.h b/src/wolfssl/openssl/camellia.h index 0cad9c9..fe5b17c 100644 --- a/src/wolfssl/openssl/camellia.h +++ b/src/wolfssl/openssl/camellia.h @@ -1,6 +1,6 @@ /* camellia.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/cmac.h b/src/wolfssl/openssl/cmac.h index 120fd1d..489396c 100644 --- a/src/wolfssl/openssl/cmac.h +++ b/src/wolfssl/openssl/cmac.h @@ -1,6 +1,6 @@ /* cmac.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/cms.h b/src/wolfssl/openssl/cms.h index 7febb67..291c08d 100644 --- a/src/wolfssl/openssl/cms.h +++ b/src/wolfssl/openssl/cms.h @@ -1,6 +1,6 @@ /* cms.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/compat_types.h b/src/wolfssl/openssl/compat_types.h index 00bfde1..58113c4 100644 --- a/src/wolfssl/openssl/compat_types.h +++ b/src/wolfssl/openssl/compat_types.h @@ -1,6 +1,6 @@ /* compat_types.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/conf.h b/src/wolfssl/openssl/conf.h index 411a3e0..d2e2eb4 100644 --- a/src/wolfssl/openssl/conf.h +++ b/src/wolfssl/openssl/conf.h @@ -1,6 +1,6 @@ /* conf.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/crypto.h b/src/wolfssl/openssl/crypto.h index 33a279a..e05468e 100644 --- a/src/wolfssl/openssl/crypto.h +++ b/src/wolfssl/openssl/crypto.h @@ -1,6 +1,6 @@ /* crypto.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/des.h b/src/wolfssl/openssl/des.h index 6db0df7..9554c2a 100644 --- a/src/wolfssl/openssl/des.h +++ b/src/wolfssl/openssl/des.h @@ -1,6 +1,6 @@ /* des.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/dh.h b/src/wolfssl/openssl/dh.h index 60fe59f..70b1087 100644 --- a/src/wolfssl/openssl/dh.h +++ b/src/wolfssl/openssl/dh.h @@ -1,6 +1,6 @@ /* dh.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/dsa.h b/src/wolfssl/openssl/dsa.h index 1d24ceb..d5f64bb 100644 --- a/src/wolfssl/openssl/dsa.h +++ b/src/wolfssl/openssl/dsa.h @@ -1,6 +1,6 @@ /* dsa.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/ec.h b/src/wolfssl/openssl/ec.h index 4067cff..d68217b 100644 --- a/src/wolfssl/openssl/ec.h +++ b/src/wolfssl/openssl/ec.h @@ -1,6 +1,6 @@ /* ec.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/ec25519.h b/src/wolfssl/openssl/ec25519.h index 0421ce8..92cf807 100644 --- a/src/wolfssl/openssl/ec25519.h +++ b/src/wolfssl/openssl/ec25519.h @@ -1,6 +1,6 @@ /* ec25519.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/ec448.h b/src/wolfssl/openssl/ec448.h index 89a9e1c..ce2cc7c 100644 --- a/src/wolfssl/openssl/ec448.h +++ b/src/wolfssl/openssl/ec448.h @@ -1,6 +1,6 @@ /* ec448.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/ecdh.h b/src/wolfssl/openssl/ecdh.h index 74b8c91..7fbc5a3 100644 --- a/src/wolfssl/openssl/ecdh.h +++ b/src/wolfssl/openssl/ecdh.h @@ -1,6 +1,6 @@ /* ecdh.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/ecdsa.h b/src/wolfssl/openssl/ecdsa.h index f9ba1ec..12d003f 100644 --- a/src/wolfssl/openssl/ecdsa.h +++ b/src/wolfssl/openssl/ecdsa.h @@ -1,6 +1,6 @@ /* ecdsa.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/ed25519.h b/src/wolfssl/openssl/ed25519.h index d4c1b1b..9d67c6f 100644 --- a/src/wolfssl/openssl/ed25519.h +++ b/src/wolfssl/openssl/ed25519.h @@ -1,6 +1,6 @@ /* ed25519.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/ed448.h b/src/wolfssl/openssl/ed448.h index 3c97862..793e66f 100644 --- a/src/wolfssl/openssl/ed448.h +++ b/src/wolfssl/openssl/ed448.h @@ -1,6 +1,6 @@ /* ed448.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/err.h b/src/wolfssl/openssl/err.h index 708498a..6723ded 100644 --- a/src/wolfssl/openssl/err.h +++ b/src/wolfssl/openssl/err.h @@ -1,6 +1,6 @@ /* err.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/evp.h b/src/wolfssl/openssl/evp.h index 02b5c8b..3192dbf 100644 --- a/src/wolfssl/openssl/evp.h +++ b/src/wolfssl/openssl/evp.h @@ -1,6 +1,6 @@ /* evp.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -221,6 +221,9 @@ typedef union { #ifdef WOLFSSL_SM3 wc_Sm3 sm3; #endif + #if defined(WOLFSSL_SHAKE128) || defined(WOLFSSL_SHAKE256) + wc_Shake shake; + #endif } WOLFSSL_Hasher; @@ -798,6 +801,7 @@ WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_blake2s256(void); WOLFSSL_API void wolfSSL_EVP_init(void); WOLFSSL_API int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* type); WOLFSSL_API int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type); +WOLFSSL_API unsigned long wolfSSL_EVP_MD_flags(const WOLFSSL_EVP_MD *md); WOLFSSL_API int wolfSSL_EVP_MD_block_size(const WOLFSSL_EVP_MD* type); WOLFSSL_API int wolfSSL_EVP_MD_pkey_type(const WOLFSSL_EVP_MD* type); @@ -823,6 +827,8 @@ WOLFSSL_API int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* unsigned int* s); WOLFSSL_API int wolfSSL_EVP_DigestFinal_ex(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md, unsigned int* s); +WOLFSSL_API int wolfSSL_EVP_DigestFinalXOF(WOLFSSL_EVP_MD_CTX* ctx, + unsigned char* md, size_t sz); WOLFSSL_API int wolfSSL_EVP_DigestSignUpdate(WOLFSSL_EVP_MD_CTX *ctx, const void *d, unsigned int cnt); WOLFSSL_API int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, @@ -1096,6 +1102,7 @@ WOLFSSL_API int wolfSSL_EVP_DigestVerifyInit(WOLFSSL_EVP_MD_CTX *ctx, WOLFSSL_API int wolfSSL_EVP_Digest(const unsigned char* in, int inSz, unsigned char* out, unsigned int* outSz, const WOLFSSL_EVP_MD* evp, WOLFSSL_ENGINE* eng); +WOLFSSL_API const char* wolfSSL_EVP_CIPHER_type_string(unsigned int type); WOLFSSL_API int wolfSSL_EVP_CipherInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx, const WOLFSSL_EVP_CIPHER* type, WOLFSSL_ENGINE *impl, @@ -1144,6 +1151,7 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx, #define WOLFSSL_EVP_CTRL_CCM_SET_TAG WOLFSSL_EVP_CTRL_AEAD_SET_TAG #define WOLFSSL_EVP_CTRL_CCM_SET_L 0x14 #define WOLFSSL_EVP_CTRL_CCM_SET_MSGLEN 0x15 +#define WOLFSSL_EVP_MD_FLAG_XOF 0x2 #define WOLFSSL_NO_PADDING_BLOCK_SIZE 1 @@ -1256,12 +1264,15 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx, #define EVP_MD_CTX_set_flags(ctx, flags) WC_DO_NOTHING #endif +#define EVP_MD_FLAG_XOF WOLFSSL_EVP_MD_FLAG_XOF + #define EVP_Digest wolfSSL_EVP_Digest #define EVP_DigestInit wolfSSL_EVP_DigestInit #define EVP_DigestInit_ex wolfSSL_EVP_DigestInit_ex #define EVP_DigestUpdate wolfSSL_EVP_DigestUpdate #define EVP_DigestFinal wolfSSL_EVP_DigestFinal #define EVP_DigestFinal_ex wolfSSL_EVP_DigestFinal_ex +#define EVP_DigestFinalXOF wolfSSL_EVP_DigestFinalXOF #define EVP_DigestSignInit wolfSSL_EVP_DigestSignInit #define EVP_DigestSignUpdate wolfSSL_EVP_DigestSignUpdate #define EVP_DigestSignFinal wolfSSL_EVP_DigestSignFinal @@ -1311,6 +1322,7 @@ WOLFSSL_API int wolfSSL_EVP_SignInit_ex(WOLFSSL_EVP_MD_CTX* ctx, #define EVP_get_cipherbynid wolfSSL_EVP_get_cipherbynid #define EVP_get_digestbynid wolfSSL_EVP_get_digestbynid #define EVP_MD_nid wolfSSL_EVP_MD_type +#define EVP_MD_flags wolfSSL_EVP_MD_flags #define EVP_PKEY_assign wolfSSL_EVP_PKEY_assign #define EVP_PKEY_assign_RSA wolfSSL_EVP_PKEY_assign_RSA diff --git a/src/wolfssl/openssl/fips_rand.h b/src/wolfssl/openssl/fips_rand.h index 58f21b3..4142e7e 100644 --- a/src/wolfssl/openssl/fips_rand.h +++ b/src/wolfssl/openssl/fips_rand.h @@ -1,6 +1,6 @@ /* fips_rand.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/hmac.h b/src/wolfssl/openssl/hmac.h index 1a2c304..b29d4fc 100644 --- a/src/wolfssl/openssl/hmac.h +++ b/src/wolfssl/openssl/hmac.h @@ -1,6 +1,6 @@ /* hmac.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/kdf.h b/src/wolfssl/openssl/kdf.h index 295c99f..f36aedc 100644 --- a/src/wolfssl/openssl/kdf.h +++ b/src/wolfssl/openssl/kdf.h @@ -1,6 +1,6 @@ /* kdf.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/lhash.h b/src/wolfssl/openssl/lhash.h index 4c1637a..6a86992 100644 --- a/src/wolfssl/openssl/lhash.h +++ b/src/wolfssl/openssl/lhash.h @@ -1,6 +1,6 @@ /* lhash.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/md4.h b/src/wolfssl/openssl/md4.h index 9181e8d..3d0549f 100644 --- a/src/wolfssl/openssl/md4.h +++ b/src/wolfssl/openssl/md4.h @@ -1,6 +1,6 @@ /* md4.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/md5.h b/src/wolfssl/openssl/md5.h index 452b6a4..709c03f 100644 --- a/src/wolfssl/openssl/md5.h +++ b/src/wolfssl/openssl/md5.h @@ -1,6 +1,6 @@ /* md5.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/modes.h b/src/wolfssl/openssl/modes.h index e6a584c..50342bd 100644 --- a/src/wolfssl/openssl/modes.h +++ b/src/wolfssl/openssl/modes.h @@ -1,6 +1,6 @@ /* modes.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/obj_mac.h b/src/wolfssl/openssl/obj_mac.h index b4d4013..3304158 100644 --- a/src/wolfssl/openssl/obj_mac.h +++ b/src/wolfssl/openssl/obj_mac.h @@ -1,6 +1,6 @@ /* obj_mac.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -59,6 +59,27 @@ #define NID_sect571k1 WC_NID_sect571k1 #define NID_sect571r1 WC_NID_sect571r1 +/* mapping of short names */ +#define SN_md4 WC_SN_md4 +#define SN_md5 WC_SN_md5 +#define SN_sha1 WC_SN_sha1 +#define SN_sha224 WC_SN_sha224 +#define SN_sha256 WC_SN_sha256 +#define SN_sha384 WC_SN_sha384 +#define SN_sha512 WC_SN_sha512 +#define SN_sha512_224 WC_SN_sha512_224 +#define SN_sha512_256 WC_SN_sha512_256 +#define SN_sha3_224 WC_SN_sha3_224 +#define SN_sha3_256 WC_SN_sha3_256 +#define SN_sha3_384 WC_SN_sha3_384 +#define SN_sha3_512 WC_SN_sha3_512 +#define SN_shake128 WC_SN_shake128 +#define SN_shake256 WC_SN_shake256 +#define SN_blake2s256 WC_SN_blake2s256 +#define SN_blake2s512 WC_SN_blake2s512 +#define SN_blake2b512 WC_SN_blake2b512 +#define SN_sm3 WC_SN_sm3 + #endif /* !OPENSSL_COEXIST */ /* the definition is for Qt Unit test */ diff --git a/src/wolfssl/openssl/objects.h b/src/wolfssl/openssl/objects.h index 1b6ce80..3325c83 100644 --- a/src/wolfssl/openssl/objects.h +++ b/src/wolfssl/openssl/objects.h @@ -1,6 +1,6 @@ /* objects.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -29,6 +29,8 @@ #include #endif /* OPENSSL_EXTRA_SSL_GUARD */ +#include + #ifdef __cplusplus extern "C" { #endif diff --git a/src/wolfssl/openssl/ocsp.h b/src/wolfssl/openssl/ocsp.h index a6bae66..67ae0f1 100644 --- a/src/wolfssl/openssl/ocsp.h +++ b/src/wolfssl/openssl/ocsp.h @@ -1,6 +1,6 @@ /* ocsp.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/opensslv.h b/src/wolfssl/openssl/opensslv.h index 481f74e..e643a64 100644 --- a/src/wolfssl/openssl/opensslv.h +++ b/src/wolfssl/openssl/opensslv.h @@ -1,6 +1,6 @@ /* opensslv.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/ossl_typ.h b/src/wolfssl/openssl/ossl_typ.h index 8214fa3..084558d 100644 --- a/src/wolfssl/openssl/ossl_typ.h +++ b/src/wolfssl/openssl/ossl_typ.h @@ -1,6 +1,6 @@ /* ossl_typ.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/pem.h b/src/wolfssl/openssl/pem.h index 3666ab5..1cf4247 100644 --- a/src/wolfssl/openssl/pem.h +++ b/src/wolfssl/openssl/pem.h @@ -1,6 +1,6 @@ /* pem.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/pkcs12.h b/src/wolfssl/openssl/pkcs12.h index 7da2b98..a59798c 100644 --- a/src/wolfssl/openssl/pkcs12.h +++ b/src/wolfssl/openssl/pkcs12.h @@ -1,6 +1,6 @@ /* pkcs12.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/pkcs7.h b/src/wolfssl/openssl/pkcs7.h index 9a53b89..84ae285 100644 --- a/src/wolfssl/openssl/pkcs7.h +++ b/src/wolfssl/openssl/pkcs7.h @@ -1,6 +1,6 @@ /* pkcs7.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/rand.h b/src/wolfssl/openssl/rand.h index 71d6810..4c41ed7 100644 --- a/src/wolfssl/openssl/rand.h +++ b/src/wolfssl/openssl/rand.h @@ -1,6 +1,6 @@ /* rand.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/rc4.h b/src/wolfssl/openssl/rc4.h index fb51128..309174b 100644 --- a/src/wolfssl/openssl/rc4.h +++ b/src/wolfssl/openssl/rc4.h @@ -1,6 +1,6 @@ /* rc4.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/ripemd.h b/src/wolfssl/openssl/ripemd.h index a7c4247..0e80bb3 100644 --- a/src/wolfssl/openssl/ripemd.h +++ b/src/wolfssl/openssl/ripemd.h @@ -1,6 +1,6 @@ /* ripemd.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/rsa.h b/src/wolfssl/openssl/rsa.h index c414fdf..111a89e 100644 --- a/src/wolfssl/openssl/rsa.h +++ b/src/wolfssl/openssl/rsa.h @@ -1,6 +1,6 @@ /* rsa.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/safestack.h b/src/wolfssl/openssl/safestack.h index ee1f872..e059a6e 100644 --- a/src/wolfssl/openssl/safestack.h +++ b/src/wolfssl/openssl/safestack.h @@ -1,6 +1,6 @@ /* safestack.h * - * Copyright (C) 2006-2023 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/sha.h b/src/wolfssl/openssl/sha.h index 34a1962..4644a33 100644 --- a/src/wolfssl/openssl/sha.h +++ b/src/wolfssl/openssl/sha.h @@ -1,6 +1,6 @@ /* sha.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/sha3.h b/src/wolfssl/openssl/sha3.h index c2f5535..a970bfd 100644 --- a/src/wolfssl/openssl/sha3.h +++ b/src/wolfssl/openssl/sha3.h @@ -1,6 +1,6 @@ /* sha3.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/srp.h b/src/wolfssl/openssl/srp.h index d0e6123..978e05d 100644 --- a/src/wolfssl/openssl/srp.h +++ b/src/wolfssl/openssl/srp.h @@ -1,6 +1,6 @@ /* srp.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/ssl.h b/src/wolfssl/openssl/ssl.h index 959d1e6..da16168 100644 --- a/src/wolfssl/openssl/ssl.h +++ b/src/wolfssl/openssl/ssl.h @@ -1,6 +1,6 @@ /* ssl.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -289,6 +289,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define SSLv23_client_method wolfSSLv23_client_method #define SSLv2_client_method wolfSSLv2_client_method #define SSLv2_server_method wolfSSLv2_server_method +#define SSLv3_method wolfSSLv3_method #define SSLv3_server_method wolfSSLv3_server_method #define SSLv3_client_method wolfSSLv3_client_method #define TLS_client_method wolfTLS_client_method @@ -352,7 +353,9 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define SSL_write_early_data(ssl, d, dLen, len) wolfSSL_write_early_data(ssl, d, (int)(dLen), (int *)(len)) #define SSL_write wolfSSL_write +#define SSL_write_ex wolfSSL_write_ex #define SSL_read wolfSSL_read +#define SSL_read_ex wolfSSL_read_ex #define SSL_peek wolfSSL_peek #define SSL_accept wolfSSL_accept #define SSL_CTX_free wolfSSL_CTX_free @@ -432,6 +435,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define SSL_get_version wolfSSL_get_version #define SSL_get_current_cipher wolfSSL_get_current_cipher +#define SSL_get_client_ciphers wolfSSL_get_client_ciphers /* use wolfSSL_get_cipher_name for its return format */ #define SSL_get_cipher wolfSSL_get_cipher_name @@ -461,6 +465,9 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define ASN1_BOOLEAN WOLFSSL_ASN1_BOOLEAN #define X509_get_ext wolfSSL_X509_get_ext #define X509_get_ext_by_OBJ wolfSSL_X509_get_ext_by_OBJ + #define X509_OBJECT_set1_X509 wolfSSL_X509_OBJECT_set1_X509 + #define X509_OBJECT_set1_X509_CRL wolfSSL_X509_OBJECT_set1_X509_CRL + #define sk_X509_OBJECT_deep_copy wolfSSL_sk_X509_OBJECT_deep_copy #define X509_cmp wolfSSL_X509_cmp #define X509_EXTENSION_get_object wolfSSL_X509_EXTENSION_get_object #define X509_EXTENSION_get_critical wolfSSL_X509_EXTENSION_get_critical @@ -688,6 +695,7 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY; #define X509_NAME_entry_count wolfSSL_X509_NAME_entry_count #define X509_NAME_get_entry wolfSSL_X509_NAME_get_entry +#define X509_NAME_ENTRY_set wolfSSL_X509_NAME_ENTRY_set #define X509_NAME_ENTRY_get_object wolfSSL_X509_NAME_ENTRY_get_object #define X509_NAME_ENTRY_get_data wolfSSL_X509_NAME_ENTRY_get_data #define X509_NAME_ENTRY_get_object wolfSSL_X509_NAME_ENTRY_get_object @@ -717,6 +725,9 @@ typedef WOLFSSL_X509_NAME_ENTRY X509_NAME_ENTRY; #define X509_VP_FLAG_LOCKED WOLFSSL_VPARAM_LOCKED #define X509_VP_FLAG_ONCE WOLFSSL_VPARAM_ONCE +#define X509_STORE_lock(x) 1 +#define X509_STORE_unlock(x) 1 + #define X509_STORE_CTX_get_current_cert wolfSSL_X509_STORE_CTX_get_current_cert #define X509_STORE_CTX_set_verify_cb wolfSSL_X509_STORE_CTX_set_verify_cb #define X509_STORE_CTX_new wolfSSL_X509_STORE_CTX_new @@ -779,6 +790,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define X509_VERIFY_PARAM_lookup wolfSSL_X509_VERIFY_PARAM_lookup #define X509_VERIFY_PARAM_inherit wolfSSL_X509_VERIFY_PARAM_inherit #define X509_STORE_load_locations wolfSSL_X509_STORE_load_locations +#define X509_STORE_set_default_paths wolfSSL_X509_STORE_set_default_paths #define X509_STORE_get0_param wolfSSL_X509_STORE_get0_param #define X509_LOOKUP_add_dir wolfSSL_X509_LOOKUP_add_dir @@ -1104,6 +1116,10 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL_CTX_set_psk_server_callback wolfSSL_CTX_set_psk_server_callback #define SSL_set_psk_server_callback wolfSSL_set_psk_server_callback +#if !defined(USE_WINDOWS_API) && !defined(INVALID_SOCKET) + #define INVALID_SOCKET (-1) +#endif + /* system file ints for ERR_put_error */ #define SYS_F_ACCEPT WOLFSSL_SYS_ACCEPT #define SYS_F_BIND WOLFSSL_SYS_BIND @@ -1430,6 +1446,11 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE; #define SSL3_RANDOM_SIZE 32 /* same as RAN_LEN in internal.h */ +#ifndef WOLFSSL_ALLOW_SSLV3 + #undef OPENSSL_NO_SSL3 + #define OPENSSL_NO_SSL3 +#endif + /* Used as message callback types */ #define SSL3_RT_CHANGE_CIPHER_SPEC 20 #define SSL3_RT_ALERT 21 @@ -1810,6 +1831,8 @@ typedef WOLFSSL_CONF_CTX SSL_CONF_CTX; #define SSL_CONF_cmd wolfSSL_CONF_cmd #define SSL_CONF_cmd_value_type wolfSSL_CONF_cmd_value_type +#define SSL_OP_LEGACY_SERVER_CONNECT 0 + #endif /* !OPENSSL_COEXIST && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ diff --git a/src/wolfssl/openssl/stack.h b/src/wolfssl/openssl/stack.h index fe697c4..16f71d3 100644 --- a/src/wolfssl/openssl/stack.h +++ b/src/wolfssl/openssl/stack.h @@ -1,6 +1,6 @@ /* stack.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/tls1.h b/src/wolfssl/openssl/tls1.h index 1f8895c..b1992fc 100644 --- a/src/wolfssl/openssl/tls1.h +++ b/src/wolfssl/openssl/tls1.h @@ -1,6 +1,6 @@ /* tls1.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/txt_db.h b/src/wolfssl/openssl/txt_db.h index b8aa56f..aa05d92 100644 --- a/src/wolfssl/openssl/txt_db.h +++ b/src/wolfssl/openssl/txt_db.h @@ -1,6 +1,6 @@ /* txt_db.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/x509.h b/src/wolfssl/openssl/x509.h index f2bfb1b..e1eb78e 100644 --- a/src/wolfssl/openssl/x509.h +++ b/src/wolfssl/openssl/x509.h @@ -1,6 +1,6 @@ /* x509.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -111,6 +111,8 @@ #define X509_V_ERR_UNABLE_TO_GET_CRL WOLFSSL_X509_V_ERR_UNABLE_TO_GET_CRL #define X509_V_ERR_CRL_HAS_EXPIRED WOLFSSL_X509_V_ERR_CRL_HAS_EXPIRED +#define X509_V_FLAG_ALLOW_PROXY_CERTS 0 +#define X509_V_FLAG_X509_STRICT 0 /* * Not all of these X509_V_ERR values are used in wolfSSL. Some are included to @@ -212,6 +214,7 @@ #define X509_V_ERR_EXTENSIONS_REQUIRE_VERSION_3 93 #define X509_V_ERR_EC_KEY_EXPLICIT_PARAMS 94 #define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 +#define X509_R_KEY_VALUES_MISMATCH WC_KEY_MISMATCH_E #define X509_EXTENSION_set_critical wolfSSL_X509_EXTENSION_set_critical #define X509_EXTENSION_set_object wolfSSL_X509_EXTENSION_set_object diff --git a/src/wolfssl/openssl/x509_vfy.h b/src/wolfssl/openssl/x509_vfy.h index 977e0c0..c26b94d 100644 --- a/src/wolfssl/openssl/x509_vfy.h +++ b/src/wolfssl/openssl/x509_vfy.h @@ -1,6 +1,6 @@ /* x509_vfy.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/openssl/x509v3.h b/src/wolfssl/openssl/x509v3.h index a84077d..c0ae5cc 100644 --- a/src/wolfssl/openssl/x509v3.h +++ b/src/wolfssl/openssl/x509v3.h @@ -1,6 +1,6 @@ /* x509v3.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/quic.h b/src/wolfssl/quic.h index 70ae61c..da8c50a 100644 --- a/src/wolfssl/quic.h +++ b/src/wolfssl/quic.h @@ -1,6 +1,6 @@ /* quic.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/sniffer.h b/src/wolfssl/sniffer.h index 3eabd42..929fcdc 100644 --- a/src/wolfssl/sniffer.h +++ b/src/wolfssl/sniffer.h @@ -1,6 +1,6 @@ /* sniffer.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/sniffer_error.h b/src/wolfssl/sniffer_error.h index 1794ba8..bb574b4 100644 --- a/src/wolfssl/sniffer_error.h +++ b/src/wolfssl/sniffer_error.h @@ -1,6 +1,6 @@ /* sniffer_error.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/ssl.h b/src/wolfssl/ssl.h index 8b7ebed..908d5c6 100644 --- a/src/wolfssl/ssl.h +++ b/src/wolfssl/ssl.h @@ -1,6 +1,6 @@ /* ssl.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -76,7 +76,7 @@ #endif #ifdef OPENSSL_ALL - #ifndef WOLFSSL_HAVE_BIO_ADDR + #if !defined(WOLFSSL_HAVE_BIO_ADDR) && !defined(WOLFSSL_NO_SOCK) #define WOLFSSL_HAVE_BIO_ADDR #endif #if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_DTLS_MTU) @@ -117,7 +117,6 @@ #include #include #include - #if !defined(HAVE_SELFTEST) && (!defined(HAVE_FIPS) || \ FIPS_VERSION3_GE(5,2,0)) #include @@ -125,24 +124,15 @@ #include #include #include - #include #include #include - #include - #include #include #include #include #include #include - #include #include - #include - #include - #include #include - #include - #include #include #include #include @@ -152,26 +142,21 @@ #include #include #include - #include - #include #include #include #include #include - #include - #include #include #include #include #include #include #include - #if defined(HAVE_FIPS_VERSION) && FIPS_VERSION3_LT(7,0,0) + #if defined(HAVE_FIPS_VERSION) && FIPS_VERSION3_LT(6,0,0) /* clear conflicting name */ #undef RSA_PKCS1_PADDING_SIZE #endif #include - #include #include #include #include @@ -180,6 +165,26 @@ #include #include #include + + #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x30000000L + #include + #include + #include + #include + #include + #include + #include + #if OPENSSL_VERSION_NUMBER >= 0x30200000L + #include + #endif + #include + #include + #include + #include + #include + #include + #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */ + #endif /* !HAVE_SELFTEST && (!HAVE_FIPS || FIPS_VERSION3_GE(5,2,0)) */ #endif @@ -327,6 +332,7 @@ typedef int (*WOLFSSL_X509_STORE_CTX_get_crl_cb)(WOLFSSL_X509_STORE_CTX *, typedef int (*WOLFSSL_X509_STORE_CTX_check_crl_cb)(WOLFSSL_X509_STORE_CTX *, WOLFSSL_X509_CRL *); +#define WOLFSSL_V_ASN1_BIT_STRING 0x03 #define WOLFSSL_V_ASN1_INTEGER 0x02 #define WOLFSSL_V_ASN1_NEG 0x100 #define WOLFSSL_V_ASN1_NEG_INTEGER (2 | WOLFSSL_V_ASN1_NEG) @@ -603,7 +609,7 @@ struct WOLFSSL_EVP_PKEY { typedef struct WOLFSSL_BUFFER_INFO { unsigned char* buffer; - unsigned int length; + word32 length; } WOLFSSL_BUFFER_INFO; typedef struct WOLFSSL_BUF_MEM { @@ -706,7 +712,8 @@ enum BIO_TYPE { WOLFSSL_BIO_FILE = 6, WOLFSSL_BIO_BASE64 = 7, WOLFSSL_BIO_MD = 8, - WOLFSSL_BIO_DGRAM = 9 + WOLFSSL_BIO_DGRAM = 9, + WOLFSSL_BIO_NULL = 10 }; enum BIO_FLAGS { @@ -903,7 +910,7 @@ typedef struct WOLFSSL_ALERT_HISTORY { /* Valid Alert types from page 16/17 - * Add alert string to the function wolfSSL_alert_type_string_long in src/ssl.c + * Add alert string to the function AlertTypeToString in src/ssl.c */ enum AlertDescription { invalid_alert = -1, @@ -1174,6 +1181,12 @@ WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_method(void); WOLFSSL_API int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx, const char* publicName, word16 kemId, word16 kdfId, word16 aeadId); +WOLFSSL_API int wolfSSL_CTX_SetEchConfigsBase64(WOLFSSL_CTX* ctx, + const char* echConfigs64, word32 echConfigs64Len); + +WOLFSSL_API int wolfSSL_CTX_SetEchConfigs(WOLFSSL_CTX* ctx, + const byte* echConfigs, word32 echConfigsLen); + WOLFSSL_API int wolfSSL_CTX_GetEchConfigs(WOLFSSL_CTX* ctx, byte* output, word32* outputLen); @@ -1364,7 +1377,10 @@ WOLFSSL_API int wolfSSL_get_wfd(const WOLFSSL* ssl); WOLFSSL_ABI WOLFSSL_API int wolfSSL_connect(WOLFSSL* ssl); WOLFSSL_ABI WOLFSSL_API int wolfSSL_write( WOLFSSL* ssl, const void* data, int sz); +WOLFSSL_API int wolfSSL_write_ex(WOLFSSL* ssl, const void* data, size_t sz, + size_t* wr); WOLFSSL_ABI WOLFSSL_API int wolfSSL_read(WOLFSSL* ssl, void* data, int sz); +WOLFSSL_API int wolfSSL_read_ex(WOLFSSL* ssl, void* data, size_t sz, size_t* rd); WOLFSSL_API int wolfSSL_peek(WOLFSSL* ssl, void* data, int sz); WOLFSSL_ABI WOLFSSL_API int wolfSSL_accept(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_inject(WOLFSSL* ssl, const void* data, int sz); @@ -1837,6 +1853,7 @@ WOLFSSL_API int wolfSSL_sk_push_node(WOLFSSL_STACK** stack, WOLFSSL_STACK* in); WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx); WOLFSSL_API int wolfSSL_sk_push(WOLFSSL_STACK *st, const void *data); WOLFSSL_API int wolfSSL_sk_insert(WOLFSSL_STACK *sk, const void *data, int idx); +WOLFSSL_API void* wolfSSL_sk_pop(WOLFSSL_STACK* sk); #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(WOLFSSL_QT) WOLFSSL_API int wolfSSL_sk_ACCESS_DESCRIPTION_push( @@ -2043,6 +2060,7 @@ WOLFSSL_API WOLFSSL_BIO *wolfSSL_BIO_new_fd(int fd, int close_flag); WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_bio(void); WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_socket(void); WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_datagram(void); +WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_s_null(void); WOLFSSL_API WOLFSSL_BIO *wolfSSL_BIO_new_connect(const char *str); WOLFSSL_API WOLFSSL_BIO *wolfSSL_BIO_new_accept(const char *port); @@ -2262,9 +2280,8 @@ WOLFSSL_API WOLFSSL_X509_STORE_CTX *wolfSSL_X509_STORE_CTX_get0_parent_ctx( WOLFSSL_X509_STORE_CTX *ctx); WOLFSSL_API int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag); -WOLFSSL_API int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE* store); -WOLFSSL_API int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, - int idx, WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj); +WOLFSSL_API int wolfSSL_X509_STORE_get_by_subject(WOLFSSL_X509_STORE_CTX* ctx, + int idx, WOLFSSL_X509_NAME* name, WOLFSSL_X509_OBJECT* obj); WOLFSSL_API WOLFSSL_X509_VERIFY_PARAM *wolfSSL_X509_STORE_CTX_get0_param( WOLFSSL_X509_STORE_CTX *ctx); WOLFSSL_API int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx, @@ -2666,6 +2683,7 @@ enum { #define SSL_WRITING WOLFSSL_WRITING #define SSL_READING WOLFSSL_READING #define SSL_MAX_SSL_SESSION_ID_LENGTH WOLFSSL_MAX_SSL_SESSION_ID_LENGTH +#define SSL_MAX_SID_CTX_LENGTH WOLFSSL_MAX_SSL_SESSION_ID_LENGTH #ifdef HAVE_OCSP /* OCSP Flags */ @@ -2814,6 +2832,10 @@ WOLFSSL_API int wolfSSL_SESSION_set_cipher(WOLFSSL_SESSION* session, WOLFSSL_API int wolfSSL_is_init_finished(const WOLFSSL* ssl); WOLFSSL_API const char* wolfSSL_get_version(const WOLFSSL* ssl); +#ifdef OPENSSL_EXTRA +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_CIPHER)* wolfSSL_get_client_ciphers( + WOLFSSL* ssl); +#endif WOLFSSL_API int wolfSSL_get_current_cipher_suite(WOLFSSL* ssl); WOLFSSL_API WOLFSSL_CIPHER* wolfSSL_get_current_cipher(WOLFSSL* ssl); WOLFSSL_API char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in, int len); @@ -2968,23 +2990,49 @@ enum { /* ssl Constants */ (WOLFSSL_SESS_CACHE_NO_INTERNAL_STORE | WOLFSSL_SESS_CACHE_NO_INTERNAL_LOOKUP), - /* These values match OpenSSL values for corresponding names. */ + /* These values match OpenSSL values for corresponding names.*/ WOLFSSL_ERROR_SSL = 1, + + /* Operation did not complete; call this API again.*/ WOLFSSL_ERROR_WANT_READ = 2, + + /* Operation did not complete; call this API again.*/ WOLFSSL_ERROR_WANT_WRITE = 3, + + /* Operation did not complete; callback needs this API to be called again.*/ WOLFSSL_ERROR_WANT_X509_LOOKUP = 4, + + /* Some sort of system I/O error happened.*/ WOLFSSL_ERROR_SYSCALL = 5, + + /* The connection has been closed with a closure alert.*/ WOLFSSL_ERROR_ZERO_RETURN = 6, + + /* Underlying protocol connection not started yet, call this API again.*/ WOLFSSL_ERROR_WANT_CONNECT = 7, + + /* Underlying protocol connection not started yet, call this API again.*/ WOLFSSL_ERROR_WANT_ACCEPT = 8, + /* Close notify alert was sent to the peer.*/ WOLFSSL_SENT_SHUTDOWN = 1, + + /* Close notify or fatal error was received from the peer.*/ WOLFSSL_RECEIVED_SHUTDOWN = 2, + + /* Let library know that write buffer might move to different addresses.*/ WOLFSSL_MODE_ACCEPT_MOVING_WRITE_BUFFER = 4, + /* The handshake failed. */ WOLFSSL_R_SSL_HANDSHAKE_FAILURE = 101, + + /* The issuer CA certificate is unknown. */ WOLFSSL_R_TLSV1_ALERT_UNKNOWN_CA = 102, + + /* Unable to validate the certificate. */ WOLFSSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN = 103, + + /* There was a problem parsing the certificate. */ WOLFSSL_R_SSLV3_ALERT_BAD_CERTIFICATE = 104, WOLF_PEM_BUFSIZE = 1024 @@ -4059,6 +4107,13 @@ WOLFSSL_API void wolfSSL_CTX_SetGenMasterSecretCb(WOLFSSL_CTX* ctx, WOLFSSL_API void wolfSSL_SetGenMasterSecretCtx(WOLFSSL* ssl, void *ctx); WOLFSSL_API void* wolfSSL_GetGenMasterSecretCtx(WOLFSSL* ssl); +typedef int (*CallbackGenExtMasterSecret)(WOLFSSL* ssl, byte* hash, + word32 hashsz, void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetGenExtMasterSecretCb(WOLFSSL_CTX* ctx, + CallbackGenExtMasterSecret cb); +WOLFSSL_API void wolfSSL_SetGenExtMasterSecretCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetGenExtMasterSecretCtx(WOLFSSL* ssl); + typedef int (*CallbackGenPreMaster)(WOLFSSL* ssl, byte *premaster, word32 preSz, void* ctx); WOLFSSL_API void wolfSSL_CTX_SetGenPreMasterCb(WOLFSSL_CTX* ctx, @@ -4520,62 +4575,54 @@ enum { WOLFSSL_FFDHE_4096 = 258, WOLFSSL_FFDHE_6144 = 259, WOLFSSL_FFDHE_8192 = 260, + WOLFSSL_FFDHE_END = 511, #ifdef HAVE_PQC - /* These group numbers were taken from OQS's openssl provider, see: + +#ifdef WOLFSSL_MLKEM_KYBER + /* Old code points to keep compatibility with Kyber Round 3. + * Taken from OQS's openssl provider, see: * https://github.com/open-quantum-safe/oqs-provider/blob/main/oqs-template/ - * oqs-kem-info.md. - * - * The levels in the group name refer to the claimed NIST level of each - * parameter set. The associated parameter set name is listed as a comment - * beside the group number. Please see the NIST PQC Competition's submitted - * papers for more details. - * - * LEVEL1 means that an attack on that parameter set would require the same - * or more resources as a key search on AES 128. LEVEL3 would require the - * same or more resources as a key search on AES 192. LEVEL5 would require - * the same or more resources as a key search on AES 256. None of the - * algorithms have LEVEL2 and LEVEL4 because none of these submissions - * included them. */ - -#ifdef WOLFSSL_KYBER_ORIGINAL - WOLFSSL_PQC_MIN = 570, - WOLFSSL_PQC_SIMPLE_MIN = 570, + * oqs-kem-info.md + */ WOLFSSL_KYBER_LEVEL1 = 570, /* KYBER_512 */ WOLFSSL_KYBER_LEVEL3 = 572, /* KYBER_768 */ WOLFSSL_KYBER_LEVEL5 = 573, /* KYBER_1024 */ -#ifdef WOLFSSL_NO_ML_KEM - WOLFSSL_PQC_SIMPLE_MAX = 573, -#endif - WOLFSSL_PQC_HYBRID_MIN = 12090, WOLFSSL_P256_KYBER_LEVEL1 = 12090, WOLFSSL_P384_KYBER_LEVEL3 = 12092, WOLFSSL_P521_KYBER_LEVEL5 = 12093, -#ifdef WOLFSSL_NO_ML_KEM - WOLFSSL_PQC_HYBRID_MAX = 12093, - WOLFSSL_PQC_MAX = 12093, -#endif -#endif + WOLFSSL_X25519_KYBER_LEVEL1 = 12089, + WOLFSSL_X448_KYBER_LEVEL3 = 12176, + WOLFSSL_X25519_KYBER_LEVEL3 = 25497, + WOLFSSL_P256_KYBER_LEVEL3 = 25498, +#endif /* WOLFSSL_MLKEM_KYBER */ #ifndef WOLFSSL_NO_ML_KEM -#ifndef WOLFSSL_KYBER_ORIGINAL - WOLFSSL_PQC_MIN = 583, - WOLFSSL_PQC_SIMPLE_MIN = 583, -#endif - WOLFSSL_ML_KEM_512 = 583, /* ML-KEM 512 */ - WOLFSSL_ML_KEM_768 = 584, /* ML-KEM 768 */ - WOLFSSL_ML_KEM_1024 = 585, /* ML-KEM 1024 */ - WOLFSSL_PQC_SIMPLE_MAX = 585, - -#ifndef WOLFSSL_KYBER_ORIGINAL - WOLFSSL_PQC_HYBRID_MIN = 12103, -#endif - WOLFSSL_P256_ML_KEM_512 = 12103, - WOLFSSL_P384_ML_KEM_768 = 12104, - WOLFSSL_P521_ML_KEM_1024 = 12105, - WOLFSSL_PQC_HYBRID_MAX = 12105, - WOLFSSL_PQC_MAX = 12105, -#endif /* !WOLFSSL_NO_ML_KEM */ + /* Taken from draft-connolly-tls-mlkem-key-agreement, see: + * https://github.com/dconnolly/draft-connolly-tls-mlkem-key-agreement/ + */ + WOLFSSL_ML_KEM_512 = 512, + WOLFSSL_ML_KEM_768 = 513, + WOLFSSL_ML_KEM_1024 = 514, + + /* Taken from draft-kwiatkowski-tls-ecdhe-mlkem. see: + * https://github.com/post-quantum-cryptography/ + * draft-kwiatkowski-tls-ecdhe-mlkem/ + */ + WOLFSSL_P256_ML_KEM_768 = 4587, + WOLFSSL_X25519_ML_KEM_768 = 4588, + WOLFSSL_P384_ML_KEM_1024 = 4589, + + /* Taken from OQS's openssl provider, see: + * https://github.com/open-quantum-safe/oqs-provider/blob/main/oqs-template/ + * oqs-kem-info.md + */ + WOLFSSL_P256_ML_KEM_512 = 12107, + WOLFSSL_P384_ML_KEM_768 = 12108, + WOLFSSL_P521_ML_KEM_1024 = 12109, + WOLFSSL_X25519_ML_KEM_512 = 12214, + WOLFSSL_X448_ML_KEM_768 = 12215, +#endif /* WOLFSSL_NO_ML_KEM */ #endif /* HAVE_PQC */ WOLF_ENUM_DUMMY_LAST_ELEMENT(SSL_H) }; @@ -4968,6 +5015,10 @@ WOLFSSL_API const WOLFSSL_STACK *wolfSSL_X509_REQ_get_extensions(const WOLFSSL_X WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_get_ext(const WOLFSSL_X509* x, int loc); WOLFSSL_API int wolfSSL_X509_get_ext_by_OBJ(const WOLFSSL_X509 *x, const WOLFSSL_ASN1_OBJECT *obj, int lastpos); +WOLFSSL_API int wolfSSL_X509_OBJECT_set1_X509(WOLFSSL_X509_OBJECT *a, + WOLFSSL_X509 *obj); +WOLFSSL_API int wolfSSL_X509_OBJECT_set1_X509_CRL(WOLFSSL_X509_OBJECT *a, + WOLFSSL_X509_CRL *obj); WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x, int loc); WOLFSSL_API int wolfSSL_X509_EXTENSION_get_critical(const WOLFSSL_X509_EXTENSION* ex); WOLFSSL_API WOLFSSL_X509_EXTENSION* wolfSSL_X509_EXTENSION_new(void); @@ -5109,6 +5160,7 @@ struct WOLFSSL_CONF_CTX { }; WOLFSSL_API WOLFSSL_X509_NAME_ENTRY *wolfSSL_X509_NAME_get_entry(WOLFSSL_X509_NAME *name, int loc); +WOLFSSL_API int wolfSSL_X509_NAME_ENTRY_set(const WOLFSSL_X509_NAME_ENTRY *ne); #endif /* OPENSSL_EXTRA || WOLFSSL_WPAS_SMALL */ #if defined(OPENSSL_EXTRA) \ @@ -5280,6 +5332,12 @@ WOLFSSL_API void wolfSSL_sk_X509_OBJECT_pop_free(WOLFSSL_STACK* s, void (*f) (WOLFSSL_X509_OBJECT*)); WOLFSSL_API int wolfSSL_sk_X509_OBJECT_push(WOLFSSL_STACK* sk, WOLFSSL_X509_OBJECT* obj); +WOLFSSL_API WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* + wolfSSL_sk_X509_OBJECT_deep_copy( + const WOLF_STACK_OF(WOLFSSL_X509_OBJECT)* sk, + WOLFSSL_X509_OBJECT* (*c)(const WOLFSSL_X509_OBJECT*), + void (*f)(WOLFSSL_X509_OBJECT*)); + WOLFSSL_API WOLFSSL_X509_INFO *wolfSSL_X509_INFO_new(void); WOLFSSL_API void wolfSSL_X509_INFO_free(WOLFSSL_X509_INFO* info); @@ -5729,6 +5787,7 @@ WOLFSSL_API WOLF_STACK_OF(WOLFSSL_COMP) *WOLFSSL_COMP_get_compression_methods(vo #define SSL_COMP_get_compression_methods WOLFSSL_COMP_get_compression_methods #endif WOLFSSL_API int wolfSSL_X509_STORE_load_locations(WOLFSSL_X509_STORE *str, const char *file, const char *dir); +WOLFSSL_API int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE *str); WOLFSSL_API int wolfSSL_X509_STORE_add_crl(WOLFSSL_X509_STORE *ctx, WOLFSSL_X509_CRL *x); WOLFSSL_API int wolfSSL_sk_SSL_CIPHER_num(const WOLF_STACK_OF(WOLFSSL_CIPHER)* p); WOLFSSL_API int wolfSSL_sk_SSL_CIPHER_find( diff --git a/src/wolfssl/test.h b/src/wolfssl/test.h index 478a905..fa84ab0 100644 --- a/src/wolfssl/test.h +++ b/src/wolfssl/test.h @@ -1,6 +1,6 @@ /* test.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -85,11 +85,50 @@ #endif /* HAVE_ECC */ #endif /*HAVE_PK_CALLBACKS */ -#ifdef USE_WINDOWS_API +#ifdef __WATCOMC__ + #define SNPRINTF snprintf + #if defined(__NT__) + #include + #include + #include + #ifdef TEST_IPV6 /* don't require newer SDK for IPV4 */ + #include + #endif + #define SOCKET_T SOCKET + #define XSLEEP_MS(t) Sleep(t) + #elif defined(__OS2__) + #include + #include + #include + #define SOCKET_T int + #elif defined(__UNIX__) + #include + #include + #include + #ifndef WOLFSSL_NDS + #include + #endif + #include + #include + #ifdef HAVE_PTHREAD + #include + #endif + #define SOCKET_T int + #ifndef SO_NOSIGPIPE + #include /* ignore SIGPIPE */ + #endif + + #define XSLEEP_MS(m) \ + { \ + struct timespec req = { (m)/1000, ((m) % 1000) * 1000 }; \ + nanosleep( &req, NULL ); \ + } + #endif +#elif defined(USE_WINDOWS_API) #include + #include #include #ifdef TEST_IPV6 /* don't require newer SDK for IPV4 */ - #include #include #endif #define SOCKET_T SOCKET @@ -680,16 +719,6 @@ void test_wolfSSL_client_server_nofail_ex(callback_functions* client_cb, void test_wolfSSL_client_server_nofail(callback_functions* client_cb, callback_functions* server_cb); -/* Return - * tmpDir on success - * NULL on failure */ -char* create_tmp_dir(char* tmpDir, int len); -/* Remaining functions return - * 0 on success - * -1 on failure */ -int rem_dir(const char* dirName); -int rem_file(const char* fileName); -int copy_file(const char* in, const char* out); #if defined(__MACH__) || defined(__FreeBSD__) int link_file(const char* in, const char* out); @@ -1156,13 +1185,13 @@ static WC_INLINE void ShowX509Chain(WOLFSSL_X509_CHAIN* chain, int count, { int i; int length; - unsigned char buffer[3072]; + unsigned char certPem[3072]; WOLFSSL_X509* chainX509; for (i = 0; i < count; i++) { - wolfSSL_get_chain_cert_pem(chain, i, buffer, sizeof(buffer), &length); - buffer[length] = 0; - printf("\n%s: %d has length %d data = \n%s\n", hdr, i, length, buffer); + wolfSSL_get_chain_cert_pem(chain, i, certPem, sizeof(certPem), &length); + certPem[length] = 0; + printf("\n%s: %d has length %d data = \n%s\n", hdr, i, length, certPem); chainX509 = wolfSSL_get_chain_X509(chain, i); if (chainX509) @@ -1439,7 +1468,7 @@ static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp) err_sys_with_errno("socket failed\n"); } -#ifndef USE_WINDOWS_API +#if !defined(USE_WINDOWS_API) && !defined(__WATCOMC__) && !defined(__OS2__) #ifdef SO_NOSIGPIPE { int on = 1; @@ -1449,7 +1478,7 @@ static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp) err_sys_with_errno("setsockopt SO_NOSIGPIPE failed\n"); } #elif defined(WOLFSSL_MDK_ARM) || defined (WOLFSSL_TIRTOS) ||\ - defined(WOLFSSL_KEIL_TCP_NET) || defined(WOLFSSL_ZEPHYR) + defined(WOLFSSL_KEIL_TCP_NET) || defined(WOLFSSL_ZEPHYR) /* nothing to define */ #elif defined(NETOS) /* TODO: signal(SIGPIPE, SIG_IGN); */ @@ -1467,7 +1496,7 @@ static WC_INLINE void tcp_socket(SOCKET_T* sockfd, int udp, int sctp) err_sys_with_errno("setsockopt TCP_NODELAY failed\n"); } #endif -#endif /* USE_WINDOWS_API */ +#endif /* !defined(USE_WINDOWS_API) && !defined(__WATCOMC__) && ... */ } #if defined(WOLFSSL_WOLFSENTRY_HOOKS) && defined(WOLFSENTRY_H) @@ -1521,7 +1550,7 @@ static WC_INLINE int tcp_select_ex(SOCKET_T socketfd, int to_sec, int rx) fd_set* recvfds = NULL; fd_set* sendfds = NULL; SOCKET_T nfds = socketfd + 1; -#if !defined(__INTEGRITY) +#if !defined(__INTEGRITY) && !defined(__WATCOMC__) struct timeval timeout = {(to_sec > 0) ? to_sec : 0, 0}; #else struct timeval timeout; @@ -1538,8 +1567,9 @@ static WC_INLINE int tcp_select_ex(SOCKET_T socketfd, int to_sec, int rx) else sendfds = &fds; -#if defined(__INTEGRITY) - timeout.tv_sec = (long long)(to_sec > 0) ? to_sec : 0, 0; +#if defined(__INTEGRITY) || defined(__WATCOMC__) + timeout.tv_sec = (long long)(to_sec > 0) ? to_sec : 0; + timeout.tv_usec = 0; #endif result = select(nfds, recvfds, sendfds, &errfds, &timeout); @@ -1810,6 +1840,10 @@ static WC_INLINE void tcp_set_nonblocking(SOCKET_T* sockfd) || defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS) \ || defined(WOLFSSL_ZEPHYR) /* non blocking not supported, for now */ + #elif defined(__WATCOMC__) && defined(__OS2__) + int blocking = 1; + if (ioctl(*sockfd, FIONBIO, &blocking) == -1) + err_sys_with_errno("ioctl failed"); #else int flags = fcntl(*sockfd, F_GETFL, 0); if (flags < 0) @@ -1831,6 +1865,10 @@ static WC_INLINE void tcp_set_blocking(SOCKET_T* sockfd) || defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS) \ || defined(WOLFSSL_ZEPHYR) /* non blocking not supported, for now */ + #elif defined(__WATCOMC__) && defined(__OS2__) + int blocking = 0; + if (ioctl(*sockfd, FIONBIO, &blocking) == -1) + err_sys_with_errno("ioctl failed"); #else int flags = fcntl(*sockfd, F_GETFL, 0); if (flags < 0) @@ -2131,7 +2169,9 @@ static WC_INLINE unsigned int my_psk_client_cs_cb(WOLFSSL* ssl, #elif defined(USE_WINDOWS_API) #define WIN32_LEAN_AND_MEAN + #define _WINSOCKAPI_ /* block inclusion of winsock.h header file */ #include + #undef _WINSOCKAPI_ /* undefine it for MINGW winsock2.h header file */ static WC_INLINE double current_time(int reset) { @@ -2423,7 +2463,7 @@ static THREAD_LS_T int myVerifyAction = VERIFY_OVERRIDE_ERROR; static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store) { - char buffer[WOLFSSL_MAX_ERROR_SZ]; + char err_buffer[WOLFSSL_MAX_ERROR_SZ]; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) WOLFSSL_X509* peer; #if defined(SHOW_CERTS) && !defined(NO_FILESYSTEM) && \ @@ -2450,7 +2490,7 @@ static WC_INLINE int myVerify(int preverify, WOLFSSL_X509_STORE_CTX* store) */ fprintf(stderr, "In verification callback, error = %d, %s\n", store->error, - wolfSSL_ERR_error_string((unsigned long) store->error, buffer)); + wolfSSL_ERR_error_string((unsigned long) store->error, err_buffer)); #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) peer = store->current_cert; if (peer) { @@ -4220,6 +4260,25 @@ static WC_INLINE int myGenMaster(WOLFSSL* ssl, void* ctx) return ret; } +static WC_INLINE int myGenExtMaster(WOLFSSL* ssl, byte* hash, word32 hashSz, + void* ctx) +{ + int ret; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + (void)hash; + (void)hashSz; + + WOLFSSL_PKMSG("Gen Extended Master"); + /* fall through to original routine */ + ret = PROTOCOLCB_UNAVAILABLE; + WOLFSSL_PKMSG("Gen Extended Master: ret %d\n", ret); + + return ret; +} + static WC_INLINE int myGenPreMaster(WOLFSSL* ssl, byte *premaster, word32 preSz, void* ctx) { @@ -4372,6 +4431,7 @@ static WC_INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx) #ifndef NO_CERTS wolfSSL_CTX_SetGenMasterSecretCb(ctx, myGenMaster); + wolfSSL_CTX_SetGenExtMasterSecretCb(ctx, myGenExtMaster); wolfSSL_CTX_SetGenPreMasterCb(ctx, myGenPreMaster); wolfSSL_CTX_SetGenSessionKeyCb(ctx, myGenSessionKey); wolfSSL_CTX_SetEncryptKeysCb(ctx, mySetEncryptKeys); @@ -4427,6 +4487,7 @@ static WC_INLINE void SetupPkCallbackContexts(WOLFSSL* ssl, void* myCtx) #ifndef NO_CERTS wolfSSL_SetGenMasterSecretCtx(ssl, myCtx); + wolfSSL_SetGenExtMasterSecretCtx(ssl, myCtx); wolfSSL_SetGenPreMasterCtx(ssl, myCtx); wolfSSL_SetGenSessionKeyCtx(ssl, myCtx); wolfSSL_SetEncryptKeysCtx(ssl, myCtx); @@ -4487,7 +4548,7 @@ static WC_INLINE int SimulateWantWriteIOSendCb(WOLFSSL *ssl, char *buf, int sz, #endif /* USE_WOLFSSL_IO */ #if defined(__hpux__) || defined(__MINGW32__) || defined (WOLFSSL_TIRTOS) \ - || defined(_MSC_VER) + || defined(_MSC_VER) || defined(__WATCOMC__) /* HP/UX doesn't have strsep, needed by test/suites.c */ static WC_INLINE char* strsep(char **stringp, const char *delim) diff --git a/src/wolfssl/version.h b/src/wolfssl/version.h index d7a1985..c128a21 100644 --- a/src/wolfssl/version.h +++ b/src/wolfssl/version.h @@ -1,6 +1,6 @@ /* wolfssl_version.h.in * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -28,8 +28,8 @@ extern "C" { #endif -#define LIBWOLFSSL_VERSION_STRING "5.7.6" -#define LIBWOLFSSL_VERSION_HEX 0x05007006 +#define LIBWOLFSSL_VERSION_STRING "5.8.0" +#define LIBWOLFSSL_VERSION_HEX 0x05008000 #ifdef __cplusplus } diff --git a/src/wolfssl/wolfcrypt/aes.h b/src/wolfssl/wolfcrypt/aes.h index d1b71e5..128611c 100644 --- a/src/wolfssl/wolfcrypt/aes.h +++ b/src/wolfssl/wolfcrypt/aes.h @@ -1,6 +1,6 @@ /* aes.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -303,12 +303,21 @@ struct Aes { #endif #ifdef WOLFSSL_AESNI byte use_aesni; + #if defined(WOLFSSL_LINUXKM) || defined(WC_WANT_FLAG_DONT_USE_AESNI) + /* Note, we can't support WC_FLAG_DONT_USE_AESNI by default because we + * need to support legacy applications that call wc_AesSetKey() on + * uninited struct Aes. For details see the software implementation of + * wc_AesSetKeyLocal() (aes.c). + */ + #define WC_FLAG_DONT_USE_AESNI 2 + #endif #endif /* WOLFSSL_AESNI */ #if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \ !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) byte use_aes_hw_crypto; #ifdef HAVE_AESGCM byte use_pmull_hw_crypto; + byte use_sha3_hw_crypto; #endif #endif /* __aarch64__ && WOLFSSL_ARMASM && !WOLFSSL_ARMASM_NO_HW_CRYPTO */ #ifdef WOLF_CRYPTO_CB @@ -325,7 +334,8 @@ struct Aes { WC_ASYNC_DEV asyncDev; #endif /* WOLFSSL_ASYNC_CRYPT */ #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ - defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) + defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) || \ + defined(WOLFSSL_AES_CTS) word32 left; /* unused bytes left from last call */ #endif #ifdef WOLFSSL_XILINX_CRYPT @@ -416,6 +426,9 @@ struct Aes { * trackable by sanitizers. */ #endif +#ifdef WOLFSSL_AES_CTS + byte ctsBlock[WC_AES_BLOCK_SIZE * 2]; +#endif }; #ifndef WC_AES_TYPE_DEFINED @@ -587,7 +600,7 @@ WOLFSSL_API int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz); - WOLFSSL_API int wc_AesGcmDecrypt(Aes* aes, byte* out, + WOLFSSL_API WARN_UNUSED_RESULT int wc_AesGcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, const byte* iv, word32 ivSz, const byte* authTag, word32 authTagSz, @@ -609,8 +622,8 @@ WOLFSSL_API int wc_AesGcmDecryptInit(Aes* aes, const byte* key, word32 len, const byte* iv, word32 ivSz); WOLFSSL_API int wc_AesGcmDecryptUpdate(Aes* aes, byte* out, const byte* in, word32 sz, const byte* authIn, word32 authInSz); -WOLFSSL_API int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, - word32 authTagSz); +WOLFSSL_API WARN_UNUSED_RESULT int wc_AesGcmDecryptFinal(Aes* aes, + const byte* authTag, word32 authTagSz); #endif #ifndef WC_NO_RNG @@ -647,7 +660,7 @@ WOLFSSL_API int wc_AesGcmDecryptFinal(Aes* aes, const byte* authTag, const byte* nonce, word32 nonceSz, byte* authTag, word32 authTagSz, const byte* authIn, word32 authInSz); - WOLFSSL_API int wc_AesCcmDecrypt(Aes* aes, byte* out, + WOLFSSL_API WARN_UNUSED_RESULT int wc_AesCcmDecrypt(Aes* aes, byte* out, const byte* in, word32 inSz, const byte* nonce, word32 nonceSz, const byte* authTag, word32 authTagSz, @@ -760,7 +773,7 @@ WOLFSSL_API int wc_AesSivEncrypt(const byte* key, word32 keySz, const byte* assoc, word32 assocSz, const byte* nonce, word32 nonceSz, const byte* in, word32 inSz, byte* siv, byte* out); -WOLFSSL_API +WOLFSSL_API WARN_UNUSED_RESULT int wc_AesSivDecrypt(const byte* key, word32 keySz, const byte* assoc, word32 assocSz, const byte* nonce, word32 nonceSz, const byte* in, word32 inSz, byte* siv, byte* out); @@ -769,7 +782,7 @@ WOLFSSL_API int wc_AesSivEncrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc, word32 numAssoc, const byte* nonce, word32 nonceSz, const byte* in, word32 inSz, byte* siv, byte* out); -WOLFSSL_API +WOLFSSL_API WARN_UNUSED_RESULT int wc_AesSivDecrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc, word32 numAssoc, const byte* nonce, word32 nonceSz, const byte* in, word32 inSz, byte* siv, byte* out); @@ -804,7 +817,8 @@ WOLFSSL_API int wc_AesEaxEncryptAuth(const byte* key, word32 keySz, byte* out, /* input data to authenticate (header) */ const byte* authIn, word32 authInSz); -WOLFSSL_API int wc_AesEaxDecryptAuth(const byte* key, word32 keySz, byte* out, +WOLFSSL_API WARN_UNUSED_RESULT int wc_AesEaxDecryptAuth(const byte* key, + word32 keySz, byte* out, const byte* in, word32 inSz, const byte* nonce, word32 nonceSz, /* auth tag to verify against */ @@ -832,15 +846,38 @@ WOLFSSL_API int wc_AesEaxAuthDataUpdate(AesEax* eax, WOLFSSL_API int wc_AesEaxEncryptFinal(AesEax* eax, byte* authTag, word32 authTagSz); -WOLFSSL_API int wc_AesEaxDecryptFinal(AesEax* eax, +WOLFSSL_API WARN_UNUSED_RESULT int wc_AesEaxDecryptFinal(AesEax* eax, const byte* authIn, word32 authInSz); WOLFSSL_API int wc_AesEaxFree(AesEax* eax); #endif /* WOLFSSL_AES_EAX */ +#ifdef WOLFSSL_AES_CTS +/* Ciphertext stealing encryption compatible with RFC2040 and RFC3962. */ + +/* One-shot API */ +WOLFSSL_API int wc_AesCtsEncrypt(const byte* key, word32 keySz, byte* out, + const byte* in, word32 inSz, + const byte* iv); +WOLFSSL_API int wc_AesCtsDecrypt(const byte* key, word32 keySz, byte* out, + const byte* in, word32 inSz, + const byte* iv); + +/* Incremental API */ +WOLFSSL_API int wc_AesCtsEncryptUpdate(Aes* aes, byte* out, word32* outSz, + const byte* in, word32 inSz); +WOLFSSL_API int wc_AesCtsDecryptUpdate(Aes* aes, byte* out, word32* outSz, + const byte* in, word32 inSz); +WOLFSSL_API int wc_AesCtsEncryptFinal(Aes* aes, byte* out, word32* outSz); +WOLFSSL_API int wc_AesCtsDecryptFinal(Aes* aes, byte* out, word32* outSz); + + +#endif + #if defined(__aarch64__) && defined(WOLFSSL_ARMASM) && \ !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) + /* GHASH one block of data. * * XOR block into tag and GMULT with H. @@ -848,7 +885,7 @@ WOLFSSL_API int wc_AesEaxFree(AesEax* eax); * @param [in, out] aes AES GCM object. * @param [in] block Block of AAD or cipher text. */ -#define GHASH_ONE_BLOCK(aes, block) \ +#define GHASH_ONE_BLOCK_AARCH64(aes, block) \ do { \ xorbuf(AES_TAG(aes), block, WC_AES_BLOCK_SIZE); \ GMULT_AARCH64(AES_TAG(aes), aes->gcm.H); \ diff --git a/src/wolfssl/wolfcrypt/arc4.h b/src/wolfssl/wolfcrypt/arc4.h index 0dc29d3..cdddde8 100644 --- a/src/wolfssl/wolfcrypt/arc4.h +++ b/src/wolfssl/wolfcrypt/arc4.h @@ -1,6 +1,6 @@ /* arc4.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/ascon.h b/src/wolfssl/wolfcrypt/ascon.h new file mode 100644 index 0000000..196a8ca --- /dev/null +++ b/src/wolfssl/wolfcrypt/ascon.h @@ -0,0 +1,109 @@ +/* ascon.h + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef WOLF_CRYPT_ASCON_H +#define WOLF_CRYPT_ASCON_H + +#ifdef HAVE_ASCON + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ASCON_HASH256_SZ 32 + +#define ASCON_AEAD128_KEY_SZ 16 +#define ASCON_AEAD128_NONCE_SZ 16 +#define ASCON_AEAD128_TAG_SZ 16 + +typedef union AsconState { +#ifdef WORD64_AVAILABLE + word64 s64[5]; +#endif + word32 s32[10]; + word16 s16[20]; + byte s8[40]; +} AsconState; + +typedef struct wc_AsconHash256 { + AsconState state; + byte lastBlkSz; +} wc_AsconHash256; + +enum { + ASCON_AEAD128_NOTSET = 0, + ASCON_AEAD128_ENCRYPT = 1, + ASCON_AEAD128_DECRYPT = 2 +}; + +typedef struct wc_AsconAEAD128 { + /* needed throughout both encrypt and decrypt */ +#ifdef WORD64_AVAILABLE + word64 key[ASCON_AEAD128_KEY_SZ/sizeof(word64)]; +#endif + AsconState state; + byte lastBlkSz; + byte keySet:1; /* has the key been processed */ + byte nonceSet:1; /* has the nonce been processed */ + byte adSet:1; /* has the associated data been processed */ + byte op:2; /* 0 for not set, 1 for encrypt, 2 for decrypt */ +} wc_AsconAEAD128; + +/* AsconHash API */ + +WOLFSSL_API wc_AsconHash256* wc_AsconHash256_New(void); +WOLFSSL_API void wc_AsconHash256_Free(wc_AsconHash256* a); +WOLFSSL_API int wc_AsconHash256_Init(wc_AsconHash256* a); +WOLFSSL_API void wc_AsconHash256_Clear(wc_AsconHash256* a); +WOLFSSL_API int wc_AsconHash256_Update(wc_AsconHash256* a, const byte* data, + word32 dataSz); +WOLFSSL_API int wc_AsconHash256_Final(wc_AsconHash256* a, byte* hash); + +WOLFSSL_API wc_AsconAEAD128* wc_AsconAEAD128_New(void); +WOLFSSL_API void wc_AsconAEAD128_Free(wc_AsconAEAD128* a); +WOLFSSL_API int wc_AsconAEAD128_Init(wc_AsconAEAD128* a); +WOLFSSL_API void wc_AsconAEAD128_Clear(wc_AsconAEAD128* a); + +/* AsconAEAD API */ + +WOLFSSL_API int wc_AsconAEAD128_SetKey(wc_AsconAEAD128* a, const byte* key); +WOLFSSL_API int wc_AsconAEAD128_SetNonce(wc_AsconAEAD128* a, const byte* nonce); +WOLFSSL_API int wc_AsconAEAD128_SetAD(wc_AsconAEAD128* a, const byte* ad, + word32 adSz); + +WOLFSSL_API int wc_AsconAEAD128_EncryptUpdate(wc_AsconAEAD128* a, byte* out, + const byte* in, word32 inSz); +WOLFSSL_API int wc_AsconAEAD128_EncryptFinal(wc_AsconAEAD128* a, byte* tag); + +WOLFSSL_API int wc_AsconAEAD128_DecryptUpdate(wc_AsconAEAD128* a, byte* out, + const byte* in, word32 inSz); +WOLFSSL_API int wc_AsconAEAD128_DecryptFinal(wc_AsconAEAD128* a, + const byte* tag); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* HAVE_ASCON */ + +#endif /* WOLF_CRYPT_ASCON_H */ diff --git a/src/wolfssl/wolfcrypt/asn.h b/src/wolfssl/wolfcrypt/asn.h index 12a6023..e553059 100644 --- a/src/wolfssl/wolfcrypt/asn.h +++ b/src/wolfssl/wolfcrypt/asn.h @@ -1,6 +1,6 @@ /* asn.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -853,6 +853,26 @@ extern const WOLFSSL_ObjectInfo wolfssl_object_info[]; #endif #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) +/* short names */ +#define WC_SN_md4 "MD4" +#define WC_SN_md5 "MD5" +#define WC_SN_sha1 "SHA1" +#define WC_SN_sha224 "SHA224" +#define WC_SN_sha256 "SHA256" +#define WC_SN_sha384 "SHA384" +#define WC_SN_sha512 "SHA512" +#define WC_SN_sha512_224 "SHA512-224" +#define WC_SN_sha512_256 "SHA512-256" +#define WC_SN_sha3_224 "SHA3-224" +#define WC_SN_sha3_256 "SHA3-256" +#define WC_SN_sha3_384 "SHA3-384" +#define WC_SN_sha3_512 "SHA3-512" +#define WC_SN_shake128 "SHAKE128" +#define WC_SN_shake256 "SHAKE256" +#define WC_SN_blake2s256 "BLAKE2s256" +#define WC_SN_blake2s512 "BLAKE2s512" +#define WC_SN_blake2b512 "BLAKE2b512" +#define WC_SN_sm3 "SM3" /* NIDs */ #define WC_NID_netscape_cert_type WC_NID_undef @@ -1249,6 +1269,7 @@ enum Oid_Types { enum Hash_Sum { MD2h = 646, + MD4h = 648, MD5h = 649, SHAh = 88, SHA224h = 417, @@ -1403,11 +1424,165 @@ enum Extensions_Sum { enum CertificatePolicy_Sum { CP_ANY_OID = 146, /* id-ce 32 0 */ + CP_ISRG_DOMAIN_VALID = 430, /* 1.3.6.1.4.1.44947.1.1.1 */ #ifdef WOLFSSL_FPKI - CP_FPKI_COMMON_AUTH_OID = 426, /* 2.16.840.1.101.3.2.1.3.13 */ - CP_FPKI_PIV_AUTH_OID = 453, /* 2.16.840.1.101.3.2.1.3.40 */ - CP_FPKI_PIV_AUTH_HW_OID = 454, /* 2.16.840.1.101.3.2.1.3.41 */ - CP_FPKI_PIVI_AUTH_OID = 458, /* 2.16.840.1.101.3.2.1.3.45 */ + /* Federal PKI OIDs */ + CP_FPKI_HIGH_ASSURANCE_OID = 417, /* 2.16.840.1.101.3.2.1.3.4 */ + CP_FPKI_COMMON_HARDWARE_OID = 420, /* 2.16.840.1.101.3.2.1.3.7 */ + CP_FPKI_MEDIUM_HARDWARE_OID = 425, /* 2.16.840.1.101.3.2.1.3.12 */ + CP_FPKI_COMMON_AUTH_OID = 426, /* 2.16.840.1.101.3.2.1.3.13 */ + CP_FPKI_COMMON_HIGH_OID = 429, /* 2.16.840.1.101.3.2.1.3.16 */ + CP_FPKI_PIVI_HARDWARE_OID = 431, /* 2.16.840.1.101.3.2.1.3.18 */ + CP_FPKI_PIVI_CONTENT_SIGNING_OID = 433, /* 2.16.840.1.101.3.2.1.3.20 */ + CP_FPKI_COMMON_DEVICES_HARDWARE_OID = 449, /* 2.16.840.1.101.3.2.1.3.36 */ + CP_FPKI_MEDIUM_DEVICE_HARDWARE_OID = 451, /* 2.16.840.1.101.3.2.1.3.38 */ + CP_FPKI_COMMON_PIV_CONTENT_SIGNING_OID = 452, /* 2.16.840.1.101.3.2.1.3.39 */ + CP_FPKI_PIV_AUTH_OID = 453, /* 2.16.840.1.101.3.2.1.3.40 */ + CP_FPKI_PIV_AUTH_HW_OID = 454, /* 2.16.840.1.101.3.2.1.3.41 */ + CP_FPKI_PIVI_AUTH_OID = 458, /* 2.16.840.1.101.3.2.1.3.45 */ + CP_FPKI_COMMON_PIVI_CONTENT_SIGNING_OID = 460, /* 2.16.840.1.101.3.2.1.3.47 */ + + /* Federal PKI Test OIDs */ + CP_FPKI_AUTH_TEST_OID = 469, /* 2.16.840.1.101.3.2.1.48.11 */ + CP_FPKI_CARDAUTH_TEST_OID = 471, /* 2.16.840.1.101.3.2.1.48.13 */ + CP_FPKI_PIV_CONTENT_TEST_OID = 544, /* 2.16.840.1.101.3.2.1.48.86 */ + CP_FPKI_PIV_AUTH_DERIVED_TEST_OID = 567, /* 2.16.840.1.101.3.2.1.48.109 */ + CP_FPKI_PIV_AUTH_DERIVED_HW_TEST_OID = 568, /* 2.16.840.1.101.3.2.1.48.110 */ + + /* DoD PKI OIDs */ + CP_DOD_MEDIUM_OID = 423, /* 2.16.840.1.101.2.1.11.5 */ + CP_DOD_MEDIUM_HARDWARE_OID = 427, /* 2.16.840.1.101.2.1.11.9 */ + CP_DOD_PIV_AUTH_OID = 428, /* 2.16.840.1.101.2.1.11.10 */ + CP_DOD_MEDIUM_NPE_OID = 435, /* 2.16.840.1.101.2.1.11.17 */ + CP_DOD_MEDIUM_2048_OID = 436, /* 2.16.840.1.101.2.1.11.18 */ + CP_DOD_MEDIUM_HARDWARE_2048_OID = 437, /* 2.16.840.1.101.2.1.11.19 */ + CP_DOD_PIV_AUTH_2048_OID = 438, /* 2.16.840.1.101.2.1.11.20 */ + CP_DOD_PEER_INTEROP_OID = 100449, /* 2.16.840.1.101.2.1.11.31 */ + CP_DOD_MEDIUM_NPE_112_OID = 100454, /* 2.16.840.1.101.2.1.11.36 */ + CP_DOD_MEDIUM_NPE_128_OID = 455, /* 2.16.840.1.101.2.1.11.37 */ + CP_DOD_MEDIUM_NPE_192_OID = 456, /* 2.16.840.1.101.2.1.11.38 */ + CP_DOD_MEDIUM_112_OID = 457, /* 2.16.840.1.101.2.1.11.39 */ + CP_DOD_MEDIUM_128_OID = 100458, /* 2.16.840.1.101.2.1.11.40 */ + CP_DOD_MEDIUM_192_OID = 459, /* 2.16.840.1.101.2.1.11.41 */ + CP_DOD_MEDIUM_HARDWARE_112_OID = 100460, /* 2.16.840.1.101.2.1.11.42 */ + CP_DOD_MEDIUM_HARDWARE_128_OID = 461, /* 2.16.840.1.101.2.1.11.43 */ + CP_DOD_MEDIUM_HARDWARE_192_OID = 462, /* 2.16.840.1.101.2.1.11.44 */ + CP_DOD_ADMIN_OID = 477, /* 2.16.840.1.101.2.1.11.59 */ + CP_DOD_INTERNAL_NPE_112_OID = 478, /* 2.16.840.1.101.2.1.11.60 */ + CP_DOD_INTERNAL_NPE_128_OID = 479, /* 2.16.840.1.101.2.1.11.61 */ + CP_DOD_INTERNAL_NPE_192_OID = 480, /* 2.16.840.1.101.2.1.11.62 */ + + /* ECA PKI OIDs */ + CP_ECA_MEDIUM_OID = 100423, /* 2.16.840.1.101.3.2.1.12.1 */ + CP_ECA_MEDIUM_HARDWARE_OID = 424, /* 2.16.840.1.101.3.2.1.12.2 */ + CP_ECA_MEDIUM_TOKEN_OID = 100425, /* 2.16.840.1.101.3.2.1.12.3 */ + CP_ECA_MEDIUM_SHA256_OID = 100426, /* 2.16.840.1.101.3.2.1.12.4 */ + CP_ECA_MEDIUM_TOKEN_SHA256_OID = 100427, /* 2.16.840.1.101.3.2.1.12.5 */ + CP_ECA_MEDIUM_HARDWARE_PIVI_OID = 100428, /* 2.16.840.1.101.3.2.1.12.6 */ + CP_ECA_CONTENT_SIGNING_PIVI_OID = 100430, /* 2.16.840.1.101.3.2.1.12.8 */ + CP_ECA_MEDIUM_DEVICE_SHA256_OID = 431, /* 2.16.840.1.101.3.2.1.12.9 */ + CP_ECA_MEDIUM_HARDWARE_SHA256_OID = 432, /* 2.16.840.1.101.3.2.1.12.10 */ + + /* Department of State PKI OIDs */ + CP_STATE_BASIC_OID = 100417, /* 2.16.840.1.101.3.2.1.6.1 */ + CP_STATE_LOW_OID = 418, /* 2.16.840.1.101.3.2.1.6.2 */ + CP_STATE_MODERATE_OID = 100419, /* 2.16.840.1.101.3.2.1.6.3 */ + CP_STATE_HIGH_OID = 100420, /* 2.16.840.1.101.3.2.1.6.4 */ + CP_STATE_MEDHW_OID = 101428, /* 2.16.840.1.101.3.2.1.6.12 */ + CP_STATE_MEDDEVHW_OID = 101454, /* 2.16.840.1.101.3.2.1.6.38 */ + + /* U.S. Treasury SSP PKI OIDs */ + CP_TREAS_MEDIUMHW_OID = 419, /* 2.16.840.1.101.3.2.1.5.4 */ + CP_TREAS_HIGH_OID = 101420, /* 2.16.840.1.101.3.2.1.5.5 */ + CP_TREAS_PIVI_HW_OID = 101425, /* 2.16.840.1.101.3.2.1.5.10 */ + CP_TREAS_PIVI_CONTENT_OID = 101427, /* 2.16.840.1.101.3.2.1.5.12 */ + + /* Boeing PKI OIDs */ + CP_BOEING_MEDIUMHW_SHA256_OID = 159, /* 1.3.6.1.4.1.73.15.3.1.12 */ + CP_BOEING_MEDIUMHW_CONTENT_SHA256_OID = 164, /* 1.3.6.1.4.1.73.15.3.1.17 */ + + /* Carillon Federal Services OIDs */ + CP_CARILLON_MEDIUMHW_256_OID = 467, /* 1.3.6.1.4.1.45606.3.1.12 */ + CP_CARILLON_AIVHW_OID = 475, /* 1.3.6.1.4.1.45606.3.1.20 */ + CP_CARILLON_AIVCONTENT_OID = 100477, /* 1.3.6.1.4.1.45606.3.1.22 */ + + /* Carillon Information Security OIDs */ + CP_CIS_MEDIUMHW_256_OID = 489, /* 1.3.6.1.4.1.25054.3.1.12 */ + CP_CIS_MEDDEVHW_256_OID = 491, /* 1.3.6.1.4.1.25054.3.1.14 */ + CP_CIS_ICECAP_HW_OID = 497, /* 1.3.6.1.4.1.25054.3.1.20 */ + CP_CIS_ICECAP_CONTENT_OID = 499, /* 1.3.6.1.4.1.25054.3.1.22 */ + + /* CertiPath Bridge OIDs */ + CP_CERTIPATH_MEDIUMHW_OID = 100459, /* 1.3.6.1.4.1.24019.1.1.1.2 */ + CP_CERTIPATH_HIGHHW_OID = 101460, /* 1.3.6.1.4.1.24019.1.1.1.3 */ + CP_CERTIPATH_ICECAP_HW_OID = 464, /* 1.3.6.1.4.1.24019.1.1.1.7 */ + CP_CERTIPATH_ICECAP_CONTENT_OID = 466, /* 1.3.6.1.4.1.24019.1.1.1.9 */ + CP_CERTIPATH_VAR_MEDIUMHW_OID = 100475, /* 1.3.6.1.4.1.24019.1.1.1.18 */ + CP_CERTIPATH_VAR_HIGHHW_OID = 476, /* 1.3.6.1.4.1.24019.1.1.1.19 */ + + /* TSCP Bridge OIDs */ + CP_TSCP_MEDIUMHW_OID = 442, /* 1.3.6.1.4.1.38099.1.1.1.2 */ + CP_TSCP_PIVI_OID = 445, /* 1.3.6.1.4.1.38099.1.1.1.5 */ + CP_TSCP_PIVI_CONTENT_OID = 447, /* 1.3.6.1.4.1.38099.1.1.1.7 */ + + /* DigiCert NFI PKI OIDs */ + CP_DIGICERT_NFSSP_MEDIUMHW_OID = 796, /* 2.16.840.1.113733.1.7.23.3.1.7 */ + CP_DIGICERT_NFSSP_AUTH_OID = 802, /* 2.16.840.1.113733.1.7.23.3.1.13 */ + CP_DIGICERT_NFSSP_PIVI_HW_OID = 807, /* 2.16.840.1.113733.1.7.23.3.1.18 */ + CP_DIGICERT_NFSSP_PIVI_CONTENT_OID = 809, /* 2.16.840.1.113733.1.7.23.3.1.20 */ + CP_DIGICERT_NFSSP_MEDDEVHW_OID = 825, /* 2.16.840.1.113733.1.7.23.3.1.36 */ + + /* Entrust Managed Services NFI PKI OIDs */ + CP_ENTRUST_NFSSP_MEDIUMHW_OID = 1017, /* 2.16.840.1.114027.200.3.10.7.2 */ + CP_ENTRUST_NFSSP_MEDAUTH_OID = 1019, /* 2.16.840.1.114027.200.3.10.7.4 */ + CP_ENTRUST_NFSSP_PIVI_HW_OID = 1021, /* 2.16.840.1.114027.200.3.10.7.6 */ + CP_ENTRUST_NFSSP_PIVI_CONTENT_OID = 1024, /* 2.16.840.1.114027.200.3.10.7.9 */ + CP_ENTRUST_NFSSP_MEDDEVHW_OID = 1031, /* 2.16.840.1.114027.200.3.10.7.16 */ + + /* Exostar LLC PKI OIDs */ + CP_EXOSTAR_MEDIUMHW_SHA2_OID = 100424, /* 1.3.6.1.4.1.13948.1.1.1.6 */ + + /* IdenTrust NFI OIDs */ + CP_IDENTRUST_MEDIUMHW_SIGN_OID = 846, /* 2.16.840.1.113839.0.100.12.1 */ + CP_IDENTRUST_MEDIUMHW_ENC_OID = 847, /* 2.16.840.1.113839.0.100.12.2 */ + CP_IDENTRUST_PIVI_HW_ID_OID = 851, /* 2.16.840.1.113839.0.100.18.0 */ + CP_IDENTRUST_PIVI_HW_SIGN_OID = 852, /* 2.16.840.1.113839.0.100.18.1 */ + CP_IDENTRUST_PIVI_HW_ENC_OID = 853, /* 2.16.840.1.113839.0.100.18.2 */ + CP_IDENTRUST_PIVI_CONTENT_OID = 854, /* 2.16.840.1.113839.0.100.20.1 */ + + /* Lockheed Martin PKI OIDs */ + CP_LOCKHEED_MEDIUMHW_OID = 266, /* 1.3.6.1.4.1.103.100.1.1.3.3 */ + + /* Northrop Grumman PKI OIDs */ + CP_NORTHROP_MEDIUM_256_HW_OID = 654, /* 1.3.6.1.4.1.16334.509.2.8 */ + CP_NORTHROP_PIVI_256_HW_OID = 655, /* 1.3.6.1.4.1.16334.509.2.9 */ + CP_NORTHROP_PIVI_256_CONTENT_OID = 657, /* 1.3.6.1.4.1.16334.509.2.11 */ + CP_NORTHROP_MEDIUM_384_HW_OID = 660, /* 1.3.6.1.4.1.16334.509.2.14 */ + + /* Raytheon PKI OIDs */ + CP_RAYTHEON_MEDIUMHW_OID = 251, /* 1.3.6.1.4.1.1569.10.1.12 */ + CP_RAYTHEON_MEDDEVHW_OID = 257, /* 1.3.6.1.4.1.1569.10.1.18 */ + CP_RAYTHEON_SHA2_MEDIUMHW_OID = 433, /* 1.3.6.1.4.1.26769.10.1.12 */ + CP_RAYTHEON_SHA2_MEDDEVHW_OID = 439, /* 1.3.6.1.4.1.26769.10.1.18 */ + + /* WidePoint NFI PKI OIDs */ + CP_WIDEPOINT_MEDIUMHW_OID = 310, /* 1.3.6.1.4.1.3922.1.1.1.12 */ + CP_WIDEPOINT_PIVI_HW_OID = 316, /* 1.3.6.1.4.1.3922.1.1.1.18 */ + CP_WIDEPOINT_PIVI_CONTENT_OID = 318, /* 1.3.6.1.4.1.3922.1.1.1.20 */ + CP_WIDEPOINT_MEDDEVHW_OID = 336, /* 1.3.6.1.4.1.3922.1.1.1.38 */ + + /* Australian Defence Organisation PKI OIDs */ + CP_ADO_MEDIUM_OID = 293, /* 1.2.36.1.334.1.2.1.2 */ + CP_ADO_HIGH_OID = 294, /* 1.2.36.1.334.1.2.1.3 */ + CP_ADO_RESOURCE_MEDIUM_OID = 100294, /* 1.2.36.1.334.1.2.2.2 */ + + /* Comodo Ltd PKI OID */ + CP_COMODO_OID = 100293, /* 1.3.6.1.4.1.6449.1.2.1.3.4 */ + + /* Netherlands Ministry of Defence PKI OIDs */ + CP_NL_MOD_AUTH_OID = 496, /* 2.16.528.1.1003.1.2.5.1 */ + CP_NL_MOD_IRREFUT_OID = 100497, /* 2.16.528.1.1003.1.2.5.2 */ + CP_NL_MOD_CONFID_OID = 498, /* 2.16.528.1.1003.1.2.5.3 */ #endif /* WOLFSSL_FPKI */ WOLF_ENUM_DUMMY_LAST_ELEMENT(CertificatePolicy_Sum) }; @@ -2112,11 +2287,6 @@ struct DecodedCert { #ifdef WOLFSSL_SUBJ_INFO_ACC WC_BITFIELD extSubjInfoAccSet:1; #endif -#ifdef WOLFSSL_DUAL_ALG_CERTS - WC_BITFIELD extSapkiSet:1; - WC_BITFIELD extAltSigAlgSet:1; - WC_BITFIELD extAltSigValSet:1; -#endif /* WOLFSSL_DUAL_ALG_CERTS */ #ifdef WOLFSSL_SEP WC_BITFIELD extCertPolicyCrit:1; #endif @@ -2143,6 +2313,13 @@ struct DecodedCert { /* Alternative Signature Value */ byte *altSigValDer; int altSigValLen; + + WC_BITFIELD extSapkiSet:1; + WC_BITFIELD extAltSigAlgSet:1; + WC_BITFIELD extAltSigValSet:1; + WC_BITFIELD extSapkiCrit:1; + WC_BITFIELD extAltSigAlgCrit:1; + WC_BITFIELD extAltSigValCrit:1; #endif /* WOLFSSL_DUAL_ALG_CERTS */ }; @@ -2326,19 +2503,17 @@ WOLFSSL_LOCAL int CheckCertSignaturePubKey(const byte* cert, word32 certSz, word32 pubKeySz, int pubKeyOID); #endif /* OPENSSL_EXTRA || WOLFSSL_SMALL_CERT_VERIFY */ -#ifdef WOLFSSL_DUAL_ALG_CERTS -WOLFSSL_LOCAL int wc_ConfirmAltSignature( - const byte* buf, word32 bufSz, - const byte* key, word32 keySz, word32 keyOID, - const byte* sig, word32 sigSz, word32 sigOID, - void *heap); -#endif /* WOLFSSL_DUAL_ALG_CERTS */ #if (defined(HAVE_ED25519) && defined(HAVE_ED25519_KEY_IMPORT) || \ (defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT))) WOLFSSL_LOCAL int wc_CertGetPubKey(const byte* cert, word32 certSz, const unsigned char** pubKey, word32* pubKeySz); #endif - +WOLFSSL_LOCAL int ConfirmSignature(SignatureCtx* sigCtx, + const byte* buf, word32 bufSz, + const byte* key, word32 keySz, word32 keyOID, + const byte* sig, word32 sigSz, word32 sigOID, + const byte* sigParams, word32 sigParamsSz, + byte* rsaKeyIdx); #ifdef WOLFSSL_CERT_REQ WOLFSSL_LOCAL int CheckCSRSignaturePubKey(const byte* cert, word32 certSz, void* heap, const byte* pubKey, word32 pubKeySz, int pubKeyOID); @@ -2355,6 +2530,7 @@ WOLFSSL_LOCAL int TryDecodeRPKToKey(DecodedCert* cert); WOLFSSL_LOCAL int wc_GetPubX509(DecodedCert* cert, int verify, int* badDate); WOLFSSL_LOCAL const byte* OidFromId(word32 id, word32 type, word32* oidSz); +WOLFSSL_LOCAL Signer* findSignerByKeyHash(Signer *list, byte *hash); WOLFSSL_LOCAL Signer* findSignerByName(Signer *list, byte *hash); WOLFSSL_LOCAL int FillSigner(Signer* signer, DecodedCert* cert, int type, DerBuffer *der); WOLFSSL_LOCAL Signer* MakeSigner(void* heap); @@ -2687,6 +2863,14 @@ struct CertStatus { typedef struct OcspEntry OcspEntry; +#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) +#define OCSP_DIGEST WC_HASH_TYPE_SM3 +#elif defined(NO_SHA) +#define OCSP_DIGEST WC_HASH_TYPE_SHA256 +#else +#define OCSP_DIGEST WC_HASH_TYPE_SHA +#endif + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) #define OCSP_DIGEST_SIZE WC_SM3_DIGEST_SIZE #elif defined(NO_SHA) @@ -2712,6 +2896,17 @@ struct OcspEntry WC_BITFIELD used:1; /* entry used */ }; +#define OCSP_RESPONDER_ID_KEY_SZ 20 +#if !defined(NO_SHA) +#define OCSP_RESPONDER_ID_HASH_TYPE WC_SHA +#else +#define OCSP_RESPONDER_ID_HASH_TYPE WC_SHA256 +#endif +enum responderIdType { + OCSP_RESPONDER_ID_INVALID = 0, + OCSP_RESPONDER_ID_NAME = 1, + OCSP_RESPONDER_ID_KEY = 2, +}; /* TODO: Long-term, it would be helpful if we made this struct and other OCSP structs conform to the ASN spec as described in RFC 6960. It will help with readability and with implementing OpenSSL compatibility API @@ -2723,6 +2918,12 @@ struct OcspResponse { byte* response; /* Pointer to beginning of OCSP Response */ word32 responseSz; /* length of the OCSP Response */ + enum responderIdType responderIdType; + union { + byte keyHash[OCSP_RESPONDER_ID_KEY_SZ]; + byte nameHash[KEYID_SIZE]; + } responderId ; + byte producedDate[MAX_DATE_SIZE]; /* Date at which this response was signed */ byte producedDateFormat; /* format of the producedDate */ @@ -2734,6 +2935,9 @@ struct OcspResponse { word32 sigSz; /* Length in octets for the sig */ word32 sigOID; /* OID for hash used for sig */ + byte* sigParams; + word32 sigParamsSz; + OcspEntry* single; /* chain of OCSP single responses */ byte* nonce; /* pointer to nonce inside ASN.1 response */ @@ -2742,9 +2946,6 @@ struct OcspResponse { byte* source; /* pointer to source buffer, not owned */ word32 maxIdx; /* max offset based on init size */ Signer* pendingCAs; -#ifdef OPENSSL_EXTRA - int verifyError; -#endif void* heap; }; @@ -2774,7 +2975,7 @@ WOLFSSL_LOCAL void InitOcspResponse(OcspResponse* resp, OcspEntry* single, CertStatus* status, byte* source, word32 inSz, void* heap); WOLFSSL_LOCAL void FreeOcspResponse(OcspResponse* resp); WOLFSSL_LOCAL int OcspResponseDecode(OcspResponse* resp, void* cm, void* heap, - int noVerify); + int noVerifyCert, int noVerifySignature); WOLFSSL_LOCAL int InitOcspRequest(OcspRequest* req, DecodedCert* cert, byte useNonce, void* heap); @@ -2786,7 +2987,8 @@ WOLFSSL_LOCAL word32 EncodeOcspRequestExtensions(OcspRequest* req, byte* output, WOLFSSL_LOCAL int CompareOcspReqResp(OcspRequest* req, OcspResponse* resp); - +WOLFSSL_LOCAL int OcspDecodeCertID(const byte* input, word32* inOutIdx, word32 inSz, + OcspEntry* entry); #endif /* HAVE_OCSP */ diff --git a/src/wolfssl/wolfcrypt/asn_public.h b/src/wolfssl/wolfcrypt/asn_public.h index 1196c6a..08d9cc9 100644 --- a/src/wolfssl/wolfcrypt/asn_public.h +++ b/src/wolfssl/wolfcrypt/asn_public.h @@ -1,6 +1,6 @@ /* asn_public.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -182,7 +182,8 @@ enum CertType { SPHINCS_SMALL_LEVEL5_TYPE, ECC_PARAM_TYPE, CHAIN_CERT_TYPE, - PKCS7_TYPE + PKCS7_TYPE, + TRUSTED_CERT_TYPE }; @@ -526,12 +527,15 @@ typedef struct Cert { /* Subject Alternative Public Key Info */ byte *sapkiDer; int sapkiLen; + byte sapkiCrit; /* Alternative Signature Algorithm */ byte *altSigAlgDer; int altSigAlgLen; + byte altSigAlgCrit; /* Alternative Signature Value */ byte *altSigValDer; int altSigValLen; + byte altSigValCrit; #endif /* WOLFSSL_DUAL_ALG_CERTS */ #ifdef WOLFSSL_CERT_REQ char challengePw[CTC_NAME_SIZE]; @@ -550,6 +554,7 @@ typedef struct Cert { byte* der; /* Pointer to buffer of current DecodedCert cache */ void* heap; /* heap hint */ WC_BITFIELD basicConstSet:1; /* Indicator for when Basic Constraint is set */ + byte basicConstCrit; /* Indicator of criticality of Basic Constraints extension */ #ifdef WOLFSSL_ALLOW_ENCODING_CA_FALSE WC_BITFIELD isCaSet:1; /* Indicator for when isCA is set */ #endif @@ -728,6 +733,8 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer); word32 outputSz, byte *cipherIno, int type); #endif +WOLFSSL_API word32 wc_PkcsPad(byte* buf, word32 sz, word32 blockSz); + #ifndef NO_RSA WOLFSSL_API int wc_RsaPublicKeyDecode_ex(const byte* input, word32* inOutIdx, word32 inSz, const byte** n, word32* nSz, const byte** e, word32* eSz); diff --git a/src/wolfssl/wolfcrypt/blake2-impl.h b/src/wolfssl/wolfcrypt/blake2-impl.h index 1a0db32..3f509c7 100644 --- a/src/wolfssl/wolfcrypt/blake2-impl.h +++ b/src/wolfssl/wolfcrypt/blake2-impl.h @@ -12,7 +12,7 @@ */ /* blake2-impl.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/blake2-int.h b/src/wolfssl/wolfcrypt/blake2-int.h index b048ca5..ec22921 100644 --- a/src/wolfssl/wolfcrypt/blake2-int.h +++ b/src/wolfssl/wolfcrypt/blake2-int.h @@ -12,7 +12,7 @@ */ /* blake2-int.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/blake2.h b/src/wolfssl/wolfcrypt/blake2.h index 1f4ac77..5d42c15 100644 --- a/src/wolfssl/wolfcrypt/blake2.h +++ b/src/wolfssl/wolfcrypt/blake2.h @@ -1,6 +1,6 @@ /* blake2.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -49,10 +49,12 @@ enum { #ifdef HAVE_BLAKE2B BLAKE2B_ID = WC_HASH_TYPE_BLAKE2B, BLAKE2B_256 = 32, /* 256 bit type, SSL default */ + WC_BLAKE2B_DIGEST_SIZE = 64, #endif #ifdef HAVE_BLAKE2S BLAKE2S_ID = WC_HASH_TYPE_BLAKE2S, - BLAKE2S_256 = 32 /* 256 bit type */ + BLAKE2S_256 = 32, /* 256 bit type */ + WC_BLAKE2S_DIGEST_SIZE = 32 #endif }; diff --git a/src/wolfssl/wolfcrypt/camellia.h b/src/wolfssl/wolfcrypt/camellia.h index efd187e..a31f764 100644 --- a/src/wolfssl/wolfcrypt/camellia.h +++ b/src/wolfssl/wolfcrypt/camellia.h @@ -27,7 +27,7 @@ /* camellia.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/chacha.h b/src/wolfssl/wolfcrypt/chacha.h index 1c6ae17..892b6ce 100644 --- a/src/wolfssl/wolfcrypt/chacha.h +++ b/src/wolfssl/wolfcrypt/chacha.h @@ -1,6 +1,6 @@ /* chacha.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/chacha20_poly1305.h b/src/wolfssl/wolfcrypt/chacha20_poly1305.h index ffa4031..7f9ac16 100644 --- a/src/wolfssl/wolfcrypt/chacha20_poly1305.h +++ b/src/wolfssl/wolfcrypt/chacha20_poly1305.h @@ -1,6 +1,6 @@ /* chacha20_poly1305.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -95,7 +95,7 @@ int wc_ChaCha20Poly1305_Encrypt( byte* outCiphertext, byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]); -WOLFSSL_ABI WOLFSSL_API +WOLFSSL_ABI WOLFSSL_API WARN_UNUSED_RESULT int wc_ChaCha20Poly1305_Decrypt( const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE], const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE], @@ -104,7 +104,7 @@ int wc_ChaCha20Poly1305_Decrypt( const byte inAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE], byte* outPlaintext); -WOLFSSL_API +WOLFSSL_API WARN_UNUSED_RESULT int wc_ChaCha20Poly1305_CheckTag( const byte authTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE], const byte authTagChk[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]); @@ -121,7 +121,7 @@ WOLFSSL_API int wc_ChaCha20Poly1305_UpdateAad(ChaChaPoly_Aead* aead, const byte* inAAD, word32 inAADLen); WOLFSSL_API int wc_ChaCha20Poly1305_UpdateData(ChaChaPoly_Aead* aead, const byte* inData, byte* outData, word32 dataLen); -WOLFSSL_API int wc_ChaCha20Poly1305_Final(ChaChaPoly_Aead* aead, +WOLFSSL_API WARN_UNUSED_RESULT int wc_ChaCha20Poly1305_Final(ChaChaPoly_Aead* aead, byte outAuthTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE]); #ifdef HAVE_XCHACHA @@ -140,7 +140,7 @@ WOLFSSL_API int wc_XChaCha20Poly1305_Encrypt( const byte *nonce, size_t nonce_len, const byte *key, size_t key_len); -WOLFSSL_API int wc_XChaCha20Poly1305_Decrypt( +WOLFSSL_API WARN_UNUSED_RESULT int wc_XChaCha20Poly1305_Decrypt( byte *dst, size_t dst_space, const byte *src, size_t src_len, const byte *ad, size_t ad_len, diff --git a/src/wolfssl/wolfcrypt/cmac.h b/src/wolfssl/wolfcrypt/cmac.h index 3dc6d9c..dd6e5b7 100644 --- a/src/wolfssl/wolfcrypt/cmac.h +++ b/src/wolfssl/wolfcrypt/cmac.h @@ -1,6 +1,6 @@ /* cmac.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/coding.h b/src/wolfssl/wolfcrypt/coding.h index 5aef5b1..ef87ab4 100644 --- a/src/wolfssl/wolfcrypt/coding.h +++ b/src/wolfssl/wolfcrypt/coding.h @@ -1,6 +1,6 @@ /* coding.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -36,6 +36,9 @@ WOLFSSL_API int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen); +WOLFSSL_API int Base64_Decode_nonCT(const byte* in, word32 inLen, byte* out, + word32* outLen); + #if defined(OPENSSL_EXTRA) || defined(SESSION_CERTS) || defined(WOLFSSL_KEY_GEN) \ || defined(WOLFSSL_CERT_GEN) || defined(HAVE_WEBSERVER) || !defined(NO_DSA) #ifndef WOLFSSL_BASE64_ENCODE diff --git a/src/wolfssl/wolfcrypt/compress.h b/src/wolfssl/wolfcrypt/compress.h index 2886b2b..c4d5c25 100644 --- a/src/wolfssl/wolfcrypt/compress.h +++ b/src/wolfssl/wolfcrypt/compress.h @@ -1,6 +1,6 @@ /* compress.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/cpuid.h b/src/wolfssl/wolfcrypt/cpuid.h index b7a5714..bb883cb 100644 --- a/src/wolfssl/wolfcrypt/cpuid.h +++ b/src/wolfssl/wolfcrypt/cpuid.h @@ -1,6 +1,6 @@ /* cpuid.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/cryptocb.h b/src/wolfssl/wolfcrypt/cryptocb.h index 976332f..f47cb0a 100644 --- a/src/wolfssl/wolfcrypt/cryptocb.h +++ b/src/wolfssl/wolfcrypt/cryptocb.h @@ -1,6 +1,6 @@ /* cryptocb.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -74,12 +74,12 @@ #if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) #include #endif -#ifdef WOLFSSL_HAVE_KYBER - #include -#ifdef WOLFSSL_WC_KYBER - #include +#ifdef WOLFSSL_HAVE_MLKEM + #include +#ifdef WOLFSSL_WC_MLKEM + #include #elif defined(HAVE_LIBOQS) - #include + #include #endif #endif #if defined(HAVE_DILITHIUM) @@ -101,6 +101,38 @@ enum wc_CryptoCbCmdType { }; #endif + +#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM) +typedef struct { + Aes* aes; + byte* out; + const byte* in; + word32 sz; + const byte* nonce; + word32 nonceSz; + const byte* iv; + word32 ivSz; + byte* authTag; + word32 authTagSz; + const byte* authIn; + word32 authInSz; +} wc_CryptoCb_AesAuthEnc; +typedef struct { + Aes* aes; + byte* out; + const byte* in; + word32 sz; + const byte* nonce; + word32 nonceSz; + const byte* iv; + word32 ivSz; + const byte* authTag; + word32 authTagSz; + const byte* authIn; + word32 authInSz; +} wc_CryptoCb_AesAuthDec; +#endif + /* Crypto Information Structure for callbacks */ typedef struct wc_CryptoInfo { int algo_type; /* enum wc_AlgoType */ @@ -222,7 +254,7 @@ typedef struct wc_CryptoInfo { byte contextLen; } ed25519verify; #endif - #if defined(WOLFSSL_HAVE_KYBER) + #if defined(WOLFSSL_HAVE_MLKEM) struct { WC_RNG* rng; int size; @@ -262,6 +294,9 @@ typedef struct wc_CryptoInfo { WC_RNG* rng; void* key; int type; /* enum wc_PqcSignatureType */ + const byte* context; + byte contextLen; + word32 preHashType; /* enum wc_HashType */ } pqc_sign; struct { const byte* sig; @@ -271,6 +306,9 @@ typedef struct wc_CryptoInfo { int* res; void* key; int type; /* enum wc_PqcSignatureType */ + const byte* context; + byte contextLen; + word32 preHashType; /* enum wc_HashType */ } pqc_verify; struct { void* key; @@ -291,56 +329,12 @@ typedef struct wc_CryptoInfo { union { #endif #ifdef HAVE_AESGCM - struct { - Aes* aes; - byte* out; - const byte* in; - word32 sz; - const byte* iv; - word32 ivSz; - byte* authTag; - word32 authTagSz; - const byte* authIn; - word32 authInSz; - } aesgcm_enc; - struct { - Aes* aes; - byte* out; - const byte* in; - word32 sz; - const byte* iv; - word32 ivSz; - const byte* authTag; - word32 authTagSz; - const byte* authIn; - word32 authInSz; - } aesgcm_dec; + wc_CryptoCb_AesAuthEnc aesgcm_enc; + wc_CryptoCb_AesAuthDec aesgcm_dec; #endif /* HAVE_AESGCM */ #ifdef HAVE_AESCCM - struct { - Aes* aes; - byte* out; - const byte* in; - word32 sz; - const byte* nonce; - word32 nonceSz; - byte* authTag; - word32 authTagSz; - const byte* authIn; - word32 authInSz; - } aesccm_enc; - struct { - Aes* aes; - byte* out; - const byte* in; - word32 sz; - const byte* nonce; - word32 nonceSz; - const byte* authTag; - word32 authTagSz; - const byte* authIn; - word32 authInSz; - } aesccm_dec; + wc_CryptoCb_AesAuthEnc aesccm_enc; + wc_CryptoCb_AesAuthDec aesccm_dec; #endif /* HAVE_AESCCM */ #if defined(HAVE_AES_CBC) struct { @@ -381,7 +375,7 @@ typedef struct wc_CryptoInfo { } cipher; #endif /* !NO_AES || !NO_DES3 */ #if !defined(NO_SHA) || !defined(NO_SHA256) || \ - defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) + defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA3) struct { int type; /* enum wc_HashType */ const byte* in; @@ -550,7 +544,7 @@ WOLFSSL_LOCAL int wc_CryptoCb_Ed25519Verify(const byte* sig, word32 sigLen, const byte* context, byte contextLen); #endif /* HAVE_ED25519 */ -#if defined(WOLFSSL_HAVE_KYBER) +#if defined(WOLFSSL_HAVE_MLKEM) WOLFSSL_LOCAL int wc_CryptoCb_PqcKemGetDevId(int type, void* key); WOLFSSL_LOCAL int wc_CryptoCb_MakePqcKemKey(WC_RNG* rng, int type, @@ -563,7 +557,7 @@ WOLFSSL_LOCAL int wc_CryptoCb_PqcEncapsulate(byte* ciphertext, WOLFSSL_LOCAL int wc_CryptoCb_PqcDecapsulate(const byte* ciphertext, word32 ciphertextLen, byte* sharedSecret, word32 sharedSecretLen, int type, void* key); -#endif /* WOLFSSL_HAVE_KYBER */ +#endif /* WOLFSSL_HAVE_MLKEM */ #if defined(HAVE_FALCON) || defined(HAVE_DILITHIUM) WOLFSSL_LOCAL int wc_CryptoCb_PqcSigGetDevId(int type, void* key); @@ -572,10 +566,12 @@ WOLFSSL_LOCAL int wc_CryptoCb_MakePqcSignatureKey(WC_RNG* rng, int type, int keySize, void* key); WOLFSSL_LOCAL int wc_CryptoCb_PqcSign(const byte* in, word32 inlen, byte* out, - word32 *outlen, WC_RNG* rng, int type, void* key); + word32 *outlen, const byte* context, byte contextLen, word32 preHashType, + WC_RNG* rng, int type, void* key); WOLFSSL_LOCAL int wc_CryptoCb_PqcVerify(const byte* sig, word32 siglen, - const byte* msg, word32 msglen, int* res, int type, void* key); + const byte* msg, word32 msglen, const byte* context, byte contextLen, + word32 preHashType, int* res, int type, void* key); WOLFSSL_LOCAL int wc_CryptoCb_PqcSignatureCheckPrivKey(void* key, int type, const byte* pubKey, word32 pubKeySz); diff --git a/src/wolfssl/wolfcrypt/curve25519.h b/src/wolfssl/wolfcrypt/curve25519.h index 4d18c56..f1bb574 100644 --- a/src/wolfssl/wolfcrypt/curve25519.h +++ b/src/wolfssl/wolfcrypt/curve25519.h @@ -1,6 +1,6 @@ /* curve25519.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -44,6 +44,7 @@ #define CURVE25519_KEYSIZE 32 #define CURVE25519_PUB_KEY_SIZE 32 +#define CURVE25519_MAX_KEY_TO_DER_SZ 82 /* for exported DER keys temp buffer */ #ifdef WOLFSSL_NAMES_STATIC typedef char curve25519_str[12]; @@ -91,6 +92,9 @@ struct curve25519_key { int devId; #endif void *heap; +#ifdef WOLFSSL_CURVE25519_BLINDING + WC_RNG* rng; +#endif #ifdef WOLFSSL_SE050 word32 keyId; byte keyIdSet; @@ -109,11 +113,23 @@ enum { WOLFSSL_API int wc_curve25519_make_pub(int public_size, byte* pub, int private_size, const byte* priv); +#ifdef WOLFSSL_CURVE25519_BLINDING +WOLFSSL_API +int wc_curve25519_make_pub_blind(int public_size, byte* pub, int private_size, + const byte* priv, WC_RNG* rng); +#endif WOLFSSL_API int wc_curve25519_generic(int public_size, byte* pub, int private_size, const byte* priv, int basepoint_size, const byte* basepoint); +#ifdef WOLFSSL_CURVE25519_BLINDING +WOLFSSL_API +int wc_curve25519_generic_blind(int public_size, byte* pub, + int private_size, const byte* priv, + int basepoint_size, const byte* basepoint, + WC_RNG* rng); +#endif WOLFSSL_API int wc_curve25519_make_priv(WC_RNG* rng, int keysize, byte* priv); @@ -139,13 +155,17 @@ int wc_curve25519_init_ex(curve25519_key* key, void* heap, int devId); WOLFSSL_API void wc_curve25519_free(curve25519_key* key); +#ifdef WOLFSSL_CURVE25519_BLINDING +WOLFSSL_API +int wc_curve25519_set_rng(curve25519_key* key, WC_RNG* rng); +#endif + #ifndef WC_NO_CONSTRUCTORS WOLFSSL_API curve25519_key* wc_curve25519_new(void* heap, int devId, int *result_code); WOLFSSL_API int wc_curve25519_delete(curve25519_key* key, curve25519_key** key_p); #endif -WOLFSSL_API /* raw key helpers */ WOLFSSL_API diff --git a/src/wolfssl/wolfcrypt/curve448.h b/src/wolfssl/wolfcrypt/curve448.h index b722727..756c8a3 100644 --- a/src/wolfssl/wolfcrypt/curve448.h +++ b/src/wolfssl/wolfcrypt/curve448.h @@ -1,6 +1,6 @@ /* curve448.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/des3.h b/src/wolfssl/wolfcrypt/des3.h index 78a5164..2568857 100644 --- a/src/wolfssl/wolfcrypt/des3.h +++ b/src/wolfssl/wolfcrypt/des3.h @@ -1,6 +1,6 @@ /* des3.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/dh.h b/src/wolfssl/wolfcrypt/dh.h index 865baa3..81c5623 100644 --- a/src/wolfssl/wolfcrypt/dh.h +++ b/src/wolfssl/wolfcrypt/dh.h @@ -1,6 +1,6 @@ /* dh.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/dilithium.h b/src/wolfssl/wolfcrypt/dilithium.h index c43bc7e..306cef1 100644 --- a/src/wolfssl/wolfcrypt/dilithium.h +++ b/src/wolfssl/wolfcrypt/dilithium.h @@ -1,6 +1,6 @@ /* dilithium.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -117,6 +117,10 @@ /* Buffer sizes large enough to store exported DER encoded keys */ #define DILITHIUM_LEVEL2_PUB_KEY_DER_SIZE 1334 #define DILITHIUM_LEVEL2_PRV_KEY_DER_SIZE 2588 +#define DILITHIUM_LEVEL2_BOTH_KEY_DER_SIZE 3904 +/* PEM size with the header "-----BEGIN PRIVATE KEY-----" and + * the footer "-----END PRIVATE KEY-----" */ +#define DILITHIUM_LEVEL2_BOTH_KEY_PEM_SIZE 5344 #define DILITHIUM_LEVEL3_KEY_SIZE 4032 #define DILITHIUM_LEVEL3_SIG_SIZE 3309 @@ -126,7 +130,10 @@ /* Buffer sizes large enough to store exported DER encoded keys */ #define DILITHIUM_LEVEL3_PUB_KEY_DER_SIZE 1974 #define DILITHIUM_LEVEL3_PRV_KEY_DER_SIZE 4060 - +#define DILITHIUM_LEVEL3_BOTH_KEY_DER_SIZE 6016 +/* PEM size with the header "-----BEGIN PRIVATE KEY-----" and + * the footer "-----END PRIVATE KEY-----" */ +#define DILITHIUM_LEVEL3_BOTH_KEY_PEM_SIZE 8204 #define DILITHIUM_LEVEL5_KEY_SIZE 4896 #define DILITHIUM_LEVEL5_SIG_SIZE 4627 @@ -136,6 +143,10 @@ /* Buffer sizes large enough to store exported DER encoded keys */ #define DILITHIUM_LEVEL5_PUB_KEY_DER_SIZE 2614 #define DILITHIUM_LEVEL5_PRV_KEY_DER_SIZE 4924 +#define DILITHIUM_LEVEL5_BOTH_KEY_DER_SIZE 7520 +/* PEM size with the header "-----BEGIN PRIVATE KEY-----" and + * the footer "-----END PRIVATE KEY-----" */ +#define DILITHIUM_LEVEL5_BOTH_KEY_PEM_SIZE 10239 #define ML_DSA_LEVEL2_KEY_SIZE 2560 #define ML_DSA_LEVEL2_SIG_SIZE 2420 @@ -145,6 +156,10 @@ /* Buffer sizes large enough to store exported DER encoded keys */ #define ML_DSA_LEVEL2_PUB_KEY_DER_SIZE DILITHIUM_LEVEL2_PUB_KEY_DER_SIZE #define ML_DSA_LEVEL2_PRV_KEY_DER_SIZE DILITHIUM_LEVEL2_PRV_KEY_DER_SIZE +#define ML_DSA_LEVEL2_BOTH_KEY_DER_SIZE DILITHIUM_LEVEL2_BOTH_KEY_DER_SIZE +/* PEM size with the header "-----BEGIN PRIVATE KEY-----" and + * the footer "-----END PRIVATE KEY-----" */ +#define ML_DSA_LEVEL2_BOTH_KEY_PEM_SIZE DILITHIUM_LEVEL2_BOTH_KEY_PEM_SIZE #define ML_DSA_LEVEL3_KEY_SIZE 4032 #define ML_DSA_LEVEL3_SIG_SIZE 3309 @@ -154,6 +169,10 @@ /* Buffer sizes large enough to store exported DER encoded keys */ #define ML_DSA_LEVEL3_PUB_KEY_DER_SIZE DILITHIUM_LEVEL3_PUB_KEY_DER_SIZE #define ML_DSA_LEVEL3_PRV_KEY_DER_SIZE DILITHIUM_LEVEL3_PRV_KEY_DER_SIZE +#define ML_DSA_LEVEL3_BOTH_KEY_DER_SIZE DILITHIUM_LEVEL3_BOTH_KEY_DER_SIZE +/* PEM size with the header "-----BEGIN PRIVATE KEY-----" and + * the footer "-----END PRIVATE KEY-----" */ +#define ML_DSA_LEVEL3_BOTH_KEY_PEM_SIZE DILITHIUM_LEVEL3_BOTH_KEY_PEM_SIZE #define ML_DSA_LEVEL5_KEY_SIZE 4896 #define ML_DSA_LEVEL5_SIG_SIZE 4627 @@ -163,6 +182,10 @@ /* Buffer sizes large enough to store exported DER encoded keys */ #define ML_DSA_LEVEL5_PUB_KEY_DER_SIZE DILITHIUM_LEVEL5_PUB_KEY_DER_SIZE #define ML_DSA_LEVEL5_PRV_KEY_DER_SIZE DILITHIUM_LEVEL5_PRV_KEY_DER_SIZE +#define ML_DSA_LEVEL5_BOTH_KEY_DER_SIZE DILITHIUM_LEVEL5_BOTH_KEY_DER_SIZE +/* PEM size with the header "-----BEGIN PRIVATE KEY-----" and + * the footer "-----END PRIVATE KEY-----" */ +#define ML_DSA_LEVEL5_BOTH_KEY_PEM_SIZE DILITHIUM_LEVEL5_BOTH_KEY_PEM_SIZE @@ -524,6 +547,10 @@ /* Buffer sizes large enough to store exported DER encoded keys */ #define DILITHIUM_LEVEL2_PUB_KEY_DER_SIZE 1334 #define DILITHIUM_LEVEL2_PRV_KEY_DER_SIZE 2588 +#define DILITHIUM_LEVEL2_BOTH_KEY_DER_SIZE 3904 +/* PEM size with the header "-----BEGIN PRIVATE KEY-----" and + * the footer "-----END PRIVATE KEY-----" */ +#define DILITHIUM_LEVEL2_BOTH_KEY_PEM_SIZE 5344 #define DILITHIUM_LEVEL3_KEY_SIZE OQS_SIG_ml_dsa_65_ipd_length_secret_key #define DILITHIUM_LEVEL3_SIG_SIZE OQS_SIG_ml_dsa_65_ipd_length_signature @@ -533,6 +560,10 @@ /* Buffer sizes large enough to store exported DER encoded keys */ #define DILITHIUM_LEVEL3_PUB_KEY_DER_SIZE 1974 #define DILITHIUM_LEVEL3_PRV_KEY_DER_SIZE 4060 +#define DILITHIUM_LEVEL3_BOTH_KEY_DER_SIZE 6016 +/* PEM size with the header "-----BEGIN PRIVATE KEY-----" and + * the footer "-----END PRIVATE KEY-----" */ +#define DILITHIUM_LEVEL3_BOTH_KEY_PEM_SIZE 8204 #define DILITHIUM_LEVEL5_KEY_SIZE OQS_SIG_ml_dsa_87_ipd_length_secret_key #define DILITHIUM_LEVEL5_SIG_SIZE OQS_SIG_ml_dsa_87_ipd_length_signature @@ -542,7 +573,10 @@ /* Buffer sizes large enough to store exported DER encoded keys */ #define DILITHIUM_LEVEL5_PUB_KEY_DER_SIZE 2614 #define DILITHIUM_LEVEL5_PRV_KEY_DER_SIZE 4924 - +#define DILITHIUM_LEVEL5_BOTH_KEY_DER_SIZE 7520 +/* PEM size with the header "-----BEGIN PRIVATE KEY-----" and + * the footer "-----END PRIVATE KEY-----" */ +#define DILITHIUM_LEVEL5_BOTH_KEY_PEM_SIZE 10239 #define ML_DSA_LEVEL2_KEY_SIZE OQS_SIG_ml_dsa_44_ipd_length_secret_key #define ML_DSA_LEVEL2_SIG_SIZE OQS_SIG_ml_dsa_44_ipd_length_signature @@ -552,6 +586,10 @@ /* Buffer sizes large enough to store exported DER encoded keys */ #define ML_DSA_LEVEL2_PUB_KEY_DER_SIZE DILITHIUM_LEVEL2_PUB_KEY_DER_SIZE #define ML_DSA_LEVEL2_PRV_KEY_DER_SIZE DILITHIUM_LEVEL2_PRV_KEY_DER_SIZE +#define ML_DSA_LEVEL2_BOTH_KEY_DER_SIZE DILITHIUM_LEVEL2_BOTH_KEY_DER_SIZE +/* PEM size with the header "-----BEGIN PRIVATE KEY-----" and + * the footer "-----END PRIVATE KEY-----" */ +#define ML_DSA_LEVEL2_BOTH_KEY_PEM_SIZE DILITHIUM_LEVEL2_BOTH_KEY_PEM_SIZE #define ML_DSA_LEVEL3_KEY_SIZE OQS_SIG_ml_dsa_65_ipd_length_secret_key #define ML_DSA_LEVEL3_SIG_SIZE OQS_SIG_ml_dsa_65_ipd_length_signature @@ -561,6 +599,10 @@ /* Buffer sizes large enough to store exported DER encoded keys */ #define ML_DSA_LEVEL3_PUB_KEY_DER_SIZE DILITHIUM_LEVEL3_PUB_KEY_DER_SIZE #define ML_DSA_LEVEL3_PRV_KEY_DER_SIZE DILITHIUM_LEVEL3_PRV_KEY_DER_SIZE +#define ML_DSA_LEVEL3_BOTH_KEY_DER_SIZE DILITHIUM_LEVEL3_BOTH_KEY_DER_SIZE +/* PEM size with the header "-----BEGIN PRIVATE KEY-----" and + * the footer "-----END PRIVATE KEY-----" */ +#define ML_DSA_LEVEL3_BOTH_KEY_PEM_SIZE DILITHIUM_LEVEL3_BOTH_KEY_PEM_SIZE #define ML_DSA_LEVEL5_KEY_SIZE OQS_SIG_ml_dsa_87_ipd_length_secret_key #define ML_DSA_LEVEL5_SIG_SIZE OQS_SIG_ml_dsa_87_ipd_length_signature @@ -570,6 +612,10 @@ /* Buffer sizes large enough to store exported DER encoded keys */ #define ML_DSA_LEVEL5_PUB_KEY_DER_SIZE DILITHIUM_LEVEL5_PUB_KEY_DER_SIZE #define ML_DSA_LEVEL5_PRV_KEY_DER_SIZE DILITHIUM_LEVEL5_PRV_KEY_DER_SIZE +#define ML_DSA_LEVEL5_BOTH_KEY_DER_SIZE DILITHIUM_LEVEL5_BOTH_KEY_DER_SIZE +/* PEM size with the header "-----BEGIN PRIVATE KEY-----" and + * the footer "-----END PRIVATE KEY-----" */ +#define ML_DSA_LEVEL5_BOTH_KEY_PEM_SIZE DILITHIUM_LEVEL5_BOTH_KEY_PEM_SIZE #endif @@ -580,6 +626,10 @@ /* Buffer sizes large enough to store exported DER encoded keys */ #define DILITHIUM_MAX_PUB_KEY_DER_SIZE DILITHIUM_LEVEL5_PUB_KEY_DER_SIZE #define DILITHIUM_MAX_PRV_KEY_DER_SIZE DILITHIUM_LEVEL5_PRV_KEY_DER_SIZE +#define DILITHIUM_MAX_BOTH_KEY_DER_SIZE DILITHIUM_LEVEL5_BOTH_KEY_DER_SIZE +/* PEM size with the header "-----BEGIN PRIVATE KEY-----" and + * the footer "-----END PRIVATE KEY-----" */ +#define DILITHIUM_MAX_BOTH_KEY_PEM_SIZE DILITHIUM_LEVEL5_BOTH_KEY_PEM_SIZE #ifdef WOLF_PRIVATE_KEY_ID @@ -813,6 +863,10 @@ int wc_dilithium_export_key(dilithium_key* key, byte* priv, word32 *privSz, byte* pub, word32 *pubSz); #endif +#ifndef WOLFSSL_DILITHIUM_NO_ASN1 +WOLFSSL_LOCAL int dilithium_get_oid_sum(dilithium_key* key, int* keyFormat); +#endif /* WOLFSSL_DILITHIUM_NO_ASN1 */ + #ifndef WOLFSSL_DILITHIUM_NO_ASN1 #if defined(WOLFSSL_DILITHIUM_PRIVATE_KEY) WOLFSSL_API int wc_Dilithium_PrivateKeyDecode(const byte* input, @@ -894,6 +948,13 @@ WOLFSSL_API int wc_Dilithium_PrivateKeyToDer(dilithium_key* key, byte* output, #define wc_MlDsaKey_Verify(key, sig, sigSz, msg, msgSz, res) \ wc_dilithium_verify_msg(sig, sigSz, msg, msgSz, res, key) +#define wc_MlDsaKey_PublicKeyToDer(key, output, len, withAlg) \ + wc_Dilithium_PublicKeyToDer(key, output, len, withAlg) + +#define wc_MlDsaKey_PrivateKeyToDer(key, output, len) \ + wc_Dilithium_PrivateKeyToDer(key, output, len) + + WOLFSSL_API int wc_MlDsaKey_GetPrivLen(MlDsaKey* key, int* len); WOLFSSL_API int wc_MlDsaKey_GetPubLen(MlDsaKey* key, int* len); WOLFSSL_API int wc_MlDsaKey_GetSigLen(MlDsaKey* key, int* len); diff --git a/src/wolfssl/wolfcrypt/dsa.h b/src/wolfssl/wolfcrypt/dsa.h index 1e92fd5..4ae42c3 100644 --- a/src/wolfssl/wolfcrypt/dsa.h +++ b/src/wolfssl/wolfcrypt/dsa.h @@ -1,6 +1,6 @@ /* dsa.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/ecc.h b/src/wolfssl/wolfcrypt/ecc.h index 71a7a8b..04a7a66 100644 --- a/src/wolfssl/wolfcrypt/ecc.h +++ b/src/wolfssl/wolfcrypt/ecc.h @@ -1,6 +1,6 @@ /* ecc.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -287,7 +287,8 @@ typedef byte ecc_oid_t; #endif -#if !defined(WOLFSSL_ECC_CURVE_STATIC) && defined(USE_WINDOWS_API) +#if !defined(WOLFSSL_ECC_CURVE_STATIC) && defined(USE_WINDOWS_API) && \ + !defined(__WATCOMC__) /* MSC does something different with the pointers to the arrays than GCC, * and it causes the FIPS checksum to fail. In the case of windows builds, * store everything as arrays instead of pointers to strings. */ diff --git a/src/wolfssl/wolfcrypt/eccsi.h b/src/wolfssl/wolfcrypt/eccsi.h index 34e10bf..5136d13 100644 --- a/src/wolfssl/wolfcrypt/eccsi.h +++ b/src/wolfssl/wolfcrypt/eccsi.h @@ -1,6 +1,6 @@ /* eccsi.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/ed25519.h b/src/wolfssl/wolfcrypt/ed25519.h index 8c660b2..f7367b5 100644 --- a/src/wolfssl/wolfcrypt/ed25519.h +++ b/src/wolfssl/wolfcrypt/ed25519.h @@ -1,6 +1,6 @@ /* ed25519.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -187,7 +187,6 @@ ed25519_key* wc_ed25519_new(void* heap, int devId, int *result_code); WOLFSSL_API int wc_ed25519_delete(ed25519_key* key, ed25519_key** key_p); #endif -WOLFSSL_API #ifdef HAVE_ED25519_KEY_IMPORT WOLFSSL_API diff --git a/src/wolfssl/wolfcrypt/ed448.h b/src/wolfssl/wolfcrypt/ed448.h index 9e2e890..e79a048 100644 --- a/src/wolfssl/wolfcrypt/ed448.h +++ b/src/wolfssl/wolfcrypt/ed448.h @@ -1,6 +1,6 @@ /* ed448.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/error-crypt.h b/src/wolfssl/wolfcrypt/error-crypt.h index 5668783..f466e29 100644 --- a/src/wolfssl/wolfcrypt/error-crypt.h +++ b/src/wolfssl/wolfcrypt/error-crypt.h @@ -1,6 +1,6 @@ /* error-crypt.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -135,7 +135,8 @@ enum wolfCrypt_ErrorCodes { ED25519_KAT_FIPS_E = -163, /* Ed25519 Known answer test failure */ ED448_KAT_FIPS_E = -164, /* Ed448 Known answer test failure */ PBKDF2_KAT_FIPS_E = -165, /* PBKDF2 Known answer test failure */ - /* -166..-169 unused. */ + WC_KEY_MISMATCH_E = -166, /* Error for private/public key mismatch */ + /* -167..-169 unused. */ ECC_BAD_ARG_E = -170, /* ECC input argument of wrong type */ ASN_ECC_KEY_E = -171, /* ASN ECC bad input */ @@ -302,11 +303,12 @@ enum wolfCrypt_ErrorCodes { WC_SPAN2_FIRST_E = -1000, DEADLOCK_AVERTED_E = -1000, /* Deadlock averted -- retry the call */ + ASCON_AUTH_E = -1001, /* ASCON Authentication check failure */ - WC_SPAN2_LAST_E = -1000, /* Update to indicate last used error code */ + WC_SPAN2_LAST_E = -1001, /* Update to indicate last used error code */ WC_SPAN2_MIN_CODE_E = -1999, /* Last usable code in span 2 */ - WC_LAST_E = -1000, /* the last code used either here or in + WC_LAST_E = -1001, /* the last code used either here or in * error-ssl.h */ @@ -325,7 +327,7 @@ wc_static_assert((int)MIN_CODE_E <= (int)WC_SPAN2_MIN_CODE_E); #ifdef NO_ERROR_STRINGS #define wc_GetErrorString(error) "no support for error strings built in" #define wc_ErrorString(err, buf) \ - (void)err; XSTRNCPY((buf), wc_GetErrorString((err)), \ + (void)(err); XSTRNCPY((buf), wc_GetErrorString(err), \ WOLFSSL_MAX_ERROR_SZ); #else diff --git a/src/wolfssl/wolfcrypt/ext_lms.h b/src/wolfssl/wolfcrypt/ext_lms.h index 4120335..2c7d116 100644 --- a/src/wolfssl/wolfcrypt/ext_lms.h +++ b/src/wolfssl/wolfcrypt/ext_lms.h @@ -1,6 +1,6 @@ /* ext_lms.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/ext_mlkem.h b/src/wolfssl/wolfcrypt/ext_mlkem.h new file mode 100644 index 0000000..53c6c7d --- /dev/null +++ b/src/wolfssl/wolfcrypt/ext_mlkem.h @@ -0,0 +1,74 @@ +/* ext_mlkem.h + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef EXT_KYBER_H +#define EXT_KYBER_H + +#ifdef WOLF_CRYPTO_CB + #include +#endif + +#ifdef WOLFSSL_HAVE_MLKEM +#include + +#if !defined(HAVE_LIBOQS) +#error "This code requires liboqs" +#endif + +#if defined(WOLFSSL_WC_MLKEM) +#error "This code is incompatible with wolfCrypt's implementation of Kyber." +#endif + +#if defined (HAVE_LIBOQS) + #include + + #ifndef WOLFSSL_NO_ML_KEM + #define EXT_KYBER_MAX_PRIV_SZ OQS_KEM_ml_kem_1024_length_secret_key + #define EXT_KYBER_MAX_PUB_SZ OQS_KEM_ml_kem_1024_length_public_key + #elif defined(WOLFSSL_MLKEM_KYBER) + #define EXT_KYBER_MAX_PRIV_SZ OQS_KEM_kyber_1024_length_secret_key + #define EXT_KYBER_MAX_PUB_SZ OQS_KEM_kyber_1024_length_public_key + #endif +#endif + +struct KyberKey { + /* Type of key: KYBER_LEVEL1 + * KYBER_LEVEL3 + * KYBER_LEVEL5 + * + * Note we don't save the variant (SHAKE vs AES) as that is decided at + * configuration time. */ + int type; + +#ifdef WOLF_CRYPTO_CB + void* devCtx; + int devId; +#endif + + byte priv[EXT_KYBER_MAX_PRIV_SZ]; + byte pub[EXT_KYBER_MAX_PUB_SZ]; +}; + +#if defined (HAVE_LIBOQS) +WOLFSSL_LOCAL int ext_mlkem_enabled(int id); +#endif +#endif /* WOLFSSL_HAVE_MLKEM */ +#endif /* EXT_KYBER_H */ diff --git a/src/wolfssl/wolfcrypt/ext_xmss.h b/src/wolfssl/wolfcrypt/ext_xmss.h index cb041bc..1c7ed35 100644 --- a/src/wolfssl/wolfcrypt/ext_xmss.h +++ b/src/wolfssl/wolfcrypt/ext_xmss.h @@ -1,6 +1,6 @@ /* ext_xmss.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/falcon.h b/src/wolfssl/wolfcrypt/falcon.h index a103034..45ae673 100644 --- a/src/wolfssl/wolfcrypt/falcon.h +++ b/src/wolfssl/wolfcrypt/falcon.h @@ -1,6 +1,6 @@ /* falcon.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/fe_448.h b/src/wolfssl/wolfcrypt/fe_448.h index 09ff150..fef9d17 100644 --- a/src/wolfssl/wolfcrypt/fe_448.h +++ b/src/wolfssl/wolfcrypt/fe_448.h @@ -1,6 +1,6 @@ /* fe448_448.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -29,7 +29,8 @@ #include -#if defined(HAVE___UINT128_T) && !defined(NO_CURVED448_128BIT) +#if defined(HAVE___UINT128_T) && !defined(NO_CURVED448_128BIT) && \ + !defined(NO_INT128) #define CURVED448_128BIT #endif diff --git a/src/wolfssl/wolfcrypt/fe_operations.h b/src/wolfssl/wolfcrypt/fe_operations.h index 23928f2..dd029ec 100644 --- a/src/wolfssl/wolfcrypt/fe_operations.h +++ b/src/wolfssl/wolfcrypt/fe_operations.h @@ -1,6 +1,6 @@ /* fe_operations.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -76,6 +76,10 @@ Bounds on each t[i] vary depending on context. WOLFSSL_LOCAL void fe_init(void); WOLFSSL_LOCAL int curve25519(byte * q, const byte * n, const byte * p); +#ifdef WOLFSSL_CURVE25519_BLINDING +WOLFSSL_LOCAL int curve25519_blind(byte * q, const byte * n, const byte* mask, + const byte * p, const byte* rz); +#endif #endif /* default to be faster but take more memory */ diff --git a/src/wolfssl/wolfcrypt/fips_test.h b/src/wolfssl/wolfcrypt/fips_test.h index 6523753..16f170b 100644 --- a/src/wolfssl/wolfcrypt/fips_test.h +++ b/src/wolfssl/wolfcrypt/fips_test.h @@ -1,6 +1,6 @@ /* fips_test.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -72,7 +72,9 @@ enum FipsCastId { FIPS_CAST_ED25519 = 16, FIPS_CAST_ED448 = 17, FIPS_CAST_PBKDF2 = 18, - FIPS_CAST_COUNT = 19 + /* v7.0.0 + */ + FIPS_CAST_AES_ECB = 19, + FIPS_CAST_COUNT = 20 }; enum FipsCastStateId { diff --git a/src/wolfssl/wolfcrypt/ge_448.h b/src/wolfssl/wolfcrypt/ge_448.h index a9d4d47..82665cf 100644 --- a/src/wolfssl/wolfcrypt/ge_448.h +++ b/src/wolfssl/wolfcrypt/ge_448.h @@ -1,6 +1,6 @@ /* ge_448.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/ge_operations.h b/src/wolfssl/wolfcrypt/ge_operations.h index 75d4b07..9a4d995 100644 --- a/src/wolfssl/wolfcrypt/ge_operations.h +++ b/src/wolfssl/wolfcrypt/ge_operations.h @@ -1,6 +1,6 @@ /* ge_operations.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/hash.h b/src/wolfssl/wolfcrypt/hash.h index ee001a9..02d99d4 100644 --- a/src/wolfssl/wolfcrypt/hash.h +++ b/src/wolfssl/wolfcrypt/hash.h @@ -1,6 +1,6 @@ /* hash.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -83,16 +83,6 @@ enum wc_MACAlgorithm { sm3_mac }; -enum wc_HashFlags { - WC_HASH_FLAG_NONE = 0x00000000, - WC_HASH_FLAG_WILLCOPY = 0x00000001, /* flag to indicate hash will be copied */ - WC_HASH_FLAG_ISCOPY = 0x00000002, /* hash is copy */ -#ifdef WOLFSSL_SHA3 - WC_HASH_SHA3_KECCAK256 =0x00010000, /* Older KECCAK256 */ -#endif - WOLF_ENUM_DUMMY_LAST_ELEMENT(WC_HASH) -}; - /* hash union */ typedef union { #ifndef NO_MD5 diff --git a/src/wolfssl/wolfcrypt/hmac.h b/src/wolfssl/wolfcrypt/hmac.h index fd5d8d3..96da94c 100644 --- a/src/wolfssl/wolfcrypt/hmac.h +++ b/src/wolfssl/wolfcrypt/hmac.h @@ -1,6 +1,6 @@ /* hmac.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -124,6 +124,10 @@ typedef wc_Hashes wc_HmacHash; /* Hmac digest */ struct Hmac { wc_HmacHash hash; +#ifdef WOLFSSL_HMAC_COPY_HASH + wc_HmacHash i_hash; + wc_HmacHash o_hash; +#endif word32 ipad[WC_HMAC_BLOCK_SIZE / sizeof(word32)]; /* same block size all*/ word32 opad[WC_HMAC_BLOCK_SIZE / sizeof(word32)]; word32 innerHash[WC_MAX_DIGEST_SIZE / sizeof(word32)]; diff --git a/src/wolfssl/wolfcrypt/hpke.h b/src/wolfssl/wolfcrypt/hpke.h index 3bf61e5..cacfca6 100644 --- a/src/wolfssl/wolfcrypt/hpke.h +++ b/src/wolfssl/wolfcrypt/hpke.h @@ -1,6 +1,6 @@ /* hpke.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -120,9 +120,18 @@ WOLFSSL_API int wc_HpkeDeserializePublicKey(Hpke* hpke, void** key, const byte* in, word16 inSz); WOLFSSL_API void wc_HpkeFreeKey(Hpke* hpke, word16 kem, void* keypair, void* heap); +WOLFSSL_API int wc_HpkeInitSealContext(Hpke* hpke, HpkeBaseContext* context, + void* ephemeralKey, void* receiverKey, byte* info, word32 infoSz); +WOLFSSL_API int wc_HpkeContextSealBase(Hpke* hpke, HpkeBaseContext* context, + byte* aad, word32 aadSz, byte* plaintext, word32 ptSz, byte* out); WOLFSSL_API int wc_HpkeSealBase(Hpke* hpke, void* ephemeralKey, void* receiverKey, byte* info, word32 infoSz, byte* aad, word32 aadSz, byte* plaintext, word32 ptSz, byte* ciphertext); +WOLFSSL_API int wc_HpkeInitOpenContext(Hpke* hpke, HpkeBaseContext* context, + void* receiverKey, const byte* pubKey, word16 pubKeySz, byte* info, + word32 infoSz); +WOLFSSL_API int wc_HpkeContextOpenBase(Hpke* hpke, HpkeBaseContext* context, + byte* aad, word32 aadSz, byte* ciphertext, word32 ctSz, byte* out); WOLFSSL_API int wc_HpkeOpenBase(Hpke* hpke, void* receiverKey, const byte* pubKey, word16 pubKeySz, byte* info, word32 infoSz, byte* aad, word32 aadSz, byte* ciphertext, word32 ctSz, byte* plaintext); diff --git a/src/wolfssl/wolfcrypt/integer.h b/src/wolfssl/wolfcrypt/integer.h index e98cd35..68bda1f 100644 --- a/src/wolfssl/wolfcrypt/integer.h +++ b/src/wolfssl/wolfcrypt/integer.h @@ -1,6 +1,6 @@ /* integer.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/kdf.h b/src/wolfssl/wolfcrypt/kdf.h index 66b3a7a..d2fd388 100644 --- a/src/wolfssl/wolfcrypt/kdf.h +++ b/src/wolfssl/wolfcrypt/kdf.h @@ -1,6 +1,6 @@ /* kdf.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/libwolfssl_sources.h b/src/wolfssl/wolfcrypt/libwolfssl_sources.h new file mode 100644 index 0000000..474cbe1 --- /dev/null +++ b/src/wolfssl/wolfcrypt/libwolfssl_sources.h @@ -0,0 +1,50 @@ +/* libwolfssl_sources.h + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* In wolfSSL library sources, #include this file before any other #includes, to + * assure BUILDING_WOLFSSL is defined. + * + * This file also includes the common headers needed by all sources. + */ + +#ifndef LIBWOLFSSL_SOURCES_H +#define LIBWOLFSSL_SOURCES_H + +#if defined(TEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE) && \ + defined(WOLF_CRYPT_SETTINGS_H) && \ + !defined(LIBWOLFSSL_SOURCES_ASM_H) + #error settings.h included before libwolfssl_sources.h. +#endif + +#ifndef BUILDING_WOLFSSL + #define BUILDING_WOLFSSL +#endif + +#if defined(HAVE_CONFIG_H) && !defined(WC_CONFIG_H_INCLUDED) + #include + #define WC_CONFIG_H_INCLUDED +#endif + +#include +#include +#include + +#endif /* LIBWOLFSSL_SOURCES_H */ diff --git a/src/wolfssl/wolfcrypt/libwolfssl_sources_asm.h b/src/wolfssl/wolfcrypt/libwolfssl_sources_asm.h new file mode 100644 index 0000000..a3d85c9 --- /dev/null +++ b/src/wolfssl/wolfcrypt/libwolfssl_sources_asm.h @@ -0,0 +1,48 @@ +/* libwolfssl_sources_asm.h + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* In wolfSSL library sources, #include this file before any other #includes, to + * assure BUILDING_WOLFSSL is defined. + * + * This file also includes the common headers needed by all sources. + */ + +#ifndef LIBWOLFSSL_SOURCES_ASM_H +#define LIBWOLFSSL_SOURCES_ASM_H + +#if defined(TEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE) && \ + defined(WOLF_CRYPT_SETTINGS_H) && \ + !defined(LIBWOLFSSL_SOURCES_H) + #error settings.h included before libwolfssl_sources_asm.h. +#endif + +#ifndef BUILDING_WOLFSSL + #define BUILDING_WOLFSSL +#endif + +#if defined(HAVE_CONFIG_H) && !defined(WC_CONFIG_H_INCLUDED) + #include + #define WC_CONFIG_H_INCLUDED +#endif + +#include + +#endif /* LIBWOLFSSL_SOURCES_ASM_H */ diff --git a/src/wolfssl/wolfcrypt/lms.h b/src/wolfssl/wolfcrypt/lms.h index 1534fb1..ee4ccc5 100644 --- a/src/wolfssl/wolfcrypt/lms.h +++ b/src/wolfssl/wolfcrypt/lms.h @@ -1,6 +1,6 @@ /* lms.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -127,6 +127,9 @@ enum wc_LmsParm { WC_LMS_PARM_SHA256_192_L1_H10_W8 = 42, WC_LMS_PARM_SHA256_192_L1_H15_W2 = 43, WC_LMS_PARM_SHA256_192_L1_H15_W4 = 44, + WC_LMS_PARM_SHA256_192_L1_H20_W2 = 53, + WC_LMS_PARM_SHA256_192_L1_H20_W4 = 54, + WC_LMS_PARM_SHA256_192_L1_H20_W8 = 55, WC_LMS_PARM_SHA256_192_L2_H10_W2 = 45, WC_LMS_PARM_SHA256_192_L2_H10_W4 = 46, WC_LMS_PARM_SHA256_192_L2_H10_W8 = 47, @@ -183,6 +186,9 @@ WOLFSSL_API int wc_LmsKey_Verify(LmsKey * key, const byte * sig, word32 sigSz, const byte * msg, int msgSz); WOLFSSL_API const char * wc_LmsKey_ParmToStr(enum wc_LmsParm lmsParm); WOLFSSL_API const char * wc_LmsKey_RcToStr(enum wc_LmsRc lmsRc); + +WOLFSSL_API const byte * wc_LmsKey_GetKidFromPrivRaw(const byte * priv, + word32 privSz); #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/wolfssl/wolfcrypt/logging.h b/src/wolfssl/wolfcrypt/logging.h index a60f70b..49de701 100644 --- a/src/wolfssl/wolfcrypt/logging.h +++ b/src/wolfssl/wolfcrypt/logging.h @@ -1,6 +1,6 @@ /* logging.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -135,7 +135,7 @@ WOLFSSL_API void wolfSSL_SetLoggingPrefix(const char* prefix); WOLFSSL_LOCAL unsigned long wc_PeekErrorNodeLineData( const char **file, int *line, const char **data, int *flags, int (*ignore_err)(int err)); - WOLFSSL_LOCAL unsigned long wc_GetErrorNodeErr(void); + WOLFSSL_LOCAL int wc_GetErrorNodeErr(void); #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) WOLFSSL_API void wc_ERR_print_errors_fp(XFILE fp); WOLFSSL_API void wc_ERR_print_errors_cb(int (*cb)(const char *str, @@ -174,7 +174,7 @@ WOLFSSL_API void wolfSSL_SetLoggingPrefix(const char* prefix); #define WOLFSSL_STUB(m) \ WOLFSSL_MSG(WOLFSSL_LOG_CAT(wolfSSL Stub, m, not implemented)) WOLFSSL_API int WOLFSSL_IS_DEBUG_ON(void); -#if defined(XVSNPRINTF) +#if defined(XVSNPRINTF) && !defined(NO_WOLFSSL_MSG_EX) WOLFSSL_API void WOLFSSL_MSG_EX(const char* fmt, ...); #define HAVE_WOLFSSL_MSG_EX #else diff --git a/src/wolfssl/wolfcrypt/md2.h b/src/wolfssl/wolfcrypt/md2.h index 73be110..8fb5076 100644 --- a/src/wolfssl/wolfcrypt/md2.h +++ b/src/wolfssl/wolfcrypt/md2.h @@ -1,6 +1,6 @@ /* md2.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/md4.h b/src/wolfssl/wolfcrypt/md4.h index b253f8d..78c4275 100644 --- a/src/wolfssl/wolfcrypt/md4.h +++ b/src/wolfssl/wolfcrypt/md4.h @@ -1,6 +1,6 @@ /* md4.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/md5.h b/src/wolfssl/wolfcrypt/md5.h index 59d1f8d..93b906d 100644 --- a/src/wolfssl/wolfcrypt/md5.h +++ b/src/wolfssl/wolfcrypt/md5.h @@ -1,6 +1,6 @@ /* md5.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/mem_track.h b/src/wolfssl/wolfcrypt/mem_track.h index a69d1f0..205ec57 100644 --- a/src/wolfssl/wolfcrypt/mem_track.h +++ b/src/wolfssl/wolfcrypt/mem_track.h @@ -1,6 +1,6 @@ /* mem_track.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -596,7 +596,7 @@ static WC_INLINE int StackSizeCheck(struct func_args* args, thread_func tf) #endif #ifdef PTHREAD_STACK_MIN - if (stackSize < PTHREAD_STACK_MIN) + if (stackSize < (size_t)PTHREAD_STACK_MIN) stackSize = PTHREAD_STACK_MIN; #endif @@ -677,7 +677,7 @@ static WC_INLINE int StackSizeCheck_launch(struct func_args* args, struct stack_size_debug_context* shim_args; #ifdef PTHREAD_STACK_MIN - if (stackSize < PTHREAD_STACK_MIN) + if (stackSize < (size_t)PTHREAD_STACK_MIN) stackSize = PTHREAD_STACK_MIN; #endif diff --git a/src/wolfssl/wolfcrypt/memory.h b/src/wolfssl/wolfcrypt/memory.h index 179a8fd..5170a8c 100644 --- a/src/wolfssl/wolfcrypt/memory.h +++ b/src/wolfssl/wolfcrypt/memory.h @@ -1,6 +1,6 @@ /* memory.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/misc.h b/src/wolfssl/wolfcrypt/misc.h index 579c536..561c9a2 100644 --- a/src/wolfssl/wolfcrypt/misc.h +++ b/src/wolfssl/wolfcrypt/misc.h @@ -1,6 +1,6 @@ /* misc.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -134,6 +134,9 @@ WOLFSSL_LOCAL int CharIsWhiteSpace(char ch); WOLFSSL_LOCAL byte ctMaskGT(int a, int b); WOLFSSL_LOCAL byte ctMaskGTE(int a, int b); WOLFSSL_LOCAL int ctMaskIntGTE(int a, int b); +#ifdef WORD64_AVAILABLE +WOLFSSL_LOCAL word32 ctMaskWord32GTE(word32 a, word32 b); +#endif WOLFSSL_LOCAL byte ctMaskLT(int a, int b); WOLFSSL_LOCAL byte ctMaskLTE(int a, int b); WOLFSSL_LOCAL byte ctMaskEq(int a, int b); diff --git a/src/wolfssl/wolfcrypt/mlkem.h b/src/wolfssl/wolfcrypt/mlkem.h new file mode 100644 index 0000000..4a922a1 --- /dev/null +++ b/src/wolfssl/wolfcrypt/mlkem.h @@ -0,0 +1,374 @@ +/* mlkem.h + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/mlkem.h + */ + +#ifndef WOLF_CRYPT_MLKEM_H +#define WOLF_CRYPT_MLKEM_H + +#include +#include + +#ifdef WOLFSSL_HAVE_MLKEM + +/* Number of co-efficients in polynomial. */ +#define MLKEM_N 256 + +/* Define algorithm type when not excluded. */ +#ifndef WOLFSSL_NO_ML_KEM + #if !defined(WOLFSSL_NO_ML_KEM_512) + #define WOLFSSL_WC_ML_KEM_512 + #endif + #if !defined(WOLFSSL_NO_ML_KEM_768) + #define WOLFSSL_WC_ML_KEM_768 + #endif + #if !defined(WOLFSSL_NO_ML_KEM_1024) + #define WOLFSSL_WC_ML_KEM_1024 + #endif + + #if !defined(WOLFSSL_WC_ML_KEM_512) && !defined(WOLFSSL_WC_ML_KEM_768) && \ + !defined(WOLFSSL_WC_ML_KEM_1024) + #error "No ML-KEM key size chosen." + #endif +#endif + +#ifdef WOLFSSL_MLKEM_KYBER + #ifndef WOLFSSL_NO_KYBER512 + #define WOLFSSL_KYBER512 + #define WOLFSSL_WC_ML_KEM_512 + #endif + #ifndef WOLFSSL_NO_KYBER768 + #define WOLFSSL_KYBER768 + #define WOLFSSL_WC_ML_KEM_768 + #endif + #ifndef WOLFSSL_NO_KYBER1024 + #define WOLFSSL_KYBER1024 + #define WOLFSSL_WC_ML_KEM_1024 + #endif + + #if !defined(WOLFSSL_KYBER512) && !defined(WOLFSSL_KYBER768) && \ + !defined(WOLFSSL_KYBER1024) + #error "No Kyber key size chosen." + #endif +#endif + +/* Size of a polynomial vector based on dimensions. */ +#define MLKEM_POLY_VEC_SZ(k) ((k) * WC_ML_KEM_POLY_SIZE) +/* Size of a compressed polynomial based on bits per coefficient. */ +#define MLKEM_POLY_COMPRESSED_SZ(b) ((b) * (MLKEM_N / 8)) +/* Size of a compressed vector polynomial based on dimensions and bits per + * coefficient. */ +#define MLKEM_POLY_VEC_COMPRESSED_SZ(k, b) ((k) * ((b) * (MLKEM_N / 8))) + +#ifdef WOLFSSL_WC_ML_KEM_512 +#define WC_ML_KEM_512_K 2 +/* Size of a polynomial vector. */ +#define WC_ML_KEM_512_POLY_VEC_SZ MLKEM_POLY_VEC_SZ(WC_ML_KEM_512_K) +/* Size of a compressed polynomial based on bits per coefficient. */ +#define WC_ML_KEM_512_POLY_COMPRESSED_SZ MLKEM_POLY_COMPRESSED_SZ(4) +/* Size of a compressed vector polynomial based on dimensions and bits per + * coefficient. */ +#define WC_ML_KEM_512_POLY_VEC_COMPRESSED_SZ \ + MLKEM_POLY_VEC_COMPRESSED_SZ(WC_ML_KEM_512_K, 10) + +/* Public key size. */ +#define WC_ML_KEM_512_PUBLIC_KEY_SIZE \ + (WC_ML_KEM_512_POLY_VEC_SZ + WC_ML_KEM_SYM_SZ) +/* Private key size. */ +#define WC_ML_KEM_512_PRIVATE_KEY_SIZE \ + (WC_ML_KEM_512_POLY_VEC_SZ + WC_ML_KEM_512_PUBLIC_KEY_SIZE + \ + 2 * WC_ML_KEM_SYM_SZ) +/* Cipher text size. */ +#define WC_ML_KEM_512_CIPHER_TEXT_SIZE \ + (WC_ML_KEM_512_POLY_VEC_COMPRESSED_SZ + WC_ML_KEM_512_POLY_COMPRESSED_SZ) +#endif + +#ifdef WOLFSSL_WC_ML_KEM_768 +#define WC_ML_KEM_768_K 3 + +/* Size of a polynomial vector. */ +#define WC_ML_KEM_768_POLY_VEC_SZ MLKEM_POLY_VEC_SZ(WC_ML_KEM_768_K) +/* Size of a compressed polynomial based on bits per coefficient. */ +#define WC_ML_KEM_768_POLY_COMPRESSED_SZ MLKEM_POLY_COMPRESSED_SZ(4) +/* Size of a compressed vector polynomial based on dimensions and bits per + * coefficient. */ +#define WC_ML_KEM_768_POLY_VEC_COMPRESSED_SZ \ + MLKEM_POLY_VEC_COMPRESSED_SZ(WC_ML_KEM_768_K, 10) + +/* Public key size. */ +#define WC_ML_KEM_768_PUBLIC_KEY_SIZE \ + (WC_ML_KEM_768_POLY_VEC_SZ + WC_ML_KEM_SYM_SZ) +/* Private key size. */ +#define WC_ML_KEM_768_PRIVATE_KEY_SIZE \ + (WC_ML_KEM_768_POLY_VEC_SZ + WC_ML_KEM_768_PUBLIC_KEY_SIZE + \ + 2 * WC_ML_KEM_SYM_SZ) +/* Cipher text size. */ +#define WC_ML_KEM_768_CIPHER_TEXT_SIZE \ + (WC_ML_KEM_768_POLY_VEC_COMPRESSED_SZ + WC_ML_KEM_768_POLY_COMPRESSED_SZ) +#endif + +#ifdef WOLFSSL_WC_ML_KEM_1024 +#define WC_ML_KEM_1024_K 4 + +/* Size of a polynomial vector. */ +#define WC_ML_KEM_1024_POLY_VEC_SZ MLKEM_POLY_VEC_SZ(WC_ML_KEM_1024_K) +/* Size of a compressed polynomial based on bits per coefficient. */ +#define WC_ML_KEM_1024_POLY_COMPRESSED_SZ MLKEM_POLY_COMPRESSED_SZ(5) +/* Size of a compressed vector polynomial based on dimensions and bits per + * coefficient. */ +#define WC_ML_KEM_1024_POLY_VEC_COMPRESSED_SZ \ + MLKEM_POLY_VEC_COMPRESSED_SZ(WC_ML_KEM_1024_K, 11) + +/* Public key size. */ +#define WC_ML_KEM_1024_PUBLIC_KEY_SIZE \ + (WC_ML_KEM_1024_POLY_VEC_SZ + WC_ML_KEM_SYM_SZ) +/* Private key size. */ +#define WC_ML_KEM_1024_PRIVATE_KEY_SIZE \ + (WC_ML_KEM_1024_POLY_VEC_SZ + WC_ML_KEM_1024_PUBLIC_KEY_SIZE + \ + 2 * WC_ML_KEM_SYM_SZ) +/* Cipher text size. */ +#define WC_ML_KEM_1024_CIPHER_TEXT_SIZE \ + (WC_ML_KEM_1024_POLY_VEC_COMPRESSED_SZ + WC_ML_KEM_1024_POLY_COMPRESSED_SZ) +#endif + +#ifndef WC_ML_KEM_MAX_K +#ifdef WOLFSSL_WC_ML_KEM_1024 +#define WC_ML_KEM_MAX_K WC_ML_KEM_1024_K +#define WC_ML_KEM_MAX_PRIVATE_KEY_SIZE WC_ML_KEM_1024_PRIVATE_KEY_SIZE +#define WC_ML_KEM_MAX_PUBLIC_KEY_SIZE WC_ML_KEM_1024_PUBLIC_KEY_SIZE +#define WC_ML_KEM_MAX_CIPHER_TEXT_SIZE WC_ML_KEM_1024_CIPHER_TEXT_SIZE +#elif defined(WOLFSSL_WC_ML_KEM_768) +#define WC_ML_KEM_MAX_K WC_ML_KEM_768_K +#define WC_ML_KEM_MAX_PRIVATE_KEY_SIZE WC_ML_KEM_768_PRIVATE_KEY_SIZE +#define WC_ML_KEM_MAX_PUBLIC_KEY_SIZE WC_ML_KEM_768_PUBLIC_KEY_SIZE +#define WC_ML_KEM_MAX_CIPHER_TEXT_SIZE WC_ML_KEM_768_CIPHER_TEXT_SIZE +#elif defined(WOLFSSL_WC_ML_KEM_512) +#define WC_ML_KEM_MAX_K WC_ML_KEM_512_K +#define WC_ML_KEM_MAX_PRIVATE_KEY_SIZE WC_ML_KEM_512_PRIVATE_KEY_SIZE +#define WC_ML_KEM_MAX_PUBLIC_KEY_SIZE WC_ML_KEM_512_PUBLIC_KEY_SIZE +#define WC_ML_KEM_MAX_CIPHER_TEXT_SIZE WC_ML_KEM_512_CIPHER_TEXT_SIZE +#endif +#endif /* WC_ML_KEM_MAX_K */ + +#define KYBER_N MLKEM_N + +/* Size of a polynomial vector based on dimensions. */ +#define KYBER_POLY_VEC_SZ(k) ((k) * KYBER_POLY_SIZE) +/* Size of a compressed polynomial based on bits per coefficient. */ +#define KYBER_POLY_COMPRESSED_SZ(b) ((b) * (KYBER_N / 8)) +/* Size of a compressed vector polynomial based on dimensions and bits per + * coefficient. */ +#define KYBER_POLY_VEC_COMPRESSED_SZ(k, b) ((k) * ((b) * (KYBER_N / 8))) + + +/* Kyber-512 parameters */ +/* Number of polynomials in a vector and vectors in a matrix. */ +#define KYBER512_K 2 + +/* Size of a polynomial vector. */ +#define KYBER512_POLY_VEC_SZ KYBER_POLY_VEC_SZ(KYBER512_K) +/* Size of a compressed polynomial based on bits per coefficient. */ +#define KYBER512_POLY_COMPRESSED_SZ KYBER_POLY_COMPRESSED_SZ(4) +/* Size of a compressed vector polynomial based on dimensions and bits per + * coefficient. */ +#define KYBER512_POLY_VEC_COMPRESSED_SZ \ + KYBER_POLY_VEC_COMPRESSED_SZ(KYBER512_K, 10) + +/* Public key size. */ +#define KYBER512_PUBLIC_KEY_SIZE \ + (KYBER512_POLY_VEC_SZ + KYBER_SYM_SZ) +/* Private key size. */ +#define KYBER512_PRIVATE_KEY_SIZE \ + (KYBER512_POLY_VEC_SZ + KYBER512_PUBLIC_KEY_SIZE + 2 * KYBER_SYM_SZ) +/* Cipher text size. */ +#define KYBER512_CIPHER_TEXT_SIZE \ + (KYBER512_POLY_VEC_COMPRESSED_SZ + KYBER512_POLY_COMPRESSED_SZ) + +/* Kyber-768 parameters */ +/* Number of polynomials in a vector and vectors in a matrix. */ +#define KYBER768_K 3 + +/* Size of a polynomial vector. */ +#define KYBER768_POLY_VEC_SZ KYBER_POLY_VEC_SZ(KYBER768_K) +/* Size of a compressed polynomial based on bits per coefficient. */ +#define KYBER768_POLY_COMPRESSED_SZ KYBER_POLY_COMPRESSED_SZ(4) +/* Size of a compressed vector polynomial based on dimensions and bits per + * coefficient. */ +#define KYBER768_POLY_VEC_COMPRESSED_SZ \ + KYBER_POLY_VEC_COMPRESSED_SZ(KYBER768_K, 10) + +/* Public key size. */ +#define KYBER768_PUBLIC_KEY_SIZE \ + (KYBER768_POLY_VEC_SZ + KYBER_SYM_SZ) +/* Private key size. */ +#define KYBER768_PRIVATE_KEY_SIZE \ + (KYBER768_POLY_VEC_SZ + KYBER768_PUBLIC_KEY_SIZE + 2 * KYBER_SYM_SZ) +/* Cipher text size. */ +#define KYBER768_CIPHER_TEXT_SIZE \ + (KYBER768_POLY_VEC_COMPRESSED_SZ + KYBER768_POLY_COMPRESSED_SZ) + +/* Kyber-1024 parameters */ +/* Number of polynomials in a vector and vectors in a matrix. */ +#define KYBER1024_K 4 + +/* Size of a polynomial vector. */ +#define KYBER1024_POLY_VEC_SZ KYBER_POLY_VEC_SZ(KYBER1024_K) +/* Size of a compressed polynomial based on bits per coefficient. */ +#define KYBER1024_POLY_COMPRESSED_SZ KYBER_POLY_COMPRESSED_SZ(5) +/* Size of a compressed vector polynomial based on dimensions and bits per + * coefficient. */ +#define KYBER1024_POLY_VEC_COMPRESSED_SZ \ + KYBER_POLY_VEC_COMPRESSED_SZ(KYBER1024_K, 11) + +/* Public key size. */ +#define KYBER1024_PUBLIC_KEY_SIZE \ + (KYBER1024_POLY_VEC_SZ + KYBER_SYM_SZ) +/* Private key size. */ +#define KYBER1024_PRIVATE_KEY_SIZE \ + (KYBER1024_POLY_VEC_SZ + KYBER1024_PUBLIC_KEY_SIZE + 2 * KYBER_SYM_SZ) +/* Cipher text size. */ +#define KYBER1024_CIPHER_TEXT_SIZE \ + (KYBER1024_POLY_VEC_COMPRESSED_SZ + KYBER1024_POLY_COMPRESSED_SZ) + + +/* Maximum dimensions and sizes of supported key types. */ +#ifdef WOLFSSL_KYBER1024 +#define KYBER_MAX_K KYBER1024_K +#define KYBER_MAX_PRIVATE_KEY_SIZE KYBER1024_PRIVATE_KEY_SIZE +#define KYBER_MAX_PUBLIC_KEY_SIZE KYBER1024_PUBLIC_KEY_SIZE +#define KYBER_MAX_CIPHER_TEXT_SIZE KYBER1024_CIPHER_TEXT_SIZE +#elif defined(WOLFSSL_KYBER768) +#define KYBER_MAX_K KYBER768_K +#define KYBER_MAX_PRIVATE_KEY_SIZE KYBER768_PRIVATE_KEY_SIZE +#define KYBER_MAX_PUBLIC_KEY_SIZE KYBER768_PUBLIC_KEY_SIZE +#define KYBER_MAX_CIPHER_TEXT_SIZE KYBER768_CIPHER_TEXT_SIZE +#elif defined(WOLFSSL_KYBER512) +#define KYBER_MAX_K KYBER512_K +#define KYBER_MAX_PRIVATE_KEY_SIZE KYBER512_PRIVATE_KEY_SIZE +#define KYBER_MAX_PUBLIC_KEY_SIZE KYBER512_PUBLIC_KEY_SIZE +#define KYBER_MAX_CIPHER_TEXT_SIZE KYBER512_CIPHER_TEXT_SIZE +#endif + +#define KYBER_SYM_SZ WC_ML_KEM_SYM_SZ +#define KYBER_SS_SZ WC_ML_KEM_SS_SZ +#define KYBER_MAKEKEY_RAND_SZ WC_ML_KEM_MAKEKEY_RAND_SZ +#define KYBER_ENC_RAND_SZ WC_ML_KEM_ENC_RAND_SZ +#define KYBER_POLY_SIZE WC_ML_KEM_POLY_SIZE + + +enum { + /* Types of Kyber keys. */ + WC_ML_KEM_512 = 0, + WC_ML_KEM_768 = 1, + WC_ML_KEM_1024 = 2, + + MLKEM_KYBER = 0x10, + KYBER512 = 0 | MLKEM_KYBER, + KYBER768 = 1 | MLKEM_KYBER, + KYBER1024 = 2 | MLKEM_KYBER, + + KYBER_LEVEL1 = KYBER512, + KYBER_LEVEL3 = KYBER768, + KYBER_LEVEL5 = KYBER1024, + + /* Symmetric data size. */ + WC_ML_KEM_SYM_SZ = 32, + /* Shared secret size. */ + WC_ML_KEM_SS_SZ = 32, + /* Size of random required for making a key. */ + WC_ML_KEM_MAKEKEY_RAND_SZ = 2 * WC_ML_KEM_SYM_SZ, + /* Size of random required for encapsulation. */ + WC_ML_KEM_ENC_RAND_SZ = WC_ML_KEM_SYM_SZ, + + /* Encoded polynomial size. */ + WC_ML_KEM_POLY_SIZE = 384, +}; + + +/* Different structures for different implementations. */ +typedef struct MlKemKey MlKemKey; + + +#ifdef __cplusplus + extern "C" { +#endif + +WOLFSSL_API int wc_MlKemKey_Init(MlKemKey* key, int type, void* heap, + int devId); +WOLFSSL_API int wc_MlKemKey_Free(MlKemKey* key); + +WOLFSSL_API int wc_MlKemKey_MakeKey(MlKemKey* key, WC_RNG* rng); +WOLFSSL_API int wc_MlKemKey_MakeKeyWithRandom(MlKemKey* key, + const unsigned char* rand, int len); + +WOLFSSL_API int wc_MlKemKey_CipherTextSize(MlKemKey* key, word32* len); +WOLFSSL_API int wc_MlKemKey_SharedSecretSize(MlKemKey* key, word32* len); + +WOLFSSL_API int wc_MlKemKey_Encapsulate(MlKemKey* key, unsigned char* ct, + unsigned char* ss, WC_RNG* rng); +WOLFSSL_API int wc_MlKemKey_EncapsulateWithRandom(MlKemKey* key, + unsigned char* ct, unsigned char* ss, const unsigned char* rand, int len); +WOLFSSL_API int wc_MlKemKey_Decapsulate(MlKemKey* key, unsigned char* ss, + const unsigned char* ct, word32 len); + +WOLFSSL_API int wc_MlKemKey_DecodePrivateKey(MlKemKey* key, + const unsigned char* in, word32 len); +WOLFSSL_API int wc_MlKemKey_DecodePublicKey(MlKemKey* key, + const unsigned char* in, word32 len); + +WOLFSSL_API int wc_MlKemKey_PrivateKeySize(MlKemKey* key, word32* len); +WOLFSSL_API int wc_MlKemKey_PublicKeySize(MlKemKey* key, word32* len); +WOLFSSL_API int wc_MlKemKey_EncodePrivateKey(MlKemKey* key, unsigned char* out, + word32 len); +WOLFSSL_API int wc_MlKemKey_EncodePublicKey(MlKemKey* key, unsigned char* out, + word32 len); + + +#define KyberKey MlKemKey + +#define wc_KyberKey_Init(type, key, heap, devId) \ + wc_MlKemKey_Init(key, type, heap, devId) +#define wc_KyberKey_Free wc_MlKemKey_Free +#define wc_KyberKey_MakeKey wc_MlKemKey_MakeKey +#define wc_KyberKey_MakeKeyWithRandom wc_MlKemKey_MakeKeyWithRandom +#define wc_KyberKey_CipherTextSize wc_MlKemKey_CipherTextSize +#define wc_KyberKey_SharedSecretSize wc_MlKemKey_SharedSecretSize +#define wc_KyberKey_Encapsulate wc_MlKemKey_Encapsulate +#define wc_KyberKey_EncapsulateWithRandom wc_MlKemKey_EncapsulateWithRandom +#define wc_KyberKey_Decapsulate wc_MlKemKey_Decapsulate +#define wc_KyberKey_DecodePrivateKey wc_MlKemKey_DecodePrivateKey +#define wc_KyberKey_DecodePublicKey wc_MlKemKey_DecodePublicKey +#define wc_KyberKey_PrivateKeySize wc_MlKemKey_PrivateKeySize +#define wc_KyberKey_PublicKeySize wc_MlKemKey_PublicKeySize +#define wc_KyberKey_EncodePrivateKey wc_MlKemKey_EncodePrivateKey +#define wc_KyberKey_EncodePublicKey wc_MlKemKey_EncodePublicKey + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_HAVE_MLKEM */ + +#endif /* WOLF_CRYPT_MLKEM_H */ + diff --git a/src/wolfssl/wolfcrypt/mpi_class.h b/src/wolfssl/wolfcrypt/mpi_class.h index 831fae3..4879a61 100644 --- a/src/wolfssl/wolfcrypt/mpi_class.h +++ b/src/wolfssl/wolfcrypt/mpi_class.h @@ -1,6 +1,6 @@ /* mpi_class.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/mpi_superclass.h b/src/wolfssl/wolfcrypt/mpi_superclass.h index f27f61a..69dee6b 100644 --- a/src/wolfssl/wolfcrypt/mpi_superclass.h +++ b/src/wolfssl/wolfcrypt/mpi_superclass.h @@ -1,6 +1,6 @@ /* mpi_superclass.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/pkcs11.h b/src/wolfssl/wolfcrypt/pkcs11.h index f252a00..36cfd9c 100644 --- a/src/wolfssl/wolfcrypt/pkcs11.h +++ b/src/wolfssl/wolfcrypt/pkcs11.h @@ -1,6 +1,6 @@ /* pkcs11.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/pkcs12.h b/src/wolfssl/wolfcrypt/pkcs12.h index d7bf967..6dc6e9d 100644 --- a/src/wolfssl/wolfcrypt/pkcs12.h +++ b/src/wolfssl/wolfcrypt/pkcs12.h @@ -1,6 +1,6 @@ /* pkcs12.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -55,6 +55,9 @@ WOLFSSL_API int wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der, int* derSz); WOLFSSL_API int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, byte** pkey, word32* pkeySz, byte** cert, word32* certSz, WC_DerCertList** ca); +WOLFSSL_API int wc_PKCS12_parse_ex(WC_PKCS12* pkcs12, const char* psw, + byte** pkey, word32* pkeySz, byte** cert, word32* certSz, + WC_DerCertList** ca, int keepKeyHeader); WOLFSSL_LOCAL int wc_PKCS12_verify_ex(WC_PKCS12* pkcs12, const byte* psw, word32 pswSz); WOLFSSL_API WC_PKCS12* wc_PKCS12_create(char* pass, word32 passSz, diff --git a/src/wolfssl/wolfcrypt/pkcs7.h b/src/wolfssl/wolfcrypt/pkcs7.h index bc34147..efce67c 100644 --- a/src/wolfssl/wolfcrypt/pkcs7.h +++ b/src/wolfssl/wolfcrypt/pkcs7.h @@ -1,6 +1,6 @@ /* pkcs7.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -243,6 +243,7 @@ typedef int (*CallbackRsaSignRawDigest)(wc_PKCS7* pkcs7, byte* digest, int devId, int hashOID); #endif + /* Public Structure Warning: * Existing members must not be changed to maintain backwards compatibility! */ @@ -258,6 +259,7 @@ struct wc_PKCS7 { #ifdef ASN_BER_TO_DER byte* der; /* DER encoded version of message */ word32 derSz; + byte indefDepth; CallbackGetContent getContentCb; CallbackStreamOut streamOutCb; void* streamCtx; /* passed to getcontentCb and streamOutCb */ @@ -372,6 +374,19 @@ struct wc_PKCS7 { byte* customSKID; word16 customSKIDSz; + +#if !defined(NO_DES3) || !defined(NO_AES) + union { + #ifndef NO_AES + Aes* aes; + #endif + #ifndef NO_DES3 + Des* des; + Des3* des3; + #endif + } decryptKey; +#endif + /* !! NEW DATA MEMBERS MUST BE ADDED AT END !! */ }; diff --git a/src/wolfssl/wolfcrypt/poly1305.h b/src/wolfssl/wolfcrypt/poly1305.h index d4db487..c6adb0e 100644 --- a/src/wolfssl/wolfcrypt/poly1305.h +++ b/src/wolfssl/wolfcrypt/poly1305.h @@ -1,6 +1,6 @@ /* poly1305.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -98,7 +98,18 @@ typedef struct Poly1305 { word64 leftover; unsigned char buffer[POLY1305_BLOCK_SIZE]; unsigned char finished; +#elif defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_ARMASM_THUMB2) && \ + !defined(WOLFSSL_ARMASM_NO_NEON) + /* NEON implementation for ARM32 */ + word32 r[4]; + word32 h[6]; + word32 pad[4]; + word32 leftover; + unsigned char buffer[4*POLY1305_BLOCK_SIZE]; + word32 r_21[10]; + word32 r_43[10]; #elif defined(WOLFSSL_ARMASM) + /* ARM32 (non-NEON) and Thumb2 */ word32 r[4]; word32 h[5]; word32 pad[4]; @@ -173,7 +184,8 @@ void poly1305_blocks_thumb2_16(Poly1305* ctx, const unsigned char* m, void poly1305_blocks_arm32(Poly1305* ctx, const unsigned char *m, size_t bytes); void poly1305_block_arm32(Poly1305* ctx, const unsigned char *m); -void poly1305_blocks_arm32_16(Poly1305* ctx, const unsigned char* m, word32 len, +void poly1305_arm32_blocks(Poly1305* ctx, const unsigned char* m, word32 len); +void poly1305_arm32_blocks_16(Poly1305* ctx, const unsigned char* m, word32 len, int notLast); #endif void poly1305_set_key(Poly1305* ctx, const byte* key); diff --git a/src/wolfssl/wolfcrypt/port/Espressif/esp-sdk-lib.h b/src/wolfssl/wolfcrypt/port/Espressif/esp-sdk-lib.h index de37936..4ae38a9 100644 --- a/src/wolfssl/wolfcrypt/port/Espressif/esp-sdk-lib.h +++ b/src/wolfssl/wolfcrypt/port/Espressif/esp-sdk-lib.h @@ -1,6 +1,6 @@ /* esp-sdk-lib.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h b/src/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h index d49ef3e..ac48d97 100644 --- a/src/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h +++ b/src/wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h @@ -1,6 +1,6 @@ /* esp32-crypt.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -216,8 +216,11 @@ enum { ** Turns on diagnostic messages for SHA mutex. Note that given verbosity, ** there may be TLS timing issues encountered. Use with caution. ** +** DEBUG_WOLFSSL_ESP32_HEAP +** Prints heap memory usage +** ** DEBUG_WOLFSSL_ESP32_UNFINISHED_HW -** This may be interesting in that HW may have been unnessearily locked +** This may be interesting in that HW may have been unnecessarily locked ** for hash that was never completed. (typically encountered at `free1` time) ** ** LOG_LOCAL_LEVEL @@ -234,11 +237,11 @@ enum { ** Shows a warning when mulm falls back for minimum number of bits. ** ** WOLFSSL_DEBUG_ESP_HW_MULTI_RSAMAX_BITS -** Shows a marning when multiplication math bits have exceeded hardware +** Shows a warning when multiplication math bits have exceeded hardware ** capabilities and will fall back to slower software. ** ** WOLFSSL_DEBUG_ESP_HW_MOD_RSAMAX_BITS -** Shows a marning when modular math bits have exceeded hardware capabilities +** Shows a warning when modular math bits have exceeded hardware capabilities ** and will fall back to slower software. ** ** NO_HW_MATH_TEST @@ -330,7 +333,7 @@ enum { #include #endif - #if ESP_IDF_VERSION_MAJOR >= 4 + #if ESP_IDF_VERSION_MAJOR == 4 || (ESP_IDF_VERSION_MAJOR == 5 && ESP_IDF_VERSION_MINOR < 4) #include #else #include @@ -375,9 +378,7 @@ enum { #include #endif - #if ESP_IDF_VERSION_MAJOR >= 4 - /* #include */ - #else + #if ESP_IDF_VERSION_MAJOR < 4 #include #endif @@ -411,9 +412,7 @@ enum { #include #endif - #if ESP_IDF_VERSION_MAJOR >= 4 - /* #include */ - #else + #if ESP_IDF_VERSION_MAJOR < 4 #include #endif @@ -447,9 +446,7 @@ enum { #include #endif - #if ESP_IDF_VERSION_MAJOR >= 4 - /* #include */ - #else + #if ESP_IDF_VERSION_MAJOR < 4 #include #endif @@ -719,24 +716,16 @@ extern "C" */ #ifndef NO_AES - #if ESP_IDF_VERSION_MAJOR >= 4 - #include "esp32/rom/aes.h" - #elif defined(CONFIG_IDF_TARGET_ESP8266) - /* no hardware includes for ESP8266*/ - #else - /* TODO: Confirm for older versions: */ - /* #include "rom/aes.h" */ - #endif + /* wolfSSL does not use Espressif rom/aes.h */ + struct Aes; /* see wolcrypt/aes.h */ - typedef enum tagES32_AES_PROCESS /* TODO what's this ? */ + typedef enum tagES32_AES_PROCESS { ESP32_AES_LOCKHW = 1, ESP32_AES_UPDATEKEY_ENCRYPT = 2, ESP32_AES_UPDATEKEY_DECRYPT = 3, ESP32_AES_UNLOCKHW = 4 } ESP32_AESPROCESS; - - struct Aes; /* see aes.h */ #if defined(WOLFSSL_HW_METRICS) WOLFSSL_LOCAL int esp_hw_show_aes_metrics(void); WOLFSSL_LOCAL int wc_esp32AesUnupportedLengthCountAdd(void); @@ -780,7 +769,14 @@ extern "C" #define SHA_CTX ETS_SHAContext - #if ESP_IDF_VERSION_MAJOR >= 4 + #if ESP_IDF_VERSION_MAJOR > 5 || (ESP_IDF_VERSION_MAJOR == 5 && ESP_IDF_VERSION_MINOR >= 4) + #include "rom/sha.h" + #if defined(CONFIG_IDF_TARGET_ESP32) + #define WC_ESP_SHA_TYPE enum SHA_TYPE + #else + #define WC_ESP_SHA_TYPE SHA_TYPE + #endif + #elif ESP_IDF_VERSION_MAJOR >= 4 #if defined(CONFIG_IDF_TARGET_ESP32) #include "esp32/rom/sha.h" #define WC_ESP_SHA_TYPE enum SHA_TYPE diff --git a/src/wolfssl/wolfcrypt/port/Espressif/esp_crt_bundle.h b/src/wolfssl/wolfcrypt/port/Espressif/esp_crt_bundle.h index 6f6e203..cc8f48f 100644 --- a/src/wolfssl/wolfcrypt/port/Espressif/esp_crt_bundle.h +++ b/src/wolfssl/wolfcrypt/port/Espressif/esp_crt_bundle.h @@ -1,6 +1,6 @@ /* esp_crt_bundle.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/port/atmel/atmel.h b/src/wolfssl/wolfcrypt/port/atmel/atmel.h index c2f9940..d5c9458 100644 --- a/src/wolfssl/wolfcrypt/port/atmel/atmel.h +++ b/src/wolfssl/wolfcrypt/port/atmel/atmel.h @@ -1,6 +1,6 @@ /* atmel.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/pwdbased.h b/src/wolfssl/wolfcrypt/pwdbased.h index 9535b0a..9013401 100644 --- a/src/wolfssl/wolfcrypt/pwdbased.h +++ b/src/wolfssl/wolfcrypt/pwdbased.h @@ -1,6 +1,6 @@ /* pwdbased.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/random.h b/src/wolfssl/wolfcrypt/random.h index cc4c797..3b4533e 100644 --- a/src/wolfssl/wolfcrypt/random.h +++ b/src/wolfssl/wolfcrypt/random.h @@ -1,6 +1,6 @@ /* random.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/rc2.h b/src/wolfssl/wolfcrypt/rc2.h index 22b2ad1..22eb581 100644 --- a/src/wolfssl/wolfcrypt/rc2.h +++ b/src/wolfssl/wolfcrypt/rc2.h @@ -1,6 +1,6 @@ /* rc2.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/ripemd.h b/src/wolfssl/wolfcrypt/ripemd.h index d1a0e6f..54ede0d 100644 --- a/src/wolfssl/wolfcrypt/ripemd.h +++ b/src/wolfssl/wolfcrypt/ripemd.h @@ -1,6 +1,6 @@ /* ripemd.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/rsa.h b/src/wolfssl/wolfcrypt/rsa.h index dc23839..a01e18d 100644 --- a/src/wolfssl/wolfcrypt/rsa.h +++ b/src/wolfssl/wolfcrypt/rsa.h @@ -1,6 +1,6 @@ /* rsa.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/sakke.h b/src/wolfssl/wolfcrypt/sakke.h index 0f7a75c..3ba7968 100644 --- a/src/wolfssl/wolfcrypt/sakke.h +++ b/src/wolfssl/wolfcrypt/sakke.h @@ -1,6 +1,6 @@ /* sakke.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/selftest.h b/src/wolfssl/wolfcrypt/selftest.h index 198013b..08b8884 100644 --- a/src/wolfssl/wolfcrypt/selftest.h +++ b/src/wolfssl/wolfcrypt/selftest.h @@ -1,6 +1,6 @@ /* selftest.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/settings.h b/src/wolfssl/wolfcrypt/settings.h index 50eb0cb..9f4cd66 100644 --- a/src/wolfssl/wolfcrypt/settings.h +++ b/src/wolfssl/wolfcrypt/settings.h @@ -1,6 +1,6 @@ /* settings.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -47,6 +47,12 @@ extern "C" { #endif +#if defined(TEST_LIBWOLFSSL_SOURCES_INCLUSION_SEQUENCE) && \ + defined(BUILDING_WOLFSSL) && !defined(LIBWOLFSSL_SOURCES_H) && \ + !defined(LIBWOLFSSL_SOURCES_ASM_H) + #error settings.h included before libwolfssl_sources[_asm].h. +#endif + /* WOLFSSL_USE_OPTIONS_H directs wolfSSL to include options.h on behalf of * application code, rather than the application including it directly. This is * not defined when compiling wolfSSL library objects, which are configured @@ -438,9 +444,9 @@ /* old FIPS has only AES_BLOCK_SIZE. */ #if !defined(NO_AES) && (defined(HAVE_SELFTEST) || \ - (defined(HAVE_FIPS) && FIPS_VERSION3_LT(7,0,0))) + (defined(HAVE_FIPS) && FIPS_VERSION3_LT(6,0,0))) #define WC_AES_BLOCK_SIZE AES_BLOCK_SIZE -#endif /* !NO_AES && (HAVE_SELFTEST || FIPS_VERSION3_LT(7,0,0)) */ +#endif /* !NO_AES && (HAVE_SELFTEST || FIPS_VERSION3_LT(6,0,0)) */ #ifdef WOLFSSL_HARDEN_TLS #if WOLFSSL_HARDEN_TLS != 112 && WOLFSSL_HARDEN_TLS != 128 @@ -642,7 +648,7 @@ #define WOLFSSL_DEBUG_ESP_HW_MOD_RSAMAX_BITS #endif - #if defined(CONFIG_TLS_STACK_WOLFSSL) && (CONFIG_TLS_STACK_WOLFSSL) + #if defined(CONFIG_TLS_STACK_WOLFSSL) /* When using ESP-TLS, some old algorithms such as SHA1 are no longer * enabled in wolfSSL, except for the OpenSSL compatibility. So enable * that here: */ @@ -841,17 +847,19 @@ #endif /* ESP_ENABLE_WOLFSSH */ - /* Experimental Kyber. */ + /* ML-KEM. */ #ifdef CONFIG_ESP_WOLFSSL_ENABLE_KYBER + #define CONFIG_ESP_WOLFSSL_ENABLE_MLKEM + #endif + #ifdef CONFIG_ESP_WOLFSSL_ENABLE_MLKEM /* Kyber typically needs a minimum 10K stack */ - #define WOLFSSL_EXPERIMENTAL_SETTINGS - #define WOLFSSL_HAVE_KYBER - #define WOLFSSL_WC_KYBER + #define WOLFSSL_HAVE_MLKEM + #define WOLFSSL_WC_MLKEM #define WOLFSSL_SHA3 #if defined(CONFIG_IDF_TARGET_ESP8266) /* With limited RAM, we'll disable some of the Kyber sizes: */ - #define WOLFSSL_NO_KYBER1024 - #define WOLFSSL_NO_KYBER768 + #define WOLFSSL_NO_ML_KEM_1024 + #define WOLFSSL_NO_ML_KEM_768 #define NO_SESSION_CACHE #endif #endif @@ -1268,7 +1276,7 @@ #error "https://www.wolfssl.com/docs/porting-guide/" #endif #endif - #define WOLFSSL_USER_IO + #define HAVE_ECC #define NO_DH #define NO_SESSION_CACHE @@ -2090,13 +2098,14 @@ extern void uITRON4_free(void *p) ; #endif /* WOLFSSL_MAXQ1065 || WOLFSSL_MAXQ108X */ -#if defined(WOLFSSL_STM32F2) || defined(WOLFSSL_STM32F4) || \ - defined(WOLFSSL_STM32F7) || defined(WOLFSSL_STM32F1) || \ - defined(WOLFSSL_STM32L4) || defined(WOLFSSL_STM32L5) || \ - defined(WOLFSSL_STM32WB) || defined(WOLFSSL_STM32H7) || \ - defined(WOLFSSL_STM32G0) || defined(WOLFSSL_STM32U5) || \ - defined(WOLFSSL_STM32H5) || defined(WOLFSSL_STM32WL) || \ - defined(WOLFSSL_STM32G4) || defined(WOLFSSL_STM32MP13) +#if defined(WOLFSSL_STM32F2) || defined(WOLFSSL_STM32F4) || \ + defined(WOLFSSL_STM32F7) || defined(WOLFSSL_STM32F1) || \ + defined(WOLFSSL_STM32L4) || defined(WOLFSSL_STM32L5) || \ + defined(WOLFSSL_STM32WB) || defined(WOLFSSL_STM32H7) || \ + defined(WOLFSSL_STM32G0) || defined(WOLFSSL_STM32U5) || \ + defined(WOLFSSL_STM32H5) || defined(WOLFSSL_STM32WL) || \ + defined(WOLFSSL_STM32G4) || defined(WOLFSSL_STM32MP13) || \ + defined(WOLFSSL_STM32H7S) || defined(WOLFSSL_STM32WBA) #define SIZEOF_LONG_LONG 8 #ifndef CHAR_BIT @@ -2117,7 +2126,7 @@ extern void uITRON4_free(void *p) ; #if defined(WOLFSSL_STM32L4) || defined(WOLFSSL_STM32L5) || \ defined(WOLFSSL_STM32WB) || defined(WOLFSSL_STM32U5) || \ - defined(WOLFSSL_STM32WL) + defined(WOLFSSL_STM32WL) || defined(WOLFSSL_STM32WBA) #define NO_AES_192 /* hardware does not support 192-bit */ #endif #endif @@ -2144,6 +2153,8 @@ extern void uITRON4_free(void *p) ; #include "stm32f7xx_hal.h" #elif defined(WOLFSSL_STM32F1) #include "stm32f1xx_hal.h" + #elif defined(WOLFSSL_STM32H7S) + #include "stm32h7rsxx_hal.h" #elif defined(WOLFSSL_STM32H7) #include "stm32h7xx_hal.h" #elif defined(WOLFSSL_STM32WB) @@ -2164,6 +2175,8 @@ extern void uITRON4_free(void *p) ; #include "stm32mp13xx_hal.h" #include "stm32mp13xx_hal_conf.h" #endif + #elif defined(WOLFSSL_STM32WBA) + #include "stm32wbaxx_hal.h" #endif #if defined(WOLFSSL_CUBEMX_USE_LL) && defined(WOLFSSL_STM32L4) #include "stm32l4xx_ll_rng.h" @@ -2562,7 +2575,7 @@ extern void uITRON4_free(void *p) ; #if !defined(CONFIG_NET_SOCKETS_POSIX_NAMES) && !defined(CONFIG_POSIX_API) #define CONFIG_NET_SOCKETS_POSIX_NAMES #endif -#endif +#endif /* WOLFSSL_ZEPHYR */ #ifdef WOLFSSL_IMX6 #ifndef SIZEOF_LONG_LONG @@ -2840,6 +2853,10 @@ extern void uITRON4_free(void *p) ; /* default is SP Math. */ #define WOLFSSL_SP_MATH_ALL #endif +#elif defined(WOLFCRYPT_FIPS_RAND) + #ifndef NO_BIG_INT + #define NO_BIG_INT + #endif #else /* FIPS 140-2 or older */ /* Default to fast math (tfm.c), but allow heap math (integer.c) */ @@ -3153,6 +3170,11 @@ extern void uITRON4_free(void *p) ; #define WOLFSSL_AES_DIRECT #endif #endif + #ifdef WOLFSSL_AES_CTS + #if defined(NO_AES_CBC) || !defined(HAVE_AES_CBC) + #error "AES CTS requires AES CBC" + #endif + #endif #endif #if (defined(WOLFSSL_TLS13) && defined(WOLFSSL_NO_TLS12)) || \ @@ -3596,17 +3618,33 @@ extern void uITRON4_free(void *p) ; #define WOLFSSL_OLD_PRIME_CHECK #endif #ifndef WOLFSSL_TEST_SUBROUTINE - #define WOLFSSL_TEST_SUBROUTINE static + #ifdef LINUXKM_LKCAPI_REGISTER + #define WOLFSSL_TEST_SUBROUTINE + #else + #define WOLFSSL_TEST_SUBROUTINE static + #endif + #endif + #ifdef LINUXKM_LKCAPI_REGISTER + #define WC_TEST_EXPORT_SUBTESTS #endif #undef HAVE_PTHREAD + /* linuxkm uses linux/string.h, included by linuxkm_wc_port.h. */ #undef HAVE_STRINGS_H + /* linuxkm uses linux/limits.h, included by linuxkm_wc_port.h. */ + #undef HAVE_LIMITS_H #undef HAVE_ERRNO_H #undef HAVE_THREAD_LS #undef HAVE_ATEXIT #undef WOLFSSL_HAVE_MIN #undef WOLFSSL_HAVE_MAX - #define SIZEOF_LONG 8 - #define SIZEOF_LONG_LONG 8 + #undef WOLFSSL_HAVE_ASSERT_H + #define WOLFSSL_NO_ASSERT_H + #ifndef SIZEOF_LONG + #define SIZEOF_LONG 8 + #endif + #ifndef SIZEOF_LONG_LONG + #define SIZEOF_LONG_LONG 8 + #endif #define CHAR_BIT 8 #ifndef WOLFSSL_SP_DIV_64 #define WOLFSSL_SP_DIV_64 @@ -3617,6 +3655,40 @@ extern void uITRON4_free(void *p) ; #ifdef __PIE__ #define WC_NO_INTERNAL_FUNCTION_POINTERS #endif + + #ifndef NO_OLD_WC_NAMES + #define NO_OLD_WC_NAMES + #endif + #ifndef NO_OLD_SHA_NAMES + #define NO_OLD_SHA_NAMES + #endif + #ifndef NO_OLD_MD5_NAME + #define NO_OLD_MD5_NAME + #endif + #ifndef OPENSSL_COEXIST + #define OPENSSL_COEXIST + #endif + #ifndef NO_OLD_SSL_NAMES + #define NO_OLD_SSL_NAMES + #endif + #undef WOLFSSL_MIN_AUTH_TAG_SZ + #define WOLFSSL_MIN_AUTH_TAG_SZ 4 + + #if defined(LINUXKM_LKCAPI_REGISTER) && !defined(WOLFSSL_ASN_INT_LEAD_0_ANY) + /* kernel 5.10 crypto manager tests key(s) that fail unless leading + * bytes are tolerated in GetASN_Integer(). + */ + #define WOLFSSL_ASN_INT_LEAD_0_ANY + #endif + + #ifdef CONFIG_KASAN + #ifndef WC_SANITIZE_DISABLE + #define WC_SANITIZE_DISABLE() kasan_disable_current() + #endif + #ifndef WC_SANITIZE_ENABLE + #define WC_SANITIZE_ENABLE() kasan_enable_current() + #endif + #endif #endif @@ -4074,7 +4146,7 @@ extern void uITRON4_free(void *p) ; #endif #endif -#ifdef WOLFSSL_HAVE_KYBER +#ifdef WOLFSSL_HAVE_MLKEM #define HAVE_PQC #endif @@ -4089,23 +4161,27 @@ extern void uITRON4_free(void *p) ; #ifndef WOLFSSL_NO_SPHINCS #define HAVE_SPHINCS #endif -#ifndef WOLFSSL_HAVE_KYBER - #define WOLFSSL_HAVE_KYBER +#ifndef WOLFSSL_HAVE_MLKEM + #define WOLFSSL_HAVE_MLKEM #define WOLFSSL_KYBER512 #define WOLFSSL_KYBER768 #define WOLFSSL_KYBER1024 + #define WOLFSSL_WC_ML_KEM_512 + #define WOLFSSL_WC_ML_KEM_768 + #define WOLFSSL_WC_ML_KEM_1024 #endif #endif #if (defined(HAVE_LIBOQS) || \ defined(HAVE_LIBXMSS) || \ defined(HAVE_LIBLMS) || \ - defined(WOLFSSL_DUAL_ALG_CERTS)) && \ + defined(WOLFSSL_DUAL_ALG_CERTS) || \ + defined(HAVE_ASCON)) && \ !defined(WOLFSSL_EXPERIMENTAL_SETTINGS) #error Experimental settings without WOLFSSL_EXPERIMENTAL_SETTINGS #endif -#if defined(HAVE_PQC) && !defined(HAVE_LIBOQS) && !defined(WOLFSSL_HAVE_KYBER) +#if defined(HAVE_PQC) && !defined(HAVE_LIBOQS) && !defined(WOLFSSL_HAVE_MLKEM) #error Please do not define HAVE_PQC yourself. #endif @@ -4361,6 +4437,11 @@ extern void uITRON4_free(void *p) ; #endif #endif /* HAVE_ENTROPY_MEMUSE */ +#if defined(NO_WOLFSSL_CLIENT) && defined(NO_WOLFSSL_SERVER) && \ + !defined(WOLFCRYPT_ONLY) && !defined(NO_TLS) +#error "If TLS is enabled please make sure either client or server is enabled." +#endif + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/src/wolfssl/wolfcrypt/sha.h b/src/wolfssl/wolfcrypt/sha.h index 063784e..54b0833 100644 --- a/src/wolfssl/wolfcrypt/sha.h +++ b/src/wolfssl/wolfcrypt/sha.h @@ -1,6 +1,6 @@ /* sha.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/sha256.h b/src/wolfssl/wolfcrypt/sha256.h index b5534d4..7a064a0 100644 --- a/src/wolfssl/wolfcrypt/sha256.h +++ b/src/wolfssl/wolfcrypt/sha256.h @@ -1,6 +1,6 @@ /* sha256.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -264,10 +264,14 @@ struct wc_Sha256 { WOLFSSL_API int wc_InitSha256(wc_Sha256* sha); WOLFSSL_API int wc_InitSha256_ex(wc_Sha256* sha, void* heap, int devId); WOLFSSL_API int wc_Sha256Update(wc_Sha256* sha, const byte* data, word32 len); + +#if !defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_AFALG_HASH) WOLFSSL_API int wc_Sha256FinalRaw(wc_Sha256* sha256, byte* hash); +#endif WOLFSSL_API int wc_Sha256Final(wc_Sha256* sha256, byte* hash); WOLFSSL_API void wc_Sha256Free(wc_Sha256* sha256); -#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL) +#if (defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) && \ + !defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_AFALG_HASH) WOLFSSL_API int wc_Sha256Transform(wc_Sha256* sha, const unsigned char* data); #endif #if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_FULL_HASH) diff --git a/src/wolfssl/wolfcrypt/sha3.h b/src/wolfssl/wolfcrypt/sha3.h index 2491acd..724719a 100644 --- a/src/wolfssl/wolfcrypt/sha3.h +++ b/src/wolfssl/wolfcrypt/sha3.h @@ -1,6 +1,6 @@ /* sha3.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -225,6 +225,7 @@ WOLFSSL_LOCAL void sha3_block_n_bmi2(word64* s, const byte* data, word32 n, word64 c); WOLFSSL_LOCAL void sha3_block_bmi2(word64* s); WOLFSSL_LOCAL void sha3_block_avx2(word64* s); +WOLFSSL_LOCAL void sha3_blocksx4_avx2(word64* s); WOLFSSL_LOCAL void BlockSha3(word64 *s); #elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3 diff --git a/src/wolfssl/wolfcrypt/sha512.h b/src/wolfssl/wolfcrypt/sha512.h index 5033a2c..593177e 100644 --- a/src/wolfssl/wolfcrypt/sha512.h +++ b/src/wolfssl/wolfcrypt/sha512.h @@ -1,6 +1,6 @@ /* sha512.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -224,7 +224,7 @@ struct wc_Sha512 { #endif /* HAVE_FIPS */ -#ifdef WOLFSSL_SHA512 +#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384) #ifdef WOLFSSL_ARMASM #ifdef __aarch64__ diff --git a/src/wolfssl/wolfcrypt/signature.h b/src/wolfssl/wolfcrypt/signature.h index 51c07af..7d9a1d4 100644 --- a/src/wolfssl/wolfcrypt/signature.h +++ b/src/wolfssl/wolfcrypt/signature.h @@ -1,6 +1,6 @@ /* signature.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/siphash.h b/src/wolfssl/wolfcrypt/siphash.h index 6b75a46..26cd821 100644 --- a/src/wolfssl/wolfcrypt/siphash.h +++ b/src/wolfssl/wolfcrypt/siphash.h @@ -1,6 +1,6 @@ /* siphash.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/sm2.h b/src/wolfssl/wolfcrypt/sm2.h index ae9885e..fb90aaa 100644 --- a/src/wolfssl/wolfcrypt/sm2.h +++ b/src/wolfssl/wolfcrypt/sm2.h @@ -1,6 +1,6 @@ /* sm2.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/sm3.h b/src/wolfssl/wolfcrypt/sm3.h index b24fcf4..e7e8b0e 100644 --- a/src/wolfssl/wolfcrypt/sm3.h +++ b/src/wolfssl/wolfcrypt/sm3.h @@ -1,6 +1,6 @@ /* sm3.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/sm4.h b/src/wolfssl/wolfcrypt/sm4.h index 84a8166..3cebb79 100644 --- a/src/wolfssl/wolfcrypt/sm4.h +++ b/src/wolfssl/wolfcrypt/sm4.h @@ -1,6 +1,6 @@ /* sm4.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/sp.h b/src/wolfssl/wolfcrypt/sp.h index 3ede752..9e7a9c9 100644 --- a/src/wolfssl/wolfcrypt/sp.h +++ b/src/wolfssl/wolfcrypt/sp.h @@ -1,6 +1,6 @@ /* sp.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/sp_int.h b/src/wolfssl/wolfcrypt/sp_int.h index dc707d2..7385e68 100644 --- a/src/wolfssl/wolfcrypt/sp_int.h +++ b/src/wolfssl/wolfcrypt/sp_int.h @@ -1,6 +1,6 @@ /* sp_int.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -210,8 +210,10 @@ extern "C" { #elif defined(WOLFSSL_SP_X86_64_ASM) || defined(WOLFSSL_SP_X86_64) #if SP_ULONG_BITS == 64 || SP_ULLONG_BITS == 64 #define SP_WORD_SIZE 64 - #define HAVE_INTEL_AVX1 - #ifndef NO_AVX2_SUPPORT + #ifndef HAVE_INTEL_AVX1 + #define HAVE_INTEL_AVX1 + #endif + #if !defined(NO_AVX2_SUPPORT) && !defined(HAVE_INTEL_AVX2) #define HAVE_INTEL_AVX2 #endif #elif SP_ULONG_BITS == 32 @@ -262,7 +264,7 @@ extern "C" { #define SP_WORD_SIZEOF (SP_WORD_SIZE / 8) /* Define the types used. */ -#ifdef HAVE___UINT128_T +#if defined(HAVE___UINT128_T) && !defined(NO_INT128) #ifdef __SIZEOF_INT128__ typedef __uint128_t sp_uint128; typedef __int128_t sp_int128; @@ -385,11 +387,11 @@ extern "C" { /* Non-blocking ECC operation context. */ typedef struct sp_ecc_ctx { #ifdef WOLFSSL_SP_521 - byte data[66*80]; /* stack data */ + XALIGNED(4) byte data[66*80]; /* stack data */ #elif defined(WOLFSSL_SP_384) - byte data[48*80]; /* stack data */ + XALIGNED(4) byte data[48*80]; /* stack data */ #else - byte data[32*80]; /* stack data */ + XALIGNED(4) byte data[32*80]; /* stack data */ #endif } sp_ecc_ctx_t; #endif @@ -702,7 +704,10 @@ typedef struct sp_ecc_ctx { do { \ int ii; \ if ((a)->used > 0) { \ - for (ii = (int)(a)->used - 1; ii >= 0 && (a)->dp[ii] == 0; ii--) { \ + for (ii = (int)(a)->used - 1; ii >= 0; ii--) { \ + if ((a)->dp[ii] != 0) { \ + break; \ + } \ } \ (a)->used = (wc_mp_size_t)(ii + 1); \ } \ diff --git a/src/wolfssl/wolfcrypt/sphincs.h b/src/wolfssl/wolfcrypt/sphincs.h index 6dd3a8e..f1487dd 100644 --- a/src/wolfssl/wolfcrypt/sphincs.h +++ b/src/wolfssl/wolfcrypt/sphincs.h @@ -1,6 +1,6 @@ /* sphincs.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/srp.h b/src/wolfssl/wolfcrypt/srp.h index d1307c7..7607765 100644 --- a/src/wolfssl/wolfcrypt/srp.h +++ b/src/wolfssl/wolfcrypt/srp.h @@ -1,6 +1,6 @@ /* srp.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/tfm.h b/src/wolfssl/wolfcrypt/tfm.h index 80b7f0f..718077c 100644 --- a/src/wolfssl/wolfcrypt/tfm.h +++ b/src/wolfssl/wolfcrypt/tfm.h @@ -1,6 +1,6 @@ /* tfm.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/types.h b/src/wolfssl/wolfcrypt/types.h index f8042cf..3ff9ec5 100644 --- a/src/wolfssl/wolfcrypt/types.h +++ b/src/wolfssl/wolfcrypt/types.h @@ -1,6 +1,6 @@ /* types.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -150,9 +150,17 @@ decouple library dependencies with standard string, memory and so on. /* The C standards don't define empty aggregates, but gcc and clang do. * We need to accommodate them for one of the same reasons C++ does -- * conditionally empty aggregates, e.g. in hash.h. + * + * Nonetheless, in C++, empty aggregates wind up with size 1. If we use + * the [0] construct and the header is compiled by clang++, it warns + * "struct has size 0 in C, size 1 in C++ [-Wextern-c-compat]", despite + * the extern "C" wrapper. We sidestep this warning by recognizing + * here that C++ doesn't support truly empty aggregates. LLVM, for its part, + * deprecates compilation of C code as C++ using clang++. */ #if !defined(WOLF_C89) && defined(__GNUC__) && \ !defined(__STRICT_ANSI__) && \ + !defined(__cplusplus) && \ defined(HAVE_ANONYMOUS_INLINE_AGGREGATES) #define HAVE_EMPTY_AGGREGATES 1 #endif @@ -212,10 +220,10 @@ decouple library dependencies with standard string, memory and so on. /* try to set SIZEOF_LONG or SIZEOF_LONG_LONG if user didn't */ #if defined(_WIN32) || defined(HAVE_LIMITS_H) + #include /* make sure both SIZEOF_LONG_LONG and SIZEOF_LONG are set, * otherwise causes issues with CTC_SETTINGS */ #if !defined(SIZEOF_LONG_LONG) || !defined(SIZEOF_LONG) - #include #if !defined(SIZEOF_LONG) && defined(ULONG_MAX) && \ (ULONG_MAX == 0xffffffffUL) #define SIZEOF_LONG 4 @@ -244,7 +252,8 @@ decouple library dependencies with standard string, memory and so on. #endif #endif - #if (defined(_MSC_VER) && !defined(WOLFSSL_NOT_WINDOWS_API)) || \ + #if (defined(_MSC_VER) && (_MSC_VER == 1200)) || /* MSVC6 */ \ + (defined(_MSC_VER) && !defined(WOLFSSL_NOT_WINDOWS_API)) || \ defined(__BCPLUSPLUS__) || \ (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) /* windows types */ @@ -319,12 +328,15 @@ decouple library dependencies with standard string, memory and so on. #if defined(NO_64BIT) typedef word32 wolfssl_word; + #define WOLFSSL_WORD_SIZE_LOG2 2 #undef WORD64_AVAILABLE #else #ifdef WC_64BIT_CPU typedef word64 wolfssl_word; + #define WOLFSSL_WORD_SIZE_LOG2 3 #else typedef word32 wolfssl_word; + #define WOLFSSL_WORD_SIZE_LOG2 2 #ifdef WORD64_AVAILABLE #define WOLFCRYPT_SLOW_WORD64 #endif @@ -336,12 +348,14 @@ decouple library dependencies with standard string, memory and so on. #undef WORD64_AVAILABLE #endif typedef word16 wolfssl_word; + #define WOLFSSL_WORD_SIZE_LOG2 1 #define MP_16BIT /* for mp_int, mp_word needs to be twice as big as \ * mp_digit, no 64 bit type so make mp_digit 16 bit */ #else #undef WORD64_AVAILABLE typedef word32 wolfssl_word; + #define WOLFSSL_WORD_SIZE_LOG2 2 #define MP_16BIT /* for mp_int, mp_word needs to be twice as big as \ * mp_digit, no 64 bit type so make mp_digit 16 bit */ #endif @@ -406,7 +420,7 @@ typedef struct w64wrapper { /* set up thread local storage if available */ #ifdef HAVE_THREAD_LS - #if defined(_MSC_VER) + #if defined(_MSC_VER) || defined(__WATCOMC__) #define THREAD_LS_T __declspec(thread) /* Thread local storage only in FreeRTOS v8.2.1 and higher */ #elif defined(FREERTOS) || defined(FREERTOS_TCP) || \ @@ -754,11 +768,13 @@ typedef struct w64wrapper { #endif #ifndef XSTRCASECMP - #if defined(MICROCHIP_PIC32) && (__XC32_VERSION >= 1000) && (__XC32_VERSION < 4000) + #if (defined(MICROCHIP_MPLAB_HARMONY) || defined(MICROCHIP_PIC32)) && \ + (__XC32_VERSION >= 1000) && (__XC32_VERSION < 4000) /* XC32 supports str[n]casecmp in version >= 1.0 through 4.0. */ #define XSTRCASECMP(s1,s2) strcasecmp((s1),(s2)) - #elif defined(MICROCHIP_PIC32) || defined(WOLFSSL_TIRTOS) || \ - defined(WOLFSSL_ZEPHYR) || defined(MICROCHIP_PIC24) + #elif defined(MICROCHIP_MPLAB_HARMONY) || defined(MICROCHIP_PIC32) || \ + defined(WOLFSSL_TIRTOS) || defined(WOLFSSL_ZEPHYR) || \ + defined(MICROCHIP_PIC24) /* XC32 version < 1.0 does not support strcasecmp. */ #define USE_WOLF_STRCASECMP #elif defined(USE_WINDOWS_API) || defined(FREERTOS_TCP_WINSIM) @@ -786,11 +802,13 @@ typedef struct w64wrapper { #endif /* !XSTRCASECMP */ #ifndef XSTRNCASECMP - #if defined(MICROCHIP_PIC32) && (__XC32_VERSION >= 1000) + #if (defined(MICROCHIP_MPLAB_HARMONY) || defined(MICROCHIP_PIC32)) && \ + (__XC32_VERSION >= 1000) /* XC32 supports str[n]casecmp in version >= 1.0. */ #define XSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n)) - #elif defined(MICROCHIP_PIC32) || defined(WOLFSSL_TIRTOS) || \ - defined(WOLFSSL_ZEPHYR) || defined(MICROCHIP_PIC24) + #elif defined(MICROCHIP_MPLAB_HARMONY) || defined(MICROCHIP_PIC32) || \ + defined(WOLFSSL_TIRTOS) || defined(WOLFSSL_ZEPHYR) || \ + defined(MICROCHIP_PIC24) /* XC32 version < 1.0 does not support strncasecmp. */ #define USE_WOLF_STRNCASECMP #elif defined(USE_WINDOWS_API) || defined(FREERTOS_TCP_WINSIM) @@ -914,6 +932,13 @@ typedef struct w64wrapper { /* use only Thread Safe version of strtok */ #if defined(USE_WOLF_STRTOK) #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) + #elif defined(__WATCOMC__) + #if __WATCOMC__ < 1300 + #define USE_WOLF_STRTOK + #define XSTRTOK(s1,d,ptr) wc_strtok((s1),(d),(ptr)) + #else + #define XSTRTOK(s1,d,ptr) strtok_r((s1),(d),(ptr)) + #endif #elif defined(USE_WINDOWS_API) || defined(INTIME_RTOS) #define XSTRTOK(s1,d,ptr) strtok_s((s1),(d),(ptr)) #else @@ -985,7 +1010,7 @@ typedef struct w64wrapper { #endif #if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) #define XISALNUM(c) isalnum((c)) - #ifdef NO_STDLIB_ISASCII + #if !defined(HAVE_ISASCII) || defined(NO_STDLIB_ISASCII) #define XISASCII(c) (((c) >= 0 && (c) <= 127) ? 1 : 0) #else #define XISASCII(c) isascii((c)) @@ -996,11 +1021,14 @@ typedef struct w64wrapper { #define XTOLOWER(c) tolower((c)) #endif - #ifndef OFFSETOF + #ifndef WC_OFFSETOF #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 4)) - #define OFFSETOF(type, field) __builtin_offsetof(type, field) + #define WC_OFFSETOF(type, field) __builtin_offsetof(type, field) + #elif defined(__WATCOMC__) + #include + #define WC_OFFSETOF offsetof #else - #define OFFSETOF(type, field) ((size_t)&(((type *)0)->field)) + #define WC_OFFSETOF(type, field) ((size_t)&(((type *)0)->field)) #endif #endif @@ -1110,6 +1138,7 @@ typedef struct w64wrapper { DYNAMIC_TYPE_BIO = 102, DYNAMIC_TYPE_X509_ACERT = 103, DYNAMIC_TYPE_OS_BUF = 104, + DYNAMIC_TYPE_ASCON = 105, DYNAMIC_TYPE_SNIFFER_SERVER = 1000, DYNAMIC_TYPE_SNIFFER_SESSION = 1001, DYNAMIC_TYPE_SNIFFER_PB = 1002, @@ -1228,6 +1257,16 @@ typedef struct w64wrapper { #endif /* HAVE_SELFTEST */ }; + enum wc_HashFlags { + WC_HASH_FLAG_NONE = 0x00000000, + WC_HASH_FLAG_WILLCOPY = 0x00000001, /* flag to indicate hash will be copied */ + WC_HASH_FLAG_ISCOPY = 0x00000002, /* hash is copy */ + #ifdef WOLFSSL_SHA3 + WC_HASH_SHA3_KECCAK256 =0x00010000, /* Older KECCAK256 */ + #endif + WOLF_ENUM_DUMMY_LAST_ELEMENT(WC_HASH) + }; + /* cipher types */ enum wc_CipherType { WC_CIPHER_NONE = 0, @@ -1267,7 +1306,7 @@ typedef struct w64wrapper { WC_PK_TYPE_CURVE25519_KEYGEN = 16, WC_PK_TYPE_RSA_GET_SIZE = 17, #define _WC_PK_TYPE_MAX WC_PK_TYPE_RSA_GET_SIZE - #if defined(WOLFSSL_HAVE_KYBER) + #if defined(WOLFSSL_HAVE_MLKEM) WC_PK_TYPE_PQC_KEM_KEYGEN = 18, WC_PK_TYPE_PQC_KEM_ENCAPS = 19, WC_PK_TYPE_PQC_KEM_DECAPS = 20, @@ -1288,12 +1327,12 @@ typedef struct w64wrapper { WC_PK_TYPE_MAX = _WC_PK_TYPE_MAX }; -#if defined(WOLFSSL_HAVE_KYBER) +#if defined(WOLFSSL_HAVE_MLKEM) /* Post quantum KEM algorithms */ enum wc_PqcKemType { WC_PQC_KEM_TYPE_NONE = 0, #define _WC_PQC_KEM_TYPE_MAX WC_PQC_KEM_TYPE_NONE - #if defined(WOLFSSL_HAVE_KYBER) + #if defined(WOLFSSL_HAVE_MLKEM) WC_PQC_KEM_TYPE_KYBER = 1, #undef _WC_PQC_KEM_TYPE_MAX #define _WC_PQC_KEM_TYPE_MAX WC_PQC_KEM_TYPE_KYBER @@ -1475,6 +1514,47 @@ typedef struct w64wrapper { * wolfSSL_JoinThread() and wolfSSL_Cond signaling if they want. * Otherwise, those functions are omitted. */ + #elif defined(__WATCOMC__) + #if __WATCOMC__ < 1300 + #define _WCCALLBACK + #endif + #if defined(__NT__) + typedef unsigned THREAD_RETURN; + typedef uintptr_t THREAD_TYPE; + typedef struct COND_TYPE { + wolfSSL_Mutex mutex; + HANDLE cond; + } COND_TYPE; + #define WOLFSSL_COND + #define INVALID_THREAD_VAL ((THREAD_TYPE)(INVALID_HANDLE_VALUE)) + #define WOLFSSL_THREAD __stdcall + #define WOLFSSL_THREAD_NO_JOIN _WCCALLBACK + #elif defined(__OS2__) + #define WOLFSSL_THREAD_VOID_RETURN + typedef void THREAD_RETURN; + typedef TID THREAD_TYPE; + typedef struct COND_TYPE { + wolfSSL_Mutex mutex; + LHANDLE cond; + } COND_TYPE; + #define WOLFSSL_COND + #define INVALID_THREAD_VAL ((THREAD_TYPE)(-1)) + #define WOLFSSL_THREAD _WCCALLBACK + #define WOLFSSL_THREAD_NO_JOIN _WCCALLBACK + #elif defined(__LINUX__) + #include + typedef struct COND_TYPE { + pthread_mutex_t mutex; + pthread_cond_t cond; + } COND_TYPE; + typedef void* THREAD_RETURN; + typedef pthread_t THREAD_TYPE; + #define WOLFSSL_COND + #define WOLFSSL_THREAD + #ifndef HAVE_SELFTEST + #define WOLFSSL_THREAD_NO_JOIN + #endif + #endif #elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) || \ defined(FREESCALE_MQX) typedef unsigned int THREAD_RETURN; @@ -1587,8 +1667,6 @@ typedef struct w64wrapper { * to check if the value is an invalid thread * WOLFSSL_THREAD - attribute that should be used to declare thread * callbacks - * WOLFSSL_THREAD_NO_JOIN - attribute that should be used to declare - * thread callbacks that don't require cleanup * WOLFSSL_COND - defined if this system supports signaling * COND_TYPE - type that should be passed into the signaling API * WOLFSSL_THREAD_VOID_RETURN - defined if the thread callback has a @@ -1596,8 +1674,16 @@ typedef struct w64wrapper { * WOLFSSL_RETURN_FROM_THREAD - define used to correctly return from a * thread callback * THREAD_CB - thread callback type for regular threading API - * THREAD_CB_NOJOIN - thread callback type for threading API that don't + * + * WOLFSSL_THREAD_NO_JOIN - attribute used to declare thread callbacks + * that do not require cleanup + * THREAD_CB_NOJOIN - thread callback type for thread APIs that do not * require cleanup + * THREAD_RETURN_NOJOIN - return type used to declare thread callbacks + * that do not require cleanup + * RETURN_FROM_THREAD_NOJOIN - define used to correctly return from + * a thread callback that do not require + * cleanup * * Other defines/types are specific for the threading implementation */ @@ -1620,8 +1706,17 @@ typedef struct w64wrapper { /* Create a thread that will be automatically cleaned up. We can't * return a handle/pointer to the new thread because there are no * guarantees for how long it will be valid. */ - typedef THREAD_RETURN (WOLFSSL_THREAD_NO_JOIN *THREAD_CB_NOJOIN) - (void* arg); + #if defined(WOLFSSL_PTHREADS) + #define THREAD_CB_NOJOIN THREAD_CB + #define THREAD_RETURN_NOJOIN THREAD_RETURN + #define RETURN_FROM_THREAD_NOJOIN(x) \ + WOLFSSL_RETURN_FROM_THREAD(x) + #else + #define THREAD_RETURN_NOJOIN void + typedef THREAD_RETURN_NOJOIN + (WOLFSSL_THREAD_NO_JOIN *THREAD_CB_NOJOIN)(void* arg); + #define RETURN_FROM_THREAD_NOJOIN(x) return + #endif WOLFSSL_API int wolfSSL_NewThreadNoJoin(THREAD_CB_NOJOIN cb, void* arg); #endif @@ -1712,21 +1807,25 @@ typedef struct w64wrapper { #define PRAGMA_DIAG_POP /* null expansion */ #endif - #define WC_CPP_CAT_(a, b) a ## b - #define WC_CPP_CAT(a, b) WC_CPP_CAT_(a, b) + #define WC_CPP_CAT4_(a, b, c, d) a ## b ## c ## d + #define WC_CPP_CAT4(a, b, c, d) WC_CPP_CAT4_(a, b, c, d) #if defined(WC_NO_STATIC_ASSERT) #define wc_static_assert(expr) struct wc_static_assert_dummy_struct #define wc_static_assert2(expr, msg) wc_static_assert(expr) #elif !defined(wc_static_assert) + #if defined(WOLFSSL_HAVE_ASSERT_H) && !defined(WOLFSSL_NO_ASSERT_H) + #include + #endif #if (defined(__cplusplus) && (__cplusplus >= 201703L)) || \ (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 202311L)) || \ - (defined(_MSVC_LANG) && (_MSVC_LANG >= 201103L)) + (defined(_MSVC_LANG) && (__cpp_static_assert >= 201411L)) /* native variadic static_assert() */ #define wc_static_assert static_assert #ifndef wc_static_assert2 #define wc_static_assert2 static_assert #endif - #elif defined(_MSC_VER) && (__STDC_VERSION__ >= 201112L) + #elif (defined(_MSC_VER) && (__STDC_VERSION__ >= 201112L)) || \ + (defined(_MSVC_LANG) && (__cpp_static_assert >= 200410L)) /* native 2-argument static_assert() */ #define wc_static_assert(expr) static_assert(expr, #expr) #ifndef wc_static_assert2 @@ -1746,11 +1845,16 @@ typedef struct w64wrapper { #define wc_static_assert2(expr, msg) _Static_assert(expr, msg) #endif #else - /* C89-compatible fallback */ - #define wc_static_assert(expr) \ - struct WC_CPP_CAT(wc_static_assert_dummy_struct_L, __LINE__) { \ - char t[(expr) ? 1 : -1]; \ - } + #ifdef __COUNTER__ + #define wc_static_assert(expr) \ + struct WC_CPP_CAT4(wc_static_assert_dummy_struct_L, \ + __LINE__, _, __COUNTER__) { \ + char t[(expr) ? 1 : -1]; \ + } + #else + #define wc_static_assert(expr) \ + struct wc_static_assert_dummy_struct + #endif #ifndef wc_static_assert2 #define wc_static_assert2(expr, msg) wc_static_assert(expr) #endif @@ -1783,6 +1887,13 @@ typedef struct w64wrapper { #define RESTORE_VECTOR_REGISTERS() WC_DO_NOTHING #endif + #ifndef WC_SANITIZE_DISABLE + #define WC_SANITIZE_DISABLE() WC_DO_NOTHING + #endif + #ifndef WC_SANITIZE_ENABLE + #define WC_SANITIZE_ENABLE() WC_DO_NOTHING + #endif + #if FIPS_VERSION_GE(5,1) #define WC_SPKRE_F(x,y) wolfCrypt_SetPrivateKeyReadEnable_fips((x),(y)) #define PRIVATE_KEY_LOCK() WC_SPKRE_F(0,WC_KEYTYPE_ALL) diff --git a/src/wolfssl/wolfcrypt/visibility.h b/src/wolfssl/wolfcrypt/visibility.h index 30a19e2..fc7e485 100644 --- a/src/wolfssl/wolfcrypt/visibility.h +++ b/src/wolfssl/wolfcrypt/visibility.h @@ -1,6 +1,6 @@ /* visibility.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -33,7 +33,7 @@ #if defined(BUILDING_WOLFSSL) #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) || \ - defined(_WIN32_WCE) + defined(_WIN32_WCE) || defined(__WATCOMC__) #if defined(WOLFSSL_DLL) #define WOLFSSL_API __declspec(dllexport) #else @@ -50,8 +50,21 @@ #define WOLFSSL_API #define WOLFSSL_LOCAL #endif /* HAVE_VISIBILITY */ -#else /* BUILDING_WOLFSSL */ - #if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) || \ + + #ifdef WOLFSSL_PRIVATE_TEST_VIS + #define WOLFSSL_TEST_VIS WOLFSSL_LOCAL + #else + #define WOLFSSL_TEST_VIS WOLFSSL_API + #endif +#else /* !BUILDING_WOLFSSL */ + #if defined(__WATCOMC__) + #if defined(WOLFSSL_DLL) && defined(__NT__) + #define WOLFSSL_API __declspec(dllimport) + #else + #define WOLFSSL_API + #endif + #define WOLFSSL_LOCAL + #elif defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) || \ defined(_WIN32_WCE) #if defined(WOLFSSL_DLL) #define WOLFSSL_API __declspec(dllimport) @@ -63,7 +76,17 @@ #define WOLFSSL_API #define WOLFSSL_LOCAL #endif -#endif /* BUILDING_WOLFSSL */ + + #if defined(WOLFSSL_VIS_FOR_TESTS) + #ifdef WOLFSSL_PRIVATE_TEST_VIS + #error WOLFSSL_VIS_FOR_TESTS is unavailable in WOLFSSL_PRIVATE_TEST_VIS builds. + #endif + #define WOLFSSL_TEST_VIS WOLFSSL_API + #else + #define WOLFSSL_TEST_VIS WOLFSSL_API WC_DEPRECATED("internal use only") + #endif + +#endif /* !BUILDING_WOLFSSL */ /* WOLFSSL_ABI is used for public API symbols that must not change * their signature. This tag is used for all APIs that are a diff --git a/src/wolfssl/wolfcrypt/wc_encrypt.h b/src/wolfssl/wolfcrypt/wc_encrypt.h index e3cf9ad..4dfc84c 100644 --- a/src/wolfssl/wolfcrypt/wc_encrypt.h +++ b/src/wolfssl/wolfcrypt/wc_encrypt.h @@ -1,6 +1,6 @@ /* wc_encrypt.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/wc_lms.h b/src/wolfssl/wolfcrypt/wc_lms.h index d7317ea..a4880a9 100644 --- a/src/wolfssl/wolfcrypt/wc_lms.h +++ b/src/wolfssl/wolfcrypt/wc_lms.h @@ -1,6 +1,6 @@ /* wc_lms.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -303,13 +303,13 @@ #endif /* Indicates using SHA-256 for hashing. */ -#define LMS_SHA256 0x00 +#define LMS_SHA256 0x0000 /* Indicates using SHA-256/192 for hashing. */ -#define LMS_SHA256_192 0x10 +#define LMS_SHA256_192 0x1000 /* Mask to get hashing algorithm from type. */ -#define LMS_HASH_MASK 0xf0 +#define LMS_HASH_MASK 0xf000 /* Mask to get height or Winternitz width from type. */ -#define LMS_H_W_MASK 0x0f +#define LMS_H_W_MASK 0x0fff /* LMS Parameters. */ /* SHA-256 hash, 32-bytes of hash used, tree height of 5. */ @@ -333,24 +333,24 @@ #define LMOTS_SHA256_N32_W8 0x04 /* SHA-256 hash, 32-bytes of hash used, tree height of 5. */ -#define LMS_SHA256_M24_H5 (0x05 | LMS_SHA256_192) +#define LMS_SHA256_M24_H5 (0x0a | LMS_SHA256_192) /* SHA-256 hash, 32-bytes of hash used, tree height of 10. */ -#define LMS_SHA256_M24_H10 (0x06 | LMS_SHA256_192) +#define LMS_SHA256_M24_H10 (0x0b | LMS_SHA256_192) /* SHA-256 hash, 32-bytes of hash used, tree height of 15. */ -#define LMS_SHA256_M24_H15 (0x07 | LMS_SHA256_192) +#define LMS_SHA256_M24_H15 (0x0c | LMS_SHA256_192) /* SHA-256 hash, 32-bytes of hash used, tree height of 20. */ -#define LMS_SHA256_M24_H20 (0x08 | LMS_SHA256_192) +#define LMS_SHA256_M24_H20 (0x0d | LMS_SHA256_192) /* SHA-256 hash, 32-bytes of hash used, tree height of 25. */ -#define LMS_SHA256_M24_H25 (0x09 | LMS_SHA256_192) +#define LMS_SHA256_M24_H25 (0x0e | LMS_SHA256_192) /* SHA-256 hash, 32-bytes of hash used, Winternitz width of 1 bit. */ -#define LMOTS_SHA256_N24_W1 (0x01 | LMS_SHA256_192) +#define LMOTS_SHA256_N24_W1 (0x05 | LMS_SHA256_192) /* SHA-256 hash, 32-bytes of hash used, Winternitz width of 2 bits. */ -#define LMOTS_SHA256_N24_W2 (0x02 | LMS_SHA256_192) +#define LMOTS_SHA256_N24_W2 (0x06 | LMS_SHA256_192) /* SHA-256 hash, 32-bytes of hash used, Winternitz width of 4 bits. */ -#define LMOTS_SHA256_N24_W4 (0x03 | LMS_SHA256_192) +#define LMOTS_SHA256_N24_W4 (0x07 | LMS_SHA256_192) /* SHA-256 hash, 32-bytes of hash used, Winternitz width of 8 bits. */ -#define LMOTS_SHA256_N24_W8 (0x04 | LMS_SHA256_192) +#define LMOTS_SHA256_N24_W8 (0x08 | LMS_SHA256_192) typedef struct LmsParams { /* Number of tree levels. */ diff --git a/src/wolfssl/wolfcrypt/wc_mlkem.h b/src/wolfssl/wolfcrypt/wc_mlkem.h new file mode 100644 index 0000000..f79e188 --- /dev/null +++ b/src/wolfssl/wolfcrypt/wc_mlkem.h @@ -0,0 +1,378 @@ +/* wc_mlkem.h + * + * Copyright (C) 2006-2025 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/*! + \file wolfssl/wolfcrypt/wc_mlkem.h +*/ + + +#ifndef WOLF_CRYPT_WC_MLKEM_H +#define WOLF_CRYPT_WC_MLKEM_H + +#include +#include +#include +#include + +#ifdef WOLFSSL_HAVE_MLKEM + +#ifdef WOLFSSL_KYBER_NO_MAKE_KEY + #define WOLFSSL_MLKEM_NO_MAKE_KEY +#endif +#ifdef WOLFSSL_KYBER_NO_ENCAPSULATE + #define WOLFSSL_MLKEM_NO_ENCAPSULATE +#endif +#ifdef WOLFSSL_KYBER_NO_DECAPSULATE + #define WOLFSSL_MLKEM_NO_DECAPSULATE +#endif + +#ifdef noinline + #define MLKEM_NOINLINE noinline +#elif defined(_MSC_VER) + #define MLKEM_NOINLINE __declspec(noinline) +#elif defined(__GNUC__) + #define MLKEM_NOINLINE __attribute__((noinline)) +#else + #define MLKEM_NOINLINE +#endif + +enum { + /* Flags of Kyber keys. */ + MLKEM_FLAG_PRIV_SET = 0x0001, + MLKEM_FLAG_PUB_SET = 0x0002, + MLKEM_FLAG_BOTH_SET = 0x0003, + MLKEM_FLAG_H_SET = 0x0004, + MLKEM_FLAG_A_SET = 0x0008, + + /* 2 bits of random used to create noise value. */ + MLKEM_CBD_ETA2 = 2, + /* 3 bits of random used to create noise value. */ + MLKEM_CBD_ETA3 = 3, + + /* Number of bits to compress to. */ + MLKEM_COMP_4BITS = 4, + MLKEM_COMP_5BITS = 5, + MLKEM_COMP_10BITS = 10, + MLKEM_COMP_11BITS = 11, +}; + + +/* SHAKE128 rate. */ +#define XOF_BLOCK_SIZE 168 + +/* Modulus of co-efficients of polynomial. */ +#define MLKEM_Q 3329 + + +/* Kyber-512 parameters */ +#ifdef WOLFSSL_WC_ML_KEM_512 +/* Number of bits of random to create noise from. */ +#define WC_ML_KEM_512_ETA1 MLKEM_CBD_ETA3 +#endif /* WOLFSSL_WC_ML_KEM_512 */ + +/* Kyber-768 parameters */ +#ifdef WOLFSSL_WC_ML_KEM_768 +/* Number of bits of random to create noise from. */ +#define WC_ML_KEM_768_ETA1 MLKEM_CBD_ETA2 +#endif /* WOLFSSL_WC_ML_KEM_768 */ + +/* Kyber-1024 parameters */ +#ifdef WOLFSSL_WC_ML_KEM_1024 +/* Number of bits of random to create noise from. */ +#define WC_ML_KEM_1024_ETA1 MLKEM_CBD_ETA2 +#endif /* WOLFSSL_KYBER1024 */ + + + +/* The data type of the hash function. */ +#define MLKEM_HASH_T wc_Sha3 + +/* The data type of the pseudo-random function. */ +#define MLKEM_PRF_T wc_Shake + +/* ML-KEM key. */ +struct MlKemKey { + /* Type of key: WC_ML_KEM_512, WC_ML_KEM_768, WC_ML_KEM_1024 */ + int type; + /* Dynamic memory allocation hint. */ + void* heap; +#if defined(WOLF_CRYPTO_CB) + /* Device Id. */ + int devId; +#endif + /* Flags indicating what is stored in the key. */ + int flags; + + /* A pseudo-random function object. */ + MLKEM_HASH_T hash; + /* A pseudo-random function object. */ + MLKEM_PRF_T prf; + + /* Private key as a vector. */ + sword16 priv[WC_ML_KEM_MAX_K * MLKEM_N]; + /* Public key as a vector. */ + sword16 pub[WC_ML_KEM_MAX_K * MLKEM_N]; + /* Public seed. */ + byte pubSeed[WC_ML_KEM_SYM_SZ]; + /* Public hash - hash of encoded public key. */ + byte h[WC_ML_KEM_SYM_SZ]; + /* Randomizer for decapsulation. */ + byte z[WC_ML_KEM_SYM_SZ]; +#ifdef WOLFSSL_MLKEM_CACHE_A + /* A matrix from key generation. */ + sword16 a[WC_ML_KEM_MAX_K * WC_ML_KEM_MAX_K * MLKEM_N]; +#endif +}; + +#ifdef __cplusplus + extern "C" { +#endif + +/* For backward compatibility */ +typedef struct MlKemKey KyberKey; + +WOLFSSL_LOCAL +void mlkem_init(void); + +#ifndef WOLFSSL_MLKEM_MAKEKEY_SMALL_MEM +WOLFSSL_LOCAL +void mlkem_keygen(sword16* priv, sword16* pub, sword16* e, const sword16* a, + int kp); +#else +WOLFSSL_LOCAL +int mlkem_keygen_seeds(sword16* priv, sword16* pub, MLKEM_PRF_T* prf, + sword16* e, int kp, byte* seed, byte* noiseSeed); +#endif +#ifndef WOLFSSL_MLKEM_ENCAPSULATE_SMALL_MEM +WOLFSSL_LOCAL +void mlkem_encapsulate(const sword16* pub, sword16* bp, sword16* v, + const sword16* at, sword16* sp, const sword16* ep, const sword16* epp, + const sword16* m, int kp); +#else +WOLFSSL_LOCAL +int mlkem_encapsulate_seeds(const sword16* pub, MLKEM_PRF_T* prf, sword16* bp, + sword16* tp, sword16* sp, int kp, const byte* msg, byte* seed, + byte* coins); +#endif +WOLFSSL_LOCAL +void mlkem_decapsulate(const sword16* priv, sword16* mp, sword16* bp, + const sword16* v, int kp); + +WOLFSSL_LOCAL +int mlkem_gen_matrix(MLKEM_PRF_T* prf, sword16* a, int kp, byte* seed, + int transposed); +WOLFSSL_LOCAL +int mlkem_get_noise(MLKEM_PRF_T* prf, int kp, sword16* vec1, sword16* vec2, + sword16* poly, byte* seed); + +#if defined(USE_INTEL_SPEEDUP) || \ + (defined(WOLFSSL_ARMASM) && defined(__aarch64__)) +WOLFSSL_LOCAL +int mlkem_kdf(byte* seed, int seedLen, byte* out, int outLen); +#endif +WOLFSSL_LOCAL +void mlkem_hash_init(MLKEM_HASH_T* hash); +WOLFSSL_LOCAL +int mlkem_hash_new(MLKEM_HASH_T* hash, void* heap, int devId); +WOLFSSL_LOCAL +void mlkem_hash_free(MLKEM_HASH_T* hash); +WOLFSSL_LOCAL +int mlkem_hash256(wc_Sha3* hash, const byte* data, word32 dataLen, byte* out); +WOLFSSL_LOCAL +int mlkem_hash512(wc_Sha3* hash, const byte* data1, word32 data1Len, + const byte* data2, word32 data2Len, byte* out); + +WOLFSSL_LOCAL +int mlkem_derive_secret(MLKEM_PRF_T* prf, const byte* z, const byte* ct, + word32 ctSz, byte* ss); + +WOLFSSL_LOCAL +void mlkem_prf_init(MLKEM_PRF_T* prf); +WOLFSSL_LOCAL +int mlkem_prf_new(MLKEM_PRF_T* prf, void* heap, int devId); +WOLFSSL_LOCAL +void mlkem_prf_free(MLKEM_PRF_T* prf); + +WOLFSSL_LOCAL +int mlkem_cmp(const byte* a, const byte* b, int sz); + +WOLFSSL_LOCAL +void mlkem_vec_compress_10(byte* r, sword16* v, unsigned int kp); +WOLFSSL_LOCAL +void mlkem_vec_compress_11(byte* r, sword16* v); +WOLFSSL_LOCAL +void mlkem_vec_decompress_10(sword16* v, const unsigned char* b, + unsigned int kp); +WOLFSSL_LOCAL +void mlkem_vec_decompress_11(sword16* v, const unsigned char* b); + +WOLFSSL_LOCAL +void mlkem_compress_4(byte* b, sword16* p); +WOLFSSL_LOCAL +void mlkem_compress_5(byte* b, sword16* p); +WOLFSSL_LOCAL +void mlkem_decompress_4(sword16* p, const unsigned char* b); +WOLFSSL_LOCAL +void mlkem_decompress_5(sword16* p, const unsigned char* b); + +WOLFSSL_LOCAL +void mlkem_from_msg(sword16* p, const byte* msg); +WOLFSSL_LOCAL +void mlkem_to_msg(byte* msg, sword16* p); +WOLFSSL_LOCAL +void mlkem_from_bytes(sword16* p, const byte* b, int k); +WOLFSSL_LOCAL +void mlkem_to_bytes(byte* b, sword16* p, int k); + +#ifdef USE_INTEL_SPEEDUP +WOLFSSL_LOCAL +void mlkem_keygen_avx2(sword16* priv, sword16* pub, sword16* e, + const sword16* a, int kp); +WOLFSSL_LOCAL +void mlkem_encapsulate_avx2(const sword16* pub, sword16* bp, sword16* v, + const sword16* at, sword16* sp, const sword16* ep, const sword16* epp, + const sword16* m, int kp); +WOLFSSL_LOCAL +void mlkem_decapsulate_avx2(const sword16* priv, sword16* mp, sword16* bp, + const sword16* v, int kp); + +WOLFSSL_LOCAL +unsigned int mlkem_rej_uniform_n_avx2(sword16* p, unsigned int len, + const byte* r, unsigned int rLen); +WOLFSSL_LOCAL +unsigned int mlkem_rej_uniform_avx2(sword16* p, unsigned int len, const byte* r, + unsigned int rLen); +WOLFSSL_LOCAL +void mlkem_redistribute_21_rand_avx2(const word64* s, byte* r0, byte* r1, + byte* r2, byte* r3); +void mlkem_redistribute_17_rand_avx2(const word64* s, byte* r0, byte* r1, + byte* r2, byte* r3); +void mlkem_redistribute_16_rand_avx2(const word64* s, byte* r0, byte* r1, + byte* r2, byte* r3); +void mlkem_redistribute_8_rand_avx2(const word64* s, byte* r0, byte* r1, + byte* r2, byte* r3); + +WOLFSSL_LOCAL +void mlkem_sha3_128_blocksx4_seed_avx2(word64* s, byte* seed); +WOLFSSL_LOCAL +void mlkem_sha3_256_blocksx4_seed_avx2(word64* s, byte* seed); + +WOLFSSL_LOCAL +void mlkem_cbd_eta2_avx2(sword16* p, const byte* r); +WOLFSSL_LOCAL +void mlkem_cbd_eta3_avx2(sword16* p, const byte* r); + +WOLFSSL_LOCAL +void mlkem_from_msg_avx2(sword16* p, const byte* msg); +WOLFSSL_LOCAL +void mlkem_to_msg_avx2(byte* msg, sword16* p); + +WOLFSSL_LOCAL +void mlkem_from_bytes_avx2(sword16* p, const byte* b); +WOLFSSL_LOCAL +void mlkem_to_bytes_avx2(byte* b, sword16* p); + +WOLFSSL_LOCAL +void mlkem_compress_10_avx2(byte* r, const sword16* p, int n); +WOLFSSL_LOCAL +void mlkem_decompress_10_avx2(sword16* p, const byte* r, int n); +WOLFSSL_LOCAL +void mlkem_compress_11_avx2(byte* r, const sword16* p, int n); +WOLFSSL_LOCAL +void mlkem_decompress_11_avx2(sword16* p, const byte* r, int n); + +WOLFSSL_LOCAL +void mlkem_compress_4_avx2(byte* r, const sword16* p); +WOLFSSL_LOCAL +void mlkem_decompress_4_avx2(sword16* p, const byte* r); +WOLFSSL_LOCAL +void mlkem_compress_5_avx2(byte* r, const sword16* p); +WOLFSSL_LOCAL +void mlkem_decompress_5_avx2(sword16* p, const byte* r); + + +WOLFSSL_LOCAL +int mlkem_cmp_avx2(const byte* a, const byte* b, int sz); +#elif defined(__aarch64__) && defined(WOLFSSL_ARMASM) +WOLFSSL_LOCAL void mlkem_ntt(sword16* r); +WOLFSSL_LOCAL void mlkem_invntt(sword16* r); +WOLFSSL_LOCAL void mlkem_ntt_sqrdmlsh(sword16* r); +WOLFSSL_LOCAL void mlkem_invntt_sqrdmlsh(sword16* r); +WOLFSSL_LOCAL void mlkem_basemul_mont(sword16* r, const sword16* a, + const sword16* b); +WOLFSSL_LOCAL void mlkem_basemul_mont_add(sword16* r, const sword16* a, + const sword16* b); +WOLFSSL_LOCAL void mlkem_add_reduce(sword16* r, const sword16* a); +WOLFSSL_LOCAL void mlkem_add3_reduce(sword16* r, const sword16* a, + const sword16* b); +WOLFSSL_LOCAL void mlkem_rsub_reduce(sword16* r, const sword16* a); +WOLFSSL_LOCAL void mlkem_to_mont(sword16* p); +WOLFSSL_LOCAL void mlkem_to_mont_sqrdmlsh(sword16* p); +WOLFSSL_LOCAL void mlkem_sha3_blocksx3_neon(word64* state); +WOLFSSL_LOCAL void mlkem_shake128_blocksx3_seed_neon(word64* state, byte* seed); +WOLFSSL_LOCAL void mlkem_shake256_blocksx3_seed_neon(word64* state, byte* seed); +WOLFSSL_LOCAL unsigned int mlkem_rej_uniform_neon(sword16* p, unsigned int len, + const byte* r, unsigned int rLen); +WOLFSSL_LOCAL int mlkem_cmp_neon(const byte* a, const byte* b, int sz); +WOLFSSL_LOCAL void mlkem_csubq_neon(sword16* p); +WOLFSSL_LOCAL void mlkem_from_msg_neon(sword16* p, const byte* msg); +WOLFSSL_LOCAL void mlkem_to_msg_neon(byte* msg, sword16* p); +#elif defined(WOLFSSL_ARMASM_THUMB2) && defined(WOLFSSL_ARMASM) +#define mlkem_ntt mlkem_thumb2_ntt +#define mlkem_invntt mlkem_thumb2_invntt +#define mlkem_basemul_mont mlkem_thumb2_basemul_mont +#define mlkem_basemul_mont_add mlkem_thumb2_basemul_mont_add +#define mlkem_rej_uniform_c mlkem_thumb2_rej_uniform + +WOLFSSL_LOCAL void mlkem_thumb2_ntt(sword16* r); +WOLFSSL_LOCAL void mlkem_thumb2_invntt(sword16* r); +WOLFSSL_LOCAL void mlkem_thumb2_basemul_mont(sword16* r, const sword16* a, + const sword16* b); +WOLFSSL_LOCAL void mlkem_thumb2_basemul_mont_add(sword16* r, const sword16* a, + const sword16* b); +WOLFSSL_LOCAL void mlkem_thumb2_csubq(sword16* p); +WOLFSSL_LOCAL unsigned int mlkem_thumb2_rej_uniform(sword16* p, + unsigned int len, const byte* r, unsigned int rLen); +#elif defined(WOLFSSL_ARMASM) +#define mlkem_ntt mlkem_arm32_ntt +#define mlkem_invntt mlkem_arm32_invntt +#define mlkem_basemul_mont mlkem_arm32_basemul_mont +#define mlkem_basemul_mont_add mlkem_arm32_basemul_mont_add +#define mlkem_rej_uniform_c mlkem_arm32_rej_uniform + +WOLFSSL_LOCAL void mlkem_arm32_ntt(sword16* r); +WOLFSSL_LOCAL void mlkem_arm32_invntt(sword16* r); +WOLFSSL_LOCAL void mlkem_arm32_basemul_mont(sword16* r, const sword16* a, + const sword16* b); +WOLFSSL_LOCAL void mlkem_arm32_basemul_mont_add(sword16* r, const sword16* a, + const sword16* b); +WOLFSSL_LOCAL void mlkem_arm32_csubq(sword16* p); +WOLFSSL_LOCAL unsigned int mlkem_arm32_rej_uniform(sword16* p, unsigned int len, + const byte* r, unsigned int rLen); +#endif + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFSSL_HAVE_MLKEM */ + +#endif /* WOLF_CRYPT_WC_MLKEM_H */ diff --git a/src/wolfssl/wolfcrypt/wc_pkcs11.h b/src/wolfssl/wolfcrypt/wc_pkcs11.h index 0b8942b..fdc51e0 100644 --- a/src/wolfssl/wolfcrypt/wc_pkcs11.h +++ b/src/wolfssl/wolfcrypt/wc_pkcs11.h @@ -1,6 +1,6 @@ /* wc_pkcs11.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/wc_port.h b/src/wolfssl/wolfcrypt/wc_port.h index 4be0502..a33fbf4 100644 --- a/src/wolfssl/wolfcrypt/wc_port.h +++ b/src/wolfssl/wolfcrypt/wc_port.h @@ -1,6 +1,6 @@ /* wc_port.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -82,6 +82,25 @@ #endif #endif /* !WC_MAYBE_UNUSED */ +#ifndef WC_DEPRECATED + #ifdef WOLFSSL_ZEPHYR + #define WC_DEPRECATED(msg) /* null expansion */ + #elif ((defined(__GNUC__) && \ + ((__GNUC__ >= 5) || \ + ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5))))) || \ + defined(__clang__) + #define WC_DEPRECATED(msg) __attribute__((deprecated(msg))) + #elif defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__) || \ + defined(_WIN32_WCE) || defined(__WATCOMC__) + #define WC_DEPRECATED(msg) __declspec(deprecated(msg)) + #elif (defined(__GNUC__) && (__GNUC__ >= 4)) || \ + defined(__IAR_SYSTEMS_ICC__) + #define WC_DEPRECATED(msg) __attribute__((deprecated)) + #else + #define WC_DEPRECATED(msg) /* null expansion */ + #endif +#endif /* !WC_MAYBE_UNUSED */ + /* use inlining if compiler allows */ #ifndef WC_INLINE #ifndef NO_INLINE @@ -122,6 +141,43 @@ /* THREADING/MUTEX SECTION */ #if defined(SINGLE_THREADED) && defined(NO_FILESYSTEM) /* No system headers required for build. */ +#elif defined(__WATCOMC__) + #if defined(SINGLE_THREADED) + #if defined(USE_WINDOWS_API) + #define _WINSOCKAPI_ /* block inclusion of winsock.h header file */ + #include + #undef _WINSOCKAPI_ /* undefine it for MINGW winsock2.h header */ + #ifndef WOLFSSL_USER_IO + #include + #include /* required for InetPton */ + #endif + #elif defined(__OS2__) + #include + #endif + #else + #if defined(USE_WINDOWS_API) + #define _WINSOCKAPI_ /* block inclusion of winsock.h header file */ + #include + #undef _WINSOCKAPI_ /* undefine it for MINGW winsock2.h header */ + #include + #ifndef WOLFSSL_USER_IO + #include + #include /* required for InetPton */ + #endif + #elif defined(__OS2__) + #define INCL_DOSSEMAPHORES + #define INCL_DOSPROCESS + #include + #include + #else + #ifndef WOLFSSL_USER_MUTEX + #define WOLFSSL_PTHREADS + #endif + #if defined(WOLFSSL_PTHREADS) + #include + #endif + #endif + #endif #elif defined(USE_WINDOWS_API) #if defined(WOLFSSL_PTHREADS) #include @@ -133,12 +189,11 @@ #define WIN32_LEAN_AND_MEAN #endif #if !defined(WOLFSSL_SGX) && !defined(WOLFSSL_NOT_WINDOWS_API) - #if defined(_WIN32_WCE) || defined(WIN32_LEAN_AND_MEAN) - /* On WinCE winsock2.h must be included before windows.h */ - #include - #endif + #define _WINSOCKAPI_ /* block inclusion of winsock.h header file. */ #include + #undef _WINSOCKAPI_ /* undefine it for MINGW winsock2.h header */ #ifndef WOLFSSL_USER_IO + #include #include /* required for InetPton */ #endif #endif /* WOLFSSL_SGX */ @@ -284,7 +339,7 @@ #else /* MULTI_THREADED */ /* FREERTOS comes first to enable use of FreeRTOS Windows simulator only */ #if defined(FREERTOS) - #if ESP_IDF_VERSION_MAJOR >= 4 + #if defined(ESP_IDF_VERSION_MAJOR) && (ESP_IDF_VERSION_MAJOR >= 4) typedef SemaphoreHandle_t wolfSSL_Mutex; #else typedef xSemaphoreHandle wolfSSL_Mutex; @@ -371,6 +426,9 @@ /* typedef User_Mutex wolfSSL_Mutex; */ #elif defined(WOLFSSL_LINUXKM) /* definitions are in linuxkm/linuxkm_wc_port.h */ + #elif defined(__WATCOMC__) + /* OS/2 */ + typedef ULONG wolfSSL_Mutex; #else #error Need a mutex type in multithreaded mode #endif /* USE_WINDOWS_API */ @@ -395,6 +453,8 @@ #ifdef SINGLE_THREADED typedef int wolfSSL_Atomic_Int; #define WOLFSSL_ATOMIC_INITIALIZER(x) (x) + #define WOLFSSL_ATOMIC_LOAD(x) (x) + #define WOLFSSL_ATOMIC_STORE(x, val) (x) = (val) #define WOLFSSL_ATOMIC_OPS #elif defined(HAVE_C___ATOMIC) #ifdef __cplusplus @@ -402,6 +462,8 @@ /* C++ using direct calls to compiler built-in functions */ typedef volatile int wolfSSL_Atomic_Int; #define WOLFSSL_ATOMIC_INITIALIZER(x) (x) + #define WOLFSSL_ATOMIC_LOAD(x) __atomic_load_n(&(x), __ATOMIC_CONSUME) + #define WOLFSSL_ATOMIC_STORE(x, val) __atomic_store_n(&(x), val, __ATOMIC_RELEASE) #define WOLFSSL_ATOMIC_OPS #endif #else @@ -410,6 +472,8 @@ #include typedef atomic_int wolfSSL_Atomic_Int; #define WOLFSSL_ATOMIC_INITIALIZER(x) (x) + #define WOLFSSL_ATOMIC_LOAD(x) atomic_load(&(x)) + #define WOLFSSL_ATOMIC_STORE(x, val) atomic_store(&(x), val) #define WOLFSSL_ATOMIC_OPS #endif /* WOLFSSL_HAVE_ATOMIC_H */ #endif @@ -422,6 +486,8 @@ #endif typedef volatile long wolfSSL_Atomic_Int; #define WOLFSSL_ATOMIC_INITIALIZER(x) (x) + #define WOLFSSL_ATOMIC_LOAD(x) (x) + #define WOLFSSL_ATOMIC_STORE(x, val) (x) = (val) #define WOLFSSL_ATOMIC_OPS #endif #endif /* WOLFSSL_NO_ATOMICS */ @@ -757,13 +823,14 @@ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void); * make the API more POSIX like. */ XFILE z_fs_open(const char* filename, const char* mode); int z_fs_close(XFILE file); + int z_fs_rewind(XFILE file); #define XFOPEN z_fs_open #define XFCLOSE z_fs_close #define XFFLUSH fs_sync #define XFSEEK fs_seek #define XFTELL fs_tell - #define XFREWIND fs_rewind + #define XFREWIND z_fs_rewind #define XFREAD(P,S,N,F) fs_read(F, P, S*N) #define XFWRITE(P,S,N,F) fs_write(F, P, S*N) #define XSEEK_SET FS_SEEK_SET @@ -887,7 +954,25 @@ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void); #if !defined(NO_WOLFSSL_DIR)\ && !defined(WOLFSSL_NUCLEUS) && !defined(WOLFSSL_NUCLEUS_1_2) - #if defined(USE_WINDOWS_API) + #if defined(__WATCOMC__) + #include + #include + #define XWRITE write + #define XREAD read + #define XCLOSE close + #define XSTAT stat + #define XS_ISREG(s) S_ISREG(s) + #if defined(__UNIX__) + #include + #define SEPARATOR_CHAR ':' + #else + #include + #define SEPARATOR_CHAR ';' + #endif + #if defined(__NT__) + #define XALTHOMEVARNAME "USERPROFILE" + #endif + #elif defined(USE_WINDOWS_API) #include #include #ifndef XSTAT @@ -925,9 +1010,7 @@ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void); #define SEPARATOR_CHAR ':' #else - #ifndef NO_WOLFSSL_DIR - #include - #endif + #include #include #include #define XWRITE write @@ -1178,7 +1261,9 @@ WOLFSSL_ABI WOLFSSL_API int wolfCrypt_Cleanup(void); #define XGMTIME(c, t) gmtime((c)) #elif defined(_WIN32_WCE) + #define _WINSOCKAPI_ /* block inclusion of winsock.h header file */ #include + #undef _WINSOCKAPI_ /* undefine it for MINGW winsock2.h header file */ #include /* For file system */ time_t windows_time(time_t* timer); diff --git a/src/wolfssl/wolfcrypt/wc_xmss.h b/src/wolfssl/wolfcrypt/wc_xmss.h index 21d5fe8..e59df61 100644 --- a/src/wolfssl/wolfcrypt/wc_xmss.h +++ b/src/wolfssl/wolfcrypt/wc_xmss.h @@ -1,6 +1,6 @@ /* wc_xmss.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/wolfevent.h b/src/wolfssl/wolfcrypt/wolfevent.h index cb3cb58..d6731d1 100644 --- a/src/wolfssl/wolfcrypt/wolfevent.h +++ b/src/wolfssl/wolfcrypt/wolfevent.h @@ -1,6 +1,6 @@ /* wolfevent.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfcrypt/wolfmath.h b/src/wolfssl/wolfcrypt/wolfmath.h index e012ff6..e2e8545 100644 --- a/src/wolfssl/wolfcrypt/wolfmath.h +++ b/src/wolfssl/wolfcrypt/wolfmath.h @@ -1,6 +1,6 @@ /* wolfmath.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -40,7 +40,16 @@ This library provides big integer math functions. #endif -#if defined(USE_FAST_MATH) +#if defined(NO_BIG_INT) + /* MPI globally disabled -- no PK algorithms supported. */ + #if defined(USE_FAST_MATH) || defined(USE_INTEGER_HEAP_MATH) || \ + defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_MATH) || \ + defined(HAVE_WOLF_BIGINT) || defined(WOLFSSL_EXPORT_INT) + #error Conflicting MPI settings. + #endif +#elif defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_SP_MATH) + #include +#elif defined(USE_FAST_MATH) #include #elif defined(USE_INTEGER_HEAP_MATH) #include @@ -48,7 +57,7 @@ This library provides big integer math functions. #include #endif -#if !defined(NO_BIG_INT) || defined(WOLFSSL_SP_MATH) +#if !defined(NO_BIG_INT) #include #endif @@ -72,7 +81,7 @@ This library provides big integer math functions. extern const wc_ptr_t wc_off_on_addr[2]; #endif -#if !defined(NO_BIG_INT) || defined(WOLFSSL_SP_MATH) +#if !defined(NO_BIG_INT) /* common math functions */ MP_API int get_digit_count(const mp_int* a); MP_API mp_digit get_digit(const mp_int* a, int n); diff --git a/src/wolfssl/wolfcrypt/xmss.h b/src/wolfssl/wolfcrypt/xmss.h index 548700c..9944862 100644 --- a/src/wolfssl/wolfcrypt/xmss.h +++ b/src/wolfssl/wolfcrypt/xmss.h @@ -1,6 +1,6 @@ /* xmss.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * diff --git a/src/wolfssl/wolfio.h b/src/wolfssl/wolfio.h index 4d1145b..de45a18 100644 --- a/src/wolfssl/wolfio.h +++ b/src/wolfssl/wolfio.h @@ -1,6 +1,6 @@ /* io.h * - * Copyright (C) 2006-2024 wolfSSL Inc. + * Copyright (C) 2006-2025 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -57,7 +57,32 @@ #include "zlib.h" #endif -#ifndef USE_WINDOWS_API +#if defined(__WATCOMC__) + #if defined(__NT__) + #elif defined(__OS2__) + #include + #include + #include + #include + #include + #include + #include + #include + #include + + typedef int socklen_t; + #elif defined(__LINUX__) + #include + #include + #include + #include + #define XFCNTL(fd, flag, block) fcntl((fd), (flag), (block)) + #include + #include + #include + #endif +#elif defined(USE_WINDOWS_API) +#else #if defined(WOLFSSL_LWIP) && !defined(WOLFSSL_APACHE_MYNEWT) /* lwIP needs to be configured to use sockets API in this mode */ /* LWIP_SOCKET 1 in lwip/opt.h or in build */ @@ -204,7 +229,40 @@ #define SOCKET_RECEIVING 1 #define SOCKET_SENDING 2 -#ifdef USE_WINDOWS_API +#ifdef __WATCOMC__ + #if defined(__NT__) + /* no epipe yet */ + #ifndef WSAEPIPE + #define WSAEPIPE -12345 + #endif + #define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK + #define SOCKET_EAGAIN WSAETIMEDOUT + #define SOCKET_ETIMEDOUT WSAETIMEDOUT + #define SOCKET_ECONNRESET WSAECONNRESET + #define SOCKET_EINTR WSAEINTR + #define SOCKET_EPIPE WSAEPIPE + #define SOCKET_ECONNREFUSED WSAENOTCONN + #define SOCKET_ECONNABORTED WSAECONNABORTED + #elif defined(__OS2__) + #define SOCKET_EWOULDBLOCK SOCEWOULDBLOCK + #define SOCKET_EAGAIN SOCEAGAIN + #define SOCKET_ETIMEDOUT SOCETIMEDOUT + #define SOCKET_ECONNRESET SOCECONNRESET + #define SOCKET_EINTR SOCEINTR + #define SOCKET_EPIPE SOCEPIPE + #define SOCKET_ECONNREFUSED SOCECONNREFUSED + #define SOCKET_ECONNABORTED SOCECONNABORTED + #elif defined(__UNIX__) + #define SOCKET_EWOULDBLOCK EWOULDBLOCK + #define SOCKET_EAGAIN EAGAIN + #define SOCKET_ETIMEDOUT ETIMEDOUT + #define SOCKET_ECONNRESET ECONNRESET + #define SOCKET_EINTR EINTR + #define SOCKET_EPIPE EPIPE + #define SOCKET_ECONNREFUSED ECONNREFUSED + #define SOCKET_ECONNABORTED ECONNABORTED + #endif +#elif defined(USE_WINDOWS_API) /* no epipe yet */ #ifndef WSAEPIPE #define WSAEPIPE -12345 @@ -836,21 +894,36 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); #ifndef XINET_NTOP - #define XINET_NTOP(a,b,c,d) inet_ntop((a),(b),(c),(d)) - #ifdef USE_WINDOWS_API /* Windows-friendly definition */ - #undef XINET_NTOP + #if defined(__WATCOMC__) + #if defined(__OS2__) || defined(__NT__) && \ + (NTDDI_VERSION >= NTDDI_VISTA) + #define XINET_NTOP(a,b,c,d) inet_ntop((a),(b),(c),(d)) + #else + #define XINET_NTOP(a,b,c,d) \ + strncpy((c),inet_ntoa(*(unsigned *)(b)),(d)) + #endif + #elif defined(USE_WINDOWS_API) /* Windows-friendly definition */ #define XINET_NTOP(a,b,c,d) InetNtop((a),(b),(c),(d)) + #else + #define XINET_NTOP(a,b,c,d) inet_ntop((a),(b),(c),(d)) #endif #endif #ifndef XINET_PTON - #define XINET_PTON(a,b,c) inet_pton((a),(b),(c)) - #ifdef USE_WINDOWS_API /* Windows-friendly definition */ - #undef XINET_PTON + #if defined(__WATCOMC__) + #if defined(__OS2__) || defined(__NT__) && \ + (NTDDI_VERSION >= NTDDI_VISTA) + #define XINET_PTON(a,b,c) inet_pton((a),(b),(c)) + #else + #define XINET_PTON(a,b,c) *(unsigned *)(c) = inet_addr((b)) + #endif + #elif defined(USE_WINDOWS_API) /* Windows-friendly definition */ #if defined(__MINGW64__) && !defined(UNICODE) #define XINET_PTON(a,b,c) InetPton((a),(b),(c)) #else #define XINET_PTON(a,b,c) InetPton((a),(PCWSTR)(b),(c)) #endif + #else + #define XINET_PTON(a,b,c) inet_pton((a),(b),(c)) #endif #endif