diff --git a/.cyignore b/.cyignore new file mode 100644 index 0000000000..4fd9598686 --- /dev/null +++ b/.cyignore @@ -0,0 +1,40 @@ +# wolfSSL folders +$(SEARCH_wolfssl)/IDE +$(SEARCH_wolfssl)/examples +$(SEARCH_wolfssl)/linuxkm +$(SEARCH_wolfssl)/mcapi +$(SEARCH_wolfssl)/mplabx +$(SEARCH_wolfssl)/mqx +$(SEARCH_wolfssl)/tirtos +$(SEARCH_wolfssl)/tests +$(SEARCH_wolfssl)/testsuite +$(SEARCH_wolfssl)/wolfcrypt/src/port/autosar +$(SEARCH_wolfssl)/zephyr + +# wolfSSL files +$(SEARCH_wolfssl)/wolfcrypt/src/aes_asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/aes_xts_asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/aes_gcm_asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/aes_gcm_x86_asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/chacha_asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/fe_x25519_asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/poly1305_asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/sha256_asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/sha512_asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/sha3_asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/sm3_asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/sp_x86_64_asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/sp_sm2_x86_64_asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/wc_kyber_asm.S + +$(SEARCH_wolfssl)/wolfcrypt/src/port/arm/armv8-32-aes-asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/port/arm/armv8-32-curve25519.S +$(SEARCH_wolfssl)/wolfcrypt/src/port/arm/armv8-32-sha256-asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/port/arm/armv8-32-sha512-asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/port/arm/armv8-curve25519.S +$(SEARCH_wolfssl)/wolfcrypt/src/port/arm/armv8-sha3-asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/port/arm/armv8-sha512-asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/port/arm/thumb2-aes-asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/port/arm/thumb2-curve25519.S +$(SEARCH_wolfssl)/wolfcrypt/src/port/arm/thumb2-sha256-asm.S +$(SEARCH_wolfssl)/wolfcrypt/src/port/arm/thumb2-sha512-asm.S diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4579eaabf9..8edb7a7f38 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -42,11 +42,14 @@ jobs: uses: ./.github/workflows/packaging.yml memcached: uses: ./.github/workflows/memcached.yml -# TODO: Currently this test fails. Enable it once it becomes passing. -# libssh2: -# uses: ./.github/workflows/libssh2.yml + libssh2: + uses: ./.github/workflows/libssh2.yml openssh: uses: ./.github/workflows/openssh.yml # TODO: Currently this test fails. Enable it once it becomes passing. # haproxy: # uses: ./.github/workflows/haproxy.yml + ocsp: + uses: ./.github/workflows/ocsp.yml + no-malloc: + uses: ./.github/workflows/no-malloc.yml diff --git a/.github/workflows/no-malloc.yml b/.github/workflows/no-malloc.yml new file mode 100644 index 0000000000..70360fee69 --- /dev/null +++ b/.github/workflows/no-malloc.yml @@ -0,0 +1,34 @@ +name: No Malloc Tests + +on: + workflow_call: + +jobs: + make_check: + strategy: + matrix: + config: [ + # Add new configs here + '--enable-rsa --enable-keygen --disable-dh CFLAGS="-DWOLFSSL_NO_MALLOC"', + ] + name: make check + runs-on: ubuntu-latest + # This should be a safe limit for the tests to run. + timeout-minutes: 6 + steps: + - uses: actions/checkout@v4 + name: Checkout wolfSSL + + - name: Test wolfSSL + run: | + ./autogen.sh + ./configure ${{ matrix.config }} + make + ./wolfcrypt/test/testwolfcrypt + + - name: Print errors + if: ${{ failure() }} + run: | + if [ -f test-suite.log ] ; then + cat test-suite.log + fi diff --git a/.github/workflows/ocsp.yml b/.github/workflows/ocsp.yml new file mode 100644 index 0000000000..edfd2b6f89 --- /dev/null +++ b/.github/workflows/ocsp.yml @@ -0,0 +1,28 @@ +name: OCSP Test + +on: + workflow_call: + +jobs: + ocsp_stapling: + name: ocsp stapling + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Checkout wolfSSL + uses: actions/checkout@v4 + + - name: Build wolfSSL + run: autoreconf -ivf && ./configure --enable-ocsp --enable-ocspstapling && make + + - name: Start OCSP responder 1 + run: openssl ocsp -port 22221 -ndays 1000 -index certs/ocsp/index-intermediate1-ca-issued-certs.txt -rsigner certs/ocsp/ocsp-responder-cert.pem -rkey certs/ocsp/ocsp-responder-key.pem -CA certs/ocsp/intermediate1-ca-cert.pem & + + - name: Start OCSP responder 2 + run: openssl ocsp -port 22220 -ndays 1000 -index certs/ocsp/index-ca-and-intermediate-cas.txt -rsigner certs/ocsp/ocsp-responder-cert.pem -rkey certs/ocsp/ocsp-responder-key.pem -CA certs/ocsp/root-ca-cert.pem & + + - name: Start TLS server + run: ./examples/server/server -p 11111 -c ./certs/ocsp/server1-cert.pem -k ./certs/ocsp/server1-key.pem -d & + + - name: Test Look Up + run: ./examples/client/client -A ./certs/ocsp/root-ca-cert.pem -o diff --git a/.github/workflows/openvpn.yml b/.github/workflows/openvpn.yml index 314f9a4eb4..bf05107b2f 100644 --- a/.github/workflows/openvpn.yml +++ b/.github/workflows/openvpn.yml @@ -34,7 +34,7 @@ jobs: name: ${{ matrix.ref }} runs-on: ubuntu-latest # This should be a safe limit for the tests to run. - timeout-minutes: 6 + timeout-minutes: 10 needs: build_wolfssl steps: - name: Download lib diff --git a/CMakeLists.txt b/CMakeLists.txt index bf6bc75223..9aee6af3fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1216,6 +1216,14 @@ if(WOLFSSL_OPENSSH OR override_cache(WOLFSSL_DES3 "yes") endif() +# DES3 TLS Suites +set(WOLFSSL_DES3_TLS_SUITES_STRING "Enable DES3 TLS cipher suites (default: disabled)") +add_option("WOLFSSL_DES3_TLS_SUITES" ${WOLFSSL_DES3_TLS_SUITES_STRING} "no" "yes;no") + +if(NOT WOLFSSL_DES3_TLS_SUITES) + list(APPEND WOLFSSL_DEFINITIONS "-DNO_DES3_TLS_SUITES") +endif() + # ARC4 set(WOLFSSL_ARC4_HELP_STRING "Enable ARC4 (default: disabled)") add_option("WOLFSSL_ARC4" ${WOLFSSL_ARC4_HELP_STRING} "no" "yes;no") diff --git a/Docker/Dockerfile b/Docker/Dockerfile index b45cff4dec..67db112c53 100644 --- a/Docker/Dockerfile +++ b/Docker/Dockerfile @@ -10,7 +10,7 @@ ARG DEPS_WOLFSSL="build-essential autoconf libtool clang clang-tools zlib1g-dev ARG DEPS_LIBOQS="astyle cmake gcc ninja-build libssl-dev python3-pytest python3-pytest-xdist unzip xsltproc doxygen graphviz python3-yaml valgrind git" ARG DEPS_UDP_PROXY="wget libevent-dev" ARG DEPS_TESTS="abi-dumper libcurl4-openssl-dev tcpdump libpsl-dev python3-pandas python3-tabulate libnl-genl-3-dev libcap-ng-dev" -ARG DEPS_TOOLS="ccache" +ARG DEPS_TOOLS="ccache clang-tidy maven" RUN DEBIAN_FRONTEND=noninteractive apt update && apt install -y apt-utils \ && apt install -y ${DEPS_WOLFSSL} ${DEPS_LIBOQS} ${DEPS_UDP_PROXY} ${DEPS_TESTS} ${DEPS_TOOLS} \ && apt clean -y && rm -rf /var/lib/apt/lists/* diff --git a/Docker/Dockerfile.cross-compiler b/Docker/Dockerfile.cross-compiler index a9868d38dd..573ab0cbbe 100644 --- a/Docker/Dockerfile.cross-compiler +++ b/Docker/Dockerfile.cross-compiler @@ -3,7 +3,7 @@ FROM $DOCKER_BASE_IMAGE USER root -ARG DEPS_TESTING="gcc-arm-linux-gnueabi gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu" +ARG DEPS_TESTING="gcc-arm-linux-gnueabi gcc-arm-linux-gnueabihf gcc-aarch64-linux-gnu gcc-powerpc-linux-gnu gcc-powerpc64-linux-gnu" RUN DEBIAN_FRONTEND=noninteractive apt update \ && apt install -y ${DEPS_TESTING} \ && apt clean -y && rm -rf /var/lib/apt/lists/* diff --git a/Docker/yocto/Dockerfile b/Docker/yocto/Dockerfile index 5fda38f932..2da6769322 100644 --- a/Docker/yocto/Dockerfile +++ b/Docker/yocto/Dockerfile @@ -19,7 +19,7 @@ WORKDIR /opt/poky ARG YOCTO_VERSION=kirkstone RUN git checkout -t origin/${YOCTO_VERSION} -b ${YOCTO_VERSION} && git pull -RUN git clone --single-branch --branch=${YOCTO_VERSION} https://github.com/wolfSSL/meta-wolfssl.git && \ +RUN git clone --single-branch --branch=master https://github.com/wolfssl/meta-wolfssl.git && \ /bin/bash -c "source oe-init-build-env" && \ echo 'IMAGE_INSTALL:append = " wolfssl wolfclu wolfssh wolfmqtt wolftpm wolfclu "' >> /opt/poky/build/conf/local.conf && \ sed -i '/\/opt\/poky\/meta-poky \\/a \\t/opt/poky/meta-wolfssl \\' /opt/poky/build/conf/bblayers.conf diff --git a/IDE/Infineon/README.md b/IDE/Infineon/README.md new file mode 100644 index 0000000000..f6406afb95 --- /dev/null +++ b/IDE/Infineon/README.md @@ -0,0 +1,33 @@ +# Infineon Modus Toolbox + +Steps for building wolfSSL/wolfTPM with the Infineon Modus Toolbox examples: + +1) Add Dependency: + +In "deps" folder add wolfssl.mtb containing: + +``` +https://github.com/wolfssl/wolfssl#v5.7.0-stable#$$ASSET_REPO$$/wolfssl/wolfssl-stable +``` + +For wolfTPM add wolftpm.mtb containing: + +``` +https://github.com/wolfssl/wolftpm#master#$$ASSET_REPO$$/wolftpm/wolftpm-stable +``` + +2) Add components: +In `Makefile` under `COMPONENTS` add `WOLFSSL` and `WOLFTPM`. + +3) Add defines: + +Add `DEFINES+=WOLFSSL_USER_SETTINGS WOLFTPM_USER_SETTINGS` in Makefile. + +4) Build settings: + +Add a `user_settings.h` file for wolfSSL/wolfTPM build settings into `config` directory. +A template is provided here in `IDE/Infineon/user_settings.h`. + +5) Ignores: + +The required library ignores are found in the `.cyignore` file in the wolfSSL and wolfTPM root. diff --git a/IDE/Infineon/include.am b/IDE/Infineon/include.am new file mode 100644 index 0000000000..cc240b696b --- /dev/null +++ b/IDE/Infineon/include.am @@ -0,0 +1,7 @@ +# vim:ft=automake +# included from Top Level Makefile.am +# All paths should be given relative to the root + +EXTRA_DIST += \ + IDE/Infineon/README.md \ + IDE/Infineon/user_settings.h diff --git a/IDE/Infineon/user_settings.h b/IDE/Infineon/user_settings.h new file mode 100644 index 0000000000..62f89b7c0f --- /dev/null +++ b/IDE/Infineon/user_settings.h @@ -0,0 +1,168 @@ +/* user_settings.h + * + * Copyright (C) 2006-2024 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* Example build settings for Infineon Modus Toolbox */ +/* Enables wolfSSL TLS v1.2-v1.3 and TPM support */ +/* SHA-1, SHA-2, AES CBC/GCM, ECDHE, ECDSA, RSA, HMAC, HKDF */ + +#ifndef WOLF_USER_SETTINGS_TPM_H +#define WOLF_USER_SETTINGS_TPM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Platform / Porting */ +#define NO_FILESYSTEM /* File system disable */ +#define SINGLE_THREADED /* No threading */ +#define WOLFSSL_USER_IO /* user recv/send callbacks for network IO */ +#define NO_WRITEV +#define NO_MAIN_DRIVER +#define WOLFSSL_IGNORE_FILE_WARN /* ignore file include warnings */ +#define WOLFSSL_SMALL_STACK /* limit stack usage */ +#define BENCH_EMBEDDED + +/* TLS (allow TLS v1.3 or v1.2) */ +#define WOLFSSL_TLS13 +//#define WOLFSSL_NO_TLS12 +#define NO_OLD_TLS +#define WOLFSSL_EITHER_SIDE /* allow context to be created for either server or client */ + +#define HAVE_TLS_EXTENSIONS +#define HAVE_SUPPORTED_CURVES +#define HAVE_SERVER_RENEGOTIATION_INFO +#define HAVE_ENCRYPT_THEN_MAC + +#ifdef WOLFSSL_TLS13 + #define HAVE_HKDF + #define WC_RSA_PSS + #define WOLFSSL_PSS_LONG_SALT +#endif + +/* Enable crypto callbacks - for TPM offloading */ +#define WOLF_CRYPTO_CB + +/* Enable SP math all (sp_int.c) with multi-precision support */ +#define WOLFSSL_SP_MATH_ALL + +#if 1 + /* Single Precision math for ECC 256 and RSA 2048 */ + #define WOLFSSL_HAVE_SP_RSA + #define WOLFSSL_HAVE_SP_ECC + #define WOLFSSL_SP_SMALL +#endif + +#if 0 + /* only single precision math */ + #define WOLFSSL_SP_MATH +#endif + +/* Enable hardening (timing resistance) */ +#define TFM_TIMING_RESISTANT +#define ECC_TIMING_RESISTANT +#define WC_RSA_BLINDING + +/* Enable PRNG (SHA2-256) */ +#define HAVE_HASHDRBG + +/* Asymmetric */ +#if 1 /* RSA - needed to encrypt salt */ + #undef NO_RSA + #ifdef USE_LOW_RESOURCE + #define WOLFSSL_RSA_PUBLIC_ONLY + #define WOLFSSL_RSA_VERIFY_INLINE + #define NO_CHECK_PRIVATE_KEY + #endif +#else + #define NO_RSA +#endif + +#if 1 /* ECC - needed for encrypt ECC salt */ + #define HAVE_ECC + #define ECC_USER_CURVES /* default to only SECP256R1 */ +#endif + +#if 0 /* DH - TPM doesn't support it */ + #undef NO_DH + #define HAVE_FFDHE_2048 + #define HAVE_DH_DEFAULT_PARAMS +#else + #define NO_DH +#endif + +/* Symmetric Hash */ +#undef NO_SHA /* allow SHA-1 */ +#undef NO_SHA256 /* allow SHA2-256 */ +#define WOLFSSL_SHA384 +#define WOLFSSL_SHA512 + +/* Symmetric Cipher */ +#define WOLFSSL_AES_CFB +#define HAVE_AES_DECRYPT + +#define HAVE_AES_KEYWRAP +#define WOLFSSL_AES_DIRECT +#define HAVE_AESGCM +#define GCM_TABLE_4BIT + +/* Features */ +#define WOLFSSL_ASN_TEMPLATE + +#define WOLFSSL_CERT_GEN +#define WOLFSSL_CERT_REQ +#define WOLFSSL_CERT_EXT + +#define HAVE_PKCS7 +#define HAVE_X963_KDF +#define WOLFSSL_BASE64_ENCODE + +#if 1 + #define HAVE_SESSION_TICKETS + #define SMALL_SESSION_CACHE +#else + #define NO_SESSION_CACHE +#endif + +/* Disables */ +#define NO_PKCS8 +#define NO_PKCS12 +#define NO_PWDBASED +#define NO_DSA +#define NO_DES3 +#define NO_RC4 +#define NO_PSK +#define NO_MD4 +#define NO_MD5 +#define WOLFSSL_NO_SHAKE128 +#define WOLFSSL_NO_SHAKE256 + +/* Logging */ +#ifdef ENABLE_SECURE_SOCKETS_LOGS + #define DEBUG_WOLFSSL +#else + #define NO_ERROR_STRINGS +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* WOLF_USER_SETTINGS_TPM_H */ diff --git a/IDE/include.am b/IDE/include.am index 0656e8ba78..72879b18e6 100644 --- a/IDE/include.am +++ b/IDE/include.am @@ -60,6 +60,7 @@ include IDE/apple-universal/include.am include IDE/MPLABX16/include.am include IDE/MPLABX16/wolfssl.X/nbproject/include.am include IDE/MPLABX16/wolfcrypt_test.X/nbproject/include.am +include IDE/Infineon/include.am EXTRA_DIST+= IDE/IAR-EWARM IDE/MDK-ARM IDE/MYSQL IDE/LPCXPRESSO IDE/HEXIWEAR IDE/Espressif EXTRA_DIST+= IDE/OPENSTM32/README.md diff --git a/Makefile.am b/Makefile.am index 19e766d5bf..f65d371a33 100644 --- a/Makefile.am +++ b/Makefile.am @@ -138,6 +138,7 @@ dist_example_DATA= ACLOCAL_AMFLAGS= -I m4 +EXTRA_DIST+= .cyignore EXTRA_DIST+= wolfssl.vcproj EXTRA_DIST+= wolfssl.vcxproj EXTRA_DIST+= wolfssl64.sln diff --git a/certs/test/cert-bad-neg-int.der b/certs/test/cert-bad-neg-int.der new file mode 100644 index 0000000000..8e5fc4647b Binary files /dev/null and b/certs/test/cert-bad-neg-int.der differ diff --git a/certs/test/cert-bad-oid.der b/certs/test/cert-bad-oid.der new file mode 100644 index 0000000000..cda316511f Binary files /dev/null and b/certs/test/cert-bad-oid.der differ diff --git a/certs/test/cert-bad-utf8.der b/certs/test/cert-bad-utf8.der new file mode 100644 index 0000000000..54e0889109 Binary files /dev/null and b/certs/test/cert-bad-utf8.der differ diff --git a/certs/test/include.am b/certs/test/include.am index 8f123f35f2..ed03557abe 100644 --- a/certs/test/include.am +++ b/certs/test/include.am @@ -29,7 +29,10 @@ EXTRA_DIST += \ certs/test/cert-ext-joi.cfg \ certs/test/cert-ext-multiple.cfg \ certs/test/cert-ext-multiple.der \ - certs/test/cert-ext-multiple.pem + certs/test/cert-ext-multiple.pem \ + certs/test/cert-bad-neg-int.der \ + certs/test/cert-bad-oid.der \ + certs/test/cert-bad-utf8.der # The certs/server-cert with the last byte (signature byte) changed EXTRA_DIST += \ diff --git a/configure.ac b/configure.ac index df2f74e126..354872f49f 100644 --- a/configure.ac +++ b/configure.ac @@ -4805,6 +4805,13 @@ then ENABLED_DES3="yes" fi +# DES3 TLS suites +AC_ARG_ENABLE([des3-tls-suites], + [AS_HELP_STRING([--enable-des3-tls-suites],[Enable DES3 TLS cipher suites (default: disabled)])], + [ ENABLED_DES3_TLS_SUITES=$enableval ], + [ ENABLED_DES3_TLS_SUITES=no ] + ) + # ARC4 if (test "$ENABLED_OPENSSH" = "yes" && test "x$ENABLED_FIPS" = "xno") || \ test "$ENABLED_WPAS" = "yes" || test "$ENABLED_KRB" = "yes" @@ -5749,7 +5756,7 @@ fi AC_ARG_ENABLE([ticket-nonce-malloc], [AS_HELP_STRING([--enable-ticket-nonce-malloc], [Enable dynamic allocation of ticket nonces (default: disabled)])], [ ENABLED_TICKET_NONCE_MALLOC=$enableval ], - [ ENABLED_TICKET_NONCE_MALLOC=no ] + [ ENABLED_TICKET_NONCE_MALLOC=no_implicit ] ) if test "$ENABLED_TICKET_NONCE_MALLOC" = "yes" @@ -6760,6 +6767,13 @@ then AM_CFLAGS="$AM_CFLAGS -DNO_SESSION_CACHE_REF" AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DES_ECB" + + # support longer session ticket nonce + if test "$ENABLED_TICKET_NONCE_MALLOC" = "no_implicit" + then + ENABLED_TICKET_NONCE_MALLOC="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_TICKET_NONCE_MALLOC" + fi fi if test "$ENABLED_PSK" = "no" && test "$ENABLED_LEANPSK" = "no" \ @@ -8711,6 +8725,14 @@ else fi fi +if test "x$ENABLED_DES3_TLS_SUITES" = "xno" +then + AM_CFLAGS="$AM_CFLAGS -DNO_DES3_TLS_SUITES" +else + AS_IF([test "x$ENABLED_DES3" = "xno"], + [AC_MSG_ERROR([DES3 TLS suites require DES3])]) +fi + if test "$ENABLED_AESGCM" != "no" then if test "$ENABLED_AESGCM" = "word" @@ -9514,6 +9536,7 @@ echo " * AES-EAX: $ENABLED_AESEAX" echo " * AES Bitspliced: $ENABLED_AESBS" echo " * ARIA: $ENABLED_ARIA" echo " * DES3: $ENABLED_DES3" +echo " * DES3 TLS Suites: $ENABLED_DES3_TLS_SUITES" echo " * Camellia: $ENABLED_CAMELLIA" echo " * SM4-ECB: $ENABLED_SM4_ECB" echo " * SM4-CBC: $ENABLED_SM4_CBC" diff --git a/examples/client/client.c b/examples/client/client.c index 020e0f55de..6a133f3ddf 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -1103,7 +1103,7 @@ static int ClientWriteRead(WOLFSSL* ssl, const char* msg, int msgSz, /* 4. add the same message into Japanese section */ /* (will be translated later) */ /* 5. add printf() into suitable position of Usage() */ -static const char* client_usage_msg[][75] = { +static const char* client_usage_msg[][78] = { /* English */ { " NOTE: All files relative to wolfSSL home dir\n", /* 0 */ @@ -1318,9 +1318,13 @@ static const char* client_usage_msg[][75] = { #ifndef NO_PSK "--openssl-psk Use TLS 1.3 PSK callback compatible with OpenSSL\n", /* 74 */ #endif +#ifdef HAVE_RPK + "--rpk Use RPK for the defined certificates\n", /* 75 */ +#endif + "--files-are-der Specified files are in DER, not PEM format\n", /* 76 */ "\n" "For simpler wolfSSL TLS client examples, visit\n" - "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 75 */ + "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 77 */ NULL, }, #ifndef NO_MULTIBYTE_PRINT @@ -1542,10 +1546,14 @@ static const char* client_usage_msg[][75] = { #ifndef NO_PSK "--openssl-psk Use TLS 1.3 PSK callback compatible with OpenSSL\n", /* 74 */ #endif +#ifdef HAVE_RPK + "--rpk Use RPK for the defined certificates\n", /* 75 */ +#endif + "--files-are-der Specified files are in DER, not PEM format\n", /* 76 */ "\n" "より簡単なwolfSSL TLS クライアントの例については" "下記にアクセスしてください\n" - "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 75 */ + "https://github.com/wolfSSL/wolfssl-examples/tree/master/tls\n", /* 77 */ NULL, }, #endif @@ -1763,9 +1771,9 @@ static void Usage(void) printf("%s", msg[++msgid]); /* Examples repo link */ #ifdef HAVE_PQC printf("%s", msg[++msgid]); /* --pqc */ - printf("%s", msg[++msgid]); /* --pqc options */ - printf("%s", msg[++msgid]); /* more --pqc options */ - printf("%s", msg[++msgid]); /* more --pqc options */ +#endif +#ifdef WOLFSSL_SRTP + printf("%s", msg[++msgid]); /* dtls-srtp */ #endif #ifdef WOLFSSL_SYS_CA_CERTS printf("%s", msg[++msgid]); /* --sys-ca-certs */ @@ -1773,9 +1781,14 @@ static void Usage(void) #ifdef HAVE_SUPPORTED_CURVES printf("%s", msg[++msgid]); /* --onlyPskDheKe */ #endif -#ifdef WOLFSSL_SRTP - printf("%s", msg[++msgid]); /* dtls-srtp */ +#ifndef NO_PSK + printf("%s", msg[++msgid]); /* --openssl-psk */ +#endif +#ifdef HAVE_RPK + printf("%s", msg[++msgid]); /* --rpk */ #endif + printf("%s", msg[++msgid]); /* --files-are-der */ + printf("%s", msg[++msgid]); /* Documentation Hint */ } #ifdef WOLFSSL_SRTP @@ -1919,6 +1932,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) { "openssl-psk", 0, 265 }, #endif { "quieter", 0, 266 }, +#ifdef HAVE_RPK + { "rpk", 0, 267 }, +#endif /* HAVE_RPK */ + { "files-are-der", 0, 268 }, { 0, 0, 0 } }; #endif @@ -2059,6 +2076,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) int useDtlsCID = 0; char dtlsCID[DTLS_CID_BUFFER_SIZE] = { 0 }; #endif /* WOLFSSL_DTLS_CID */ +#ifdef HAVE_RPK + int useRPK = 0; +#endif /* HAVE_RPK */ + int fileFormat = WOLFSSL_FILETYPE_PEM; char buffer[WOLFSSL_MAX_ERROR_SZ]; @@ -2082,6 +2103,17 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) WOLFSSL_HEAP_HINT *heap = NULL; #endif +#ifdef WOLFSSL_DUAL_ALG_CERTS + /* Set our preference for verfication to be for both the native and + * alternative chains. Ultimately, its the server's choice. This will be + * used in the call to wolfSSL_UseCKS(). */ + byte cks_order[3] = { + WOLFSSL_CKS_SIGSPEC_BOTH, + WOLFSSL_CKS_SIGSPEC_ALTERNATIVE, + WOLFSSL_CKS_SIGSPEC_NATIVE, + }; +#endif /* WOLFSSL_DUAL_ALG_CERTS */ + ((func_args*)args)->return_code = -1; /* error state */ #ifndef NO_RSA @@ -2756,6 +2788,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) case 266: quieter = 1; break; + case 267: +#ifdef HAVE_RPK + useRPK = 1; +#endif /* HAVE_RPK */ + break; + case 268: + fileFormat = WOLFSSL_FILETYPE_ASN1; + break; default: Usage(); XEXIT_T(MY_EX_USAGE); @@ -3129,6 +3169,21 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif +#ifdef HAVE_RPK + if (useRPK) { + char ctype[] = {WOLFSSL_CERT_TYPE_RPK}; + char stype[] = {WOLFSSL_CERT_TYPE_RPK}; + + wolfSSL_CTX_set_client_cert_type(ctx, ctype, sizeof(ctype)/sizeof(ctype[0])); + wolfSSL_CTX_set_server_cert_type(ctx, stype, sizeof(stype)/sizeof(stype[0])); + usePsk = 0; + #ifdef HAVE_CRL + disableCRL = 1; + #endif + doPeerCheck = 0; + } +#endif /* HAVE_RPK */ + if (usePsk) { #ifndef NO_PSK const char *defaultCipherList = cipherList; @@ -3261,7 +3316,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) WOLFSSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) err_sys("can't load client cert buffer"); #elif !defined(TEST_LOAD_BUFFER) - if (wolfSSL_CTX_use_certificate_chain_file(ctx, ourCert) + if (wolfSSL_CTX_use_certificate_chain_file_format(ctx, ourCert, fileFormat) != WOLFSSL_SUCCESS) { wolfSSL_CTX_free(ctx); ctx = NULL; err_sys("can't load client cert file, check file and run from" @@ -3285,7 +3340,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) sizeof_client_key_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) err_sys("can't load client private key buffer"); #elif !defined(TEST_LOAD_BUFFER) - if (wolfSSL_CTX_use_PrivateKey_file(ctx, ourKey, WOLFSSL_FILETYPE_PEM) + if (wolfSSL_CTX_use_PrivateKey_file(ctx, ourKey, fileFormat) != WOLFSSL_SUCCESS) { wolfSSL_CTX_free(ctx); ctx = NULL; err_sys("can't load client private key file, check file and run " @@ -3559,20 +3614,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #ifdef WOLFSSL_DUAL_ALG_CERTS - /* Set our preference for verfication to be for both the native and - * alternative chains. Ultimately, its the server's choice. - */ - { - byte cks_order[3] = { - WOLFSSL_CKS_SIGSPEC_BOTH, - WOLFSSL_CKS_SIGSPEC_ALTERNATIVE, - WOLFSSL_CKS_SIGSPEC_NATIVE, - }; - - if (!wolfSSL_UseCKS(ssl, cks_order, sizeof(cks_order))) { - wolfSSL_CTX_free(ctx); ctx = NULL; - err_sys("unable to set the CKS order."); - } + if (!wolfSSL_UseCKS(ssl, cks_order, sizeof(cks_order))) { + wolfSSL_CTX_free(ctx); ctx = NULL; + err_sys("unable to set the CKS order."); } #endif /* WOLFSSL_DUAL_ALG_CERTS */ @@ -3593,7 +3637,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) err_sys("can't load client cert buffer"); } #elif !defined(TEST_LOAD_BUFFER) - if (wolfSSL_use_certificate_chain_file(ssl, ourCert) + if (wolfSSL_use_certificate_chain_file_format(ssl, ourCert, fileFormat) != WOLFSSL_SUCCESS) { wolfSSL_CTX_free(ctx); ctx = NULL; err_sys("can't load client cert file, check file and run from" @@ -3614,7 +3658,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) sizeof_client_key_der_2048, SSL_FILETYPE_ASN1) != WOLFSSL_SUCCESS) err_sys("can't load client private key buffer"); #elif !defined(TEST_LOAD_BUFFER) - if (wolfSSL_use_PrivateKey_file(ssl, ourKey, WOLFSSL_FILETYPE_PEM) + if (wolfSSL_use_PrivateKey_file(ssl, ourKey, fileFormat) != WOLFSSL_SUCCESS) { wolfSSL_CTX_free(ctx); ctx = NULL; err_sys("can't load client private key file, check file and run " diff --git a/examples/configs/user_settings_wolftpm.h b/examples/configs/user_settings_wolftpm.h index 6797211303..20da890b30 100644 --- a/examples/configs/user_settings_wolftpm.h +++ b/examples/configs/user_settings_wolftpm.h @@ -131,7 +131,7 @@ extern "C" { #else #define NO_RSA #endif -#ifndef USE_LOW_RESOURCE /* ECC */ +#if 1 /* ECC - needed for encrypt ECC salt */ #define HAVE_ECC #define ECC_USER_CURVES /* default to only SECP256R1 */ #endif diff --git a/examples/server/server.c b/examples/server/server.c index 50b6d0a889..6f0faf3385 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -513,14 +513,19 @@ int ServerEchoData(SSL* ssl, int clientfd, int echoData, int block, #define SIZE_FMT "%zu" #define SIZE_TYPE size_t #endif - printf( - "wolfSSL Server Benchmark " SIZE_FMT " bytes\n" - "\tRX %8.3f ms (%8.3f MBps)\n" - "\tTX %8.3f ms (%8.3f MBps)\n", - (SIZE_TYPE)throughput, - rx_time * 1000, throughput / rx_time / 1024 / 1024, - tx_time * 1000, throughput / tx_time / 1024 / 1024 - ); + if (rx_time > 0.0 && tx_time > 0.0) { + printf( + "wolfSSL Server Benchmark " SIZE_FMT " bytes\n" + "\tRX %8.3f ms (%8.3f MBps)\n" + "\tTX %8.3f ms (%8.3f MBps)\n", + (SIZE_TYPE)throughput, + rx_time * 1000, throughput / rx_time / 1024 / 1024, + tx_time * 1000, throughput / tx_time / 1024 / 1024 + ); + } + else { + printf("Invalid rx_time: %f or tx_time: %f\n", rx_time, tx_time); + } } return 0; diff --git a/src/internal.c b/src/internal.c index d889f33705..872721e02a 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2251,6 +2251,9 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) #ifndef NO_CERTS ctx->privateKeyDevId = INVALID_DEVID; +#ifdef WOLFSSL_DUAL_ALG_CERTS + ctx->altPrivateKeyDevId = INVALID_DEVID; +#endif #endif #ifndef NO_DH @@ -4333,11 +4336,15 @@ void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType) #endif #ifdef HAVE_PQC case PQC_SA_MAJOR: - /* Hash performed as part of sign/verify operation. */ + /* 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 if (input[1] == FALCON_LEVEL1_SA_MINOR) { *hsType = falcon_level1_sa_algo; - *hashAlgo = sha512_mac; + *hashAlgo = sha256_mac; } else if (input[1] == FALCON_LEVEL5_SA_MINOR) { *hsType = falcon_level5_sa_algo; @@ -4347,11 +4354,11 @@ void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsType) #ifdef HAVE_DILITHIUM if (input[1] == DILITHIUM_LEVEL2_SA_MINOR) { *hsType = dilithium_level2_sa_algo; - *hashAlgo = sha512_mac; + *hashAlgo = sha256_mac; } else if (input[1] == DILITHIUM_LEVEL3_SA_MINOR) { *hsType = dilithium_level3_sa_algo; - *hashAlgo = sha512_mac; + *hashAlgo = sha384_mac; } else if (input[1] == DILITHIUM_LEVEL5_SA_MINOR) { *hsType = dilithium_level5_sa_algo; @@ -6761,9 +6768,12 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->buffers.keySz = ctx->privateKeySz; ssl->buffers.keyDevId = ctx->privateKeyDevId; #ifdef WOLFSSL_DUAL_ALG_CERTS - ssl->buffers.altKey = ctx->altPrivateKey; - ssl->buffers.altKeySz = ctx->altPrivateKeySz; - ssl->buffers.altKeyType = ctx->altPrivateKeyType; + ssl->buffers.altKey = ctx->altPrivateKey; + ssl->buffers.altKeyType = ctx->altPrivateKeyType; + ssl->buffers.altKeyId = ctx->altPrivateKeyId; + ssl->buffers.altKeyLabel = ctx->altPrivateKeyLabel; + ssl->buffers.altKeySz = ctx->altPrivateKeySz; + ssl->buffers.altKeyDevId = ctx->altPrivateKeyDevId; #endif /* WOLFSSL_DUAL_ALG_CERTS */ #endif #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ @@ -9768,7 +9778,12 @@ ProtocolVersion MakeDTLSv1_3(void) word32 LowResTimer(void) { - return k_uptime_get() / 1000; + int64_t t; + #if defined(CONFIG_ARCH_POSIX) + k_cpu_idle(); + #endif + t = k_uptime_get(); /* returns current uptime in milliseconds */ + return (word32)(t / 1000); } #elif defined(WOLFSSL_LINUXKM) @@ -10561,8 +10576,7 @@ static WC_INLINE int GrowOutputBuffer(WOLFSSL* ssl, int size) #else const byte align = WOLFSSL_GENERAL_ALIGNMENT; #endif - int newSz = size + ssl->buffers.outputBuffer.idx + - ssl->buffers.outputBuffer.length; + word32 newSz; #if WOLFSSL_GENERAL_ALIGNMENT > 0 /* the encrypted data will be offset from the front of the buffer by @@ -10573,7 +10587,15 @@ static WC_INLINE int GrowOutputBuffer(WOLFSSL* ssl, int size) align *= 2; #endif - tmp = (byte*)XMALLOC(newSz + align, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER); + if (! WC_SAFE_SUM_WORD32(ssl->buffers.outputBuffer.idx, + ssl->buffers.outputBuffer.length, newSz)) + return BUFFER_E; + if (! WC_SAFE_SUM_WORD32(newSz, (word32)size, newSz)) + return BUFFER_E; + if (! WC_SAFE_SUM_WORD32(newSz, align, newSz)) + return BUFFER_E; + tmp = (byte*)XMALLOC(newSz, ssl->heap, DYNAMIC_TYPE_OUT_BUFFER); + newSz -= align; WOLFSSL_MSG("growing output buffer"); if (tmp == NULL) @@ -12432,7 +12454,8 @@ void CopyDecodedName(WOLFSSL_X509_NAME* name, DecodedCert* dCert, int nameType) name->sz = (int)XSTRLEN(name->name) + 1; #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) name->rawLen = min(dCert->subjectRawLen, ASN_NAME_MAX); - XMEMCPY(name->raw, dCert->subjectRaw, name->rawLen); + if (name->rawLen > 0) + XMEMCPY(name->raw, dCert->subjectRaw, name->rawLen); #endif } else { @@ -12442,7 +12465,7 @@ void CopyDecodedName(WOLFSSL_X509_NAME* name, DecodedCert* dCert, int nameType) #if (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY)) \ && (defined(HAVE_PKCS7) || defined(WOLFSSL_CERT_EXT)) name->rawLen = min(dCert->issuerRawLen, ASN_NAME_MAX); - if (name->rawLen) { + if (name->rawLen > 0) { XMEMCPY(name->raw, dCert->issuerRaw, name->rawLen); } #endif @@ -12963,23 +12986,40 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) /* Copy over alternative sig and pubkey. In this case we will allocate new * buffers for them as we have no knowledge of when the DecodedCert is * freed. */ - x509->sapkiDer = (byte*)XMALLOC(dCert->sapkiLen, x509->heap, - DYNAMIC_TYPE_X509_EXT); - x509->altSigAlgDer = (byte*)XMALLOC(dCert->altSigAlgLen, x509->heap, - DYNAMIC_TYPE_X509_EXT); - x509->altSigValDer = (byte*)XMALLOC(dCert->altSigValLen, x509->heap, + if (dCert->extSapkiSet) { + x509->sapkiDer = (byte*)XMALLOC(dCert->sapkiLen, x509->heap, DYNAMIC_TYPE_X509_EXT); - if ((x509->sapkiDer != NULL) && (x509->altSigAlgDer != NULL) && - (x509->altSigValDer != NULL)) { - XMEMCPY(x509->sapkiDer, dCert->sapkiDer, dCert->sapkiLen); - XMEMCPY(x509->altSigAlgDer, dCert->altSigAlgDer, dCert->altSigAlgLen); - XMEMCPY(x509->altSigValDer, dCert->altSigValDer, dCert->altSigValLen); - x509->sapkiLen = dCert->sapkiLen; - x509->altSigAlgLen = dCert->altSigAlgLen; - x509->altSigValLen = dCert->altSigValLen; + if (x509->sapkiDer != NULL) { + XMEMCPY(x509->sapkiDer, dCert->sapkiDer, dCert->sapkiLen); + x509->sapkiLen = dCert->sapkiLen; + } + else { + ret = MEMORY_E; + } } - else { - ret = MEMORY_E; + if (dCert->extAltSigAlgSet) { + x509->altSigAlgDer = (byte*)XMALLOC(dCert->altSigAlgLen, x509->heap, + DYNAMIC_TYPE_X509_EXT); + if (x509->altSigAlgDer != NULL) { + XMEMCPY(x509->altSigAlgDer, dCert->altSigAlgDer, + dCert->altSigAlgLen); + x509->altSigAlgLen = dCert->altSigAlgLen; + } + else { + ret = MEMORY_E; + } + } + if (dCert->extAltSigValSet) { + x509->altSigValDer = (byte*)XMALLOC(dCert->altSigValLen, x509->heap, + DYNAMIC_TYPE_X509_EXT); + if (x509->altSigValDer != NULL) { + XMEMCPY(x509->altSigValDer, dCert->altSigValDer, + dCert->altSigValLen); + x509->altSigValLen = dCert->altSigValLen; + } + else { + ret = MEMORY_E; + } } #endif /* WOLFSSL_DUAL_ALG_CERTS */ @@ -13930,39 +13970,6 @@ PRAGMA_GCC_DIAG_POP alreadySigner = AlreadySigner(SSL_CM(ssl), subjectHash); } -#ifdef WOLFSSL_DUAL_ALG_CERTS - if ((ret == 0) && (args->dCert->sapkiDer != NULL)) { -#ifndef WOLFSSL_SMALL_STACK - byte der[MAX_CERT_VERIFY_SZ]; -#else - byte *der = (byte*)XMALLOC(MAX_CERT_VERIFY_SZ, ssl->heap, - DYNAMIC_TYPE_DCERT); - if (der == NULL) { - ret = MEMORY_E; - } -#endif /* ! WOLFSSL_SMALL_STACK */ - - if (ret == 0) { - ret = wc_GeneratePreTBS(args->dCert, der, MAX_CERT_VERIFY_SZ); - - if (ret > 0) { - ret = wc_ConfirmAltSignature(der, ret, - args->dCert->sapkiDer, args->dCert->sapkiLen, - args->dCert->sapkiOID, - args->dCert->altSigValDer, args->dCert->altSigValLen, - args->dCert->altSigAlgOID, ssl->heap); - } -#ifdef WOLFSSL_SMALL_STACK - XFREE(der, ssl->heap, DYNAMIC_TYPE_DCERT); -#endif /* WOLFSSL_SMALL_STACK */ - - if (ret == 0) { - WOLFSSL_MSG("Alternative signature has been verified!"); - } - } - } -#endif /* WOLFSSL_DUAL_ALG_CERTS */ - #ifdef WOLFSSL_SMALL_CERT_VERIFY /* get signature check failures from above */ if (ret == 0) @@ -14288,7 +14295,25 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, ERROR_OUT(BUFFER_ERROR, exit_ppc); } c24to32(input + args->idx, &listSz); - args->idx += OPAQUE24_LEN; +#ifdef HAVE_RPK + /* + * If this is RPK from the peer, then single cert (if TLS1.2). + * So, ListSz location is same as CertSz location, so fake + * we have just seen this ListSz. + */ + if (!IsAtLeastTLSv1_3(ssl->version) && + ((ssl->options.side == WOLFSSL_SERVER_END && + ssl->options.rpkState.received_ClientCertTypeCnt == 1 && + ssl->options.rpkState.received_ClientCertTypes[0] == WOLFSSL_CERT_TYPE_RPK) || + (ssl->options.side == WOLFSSL_CLIENT_END && + ssl->options.rpkState.received_ServerCertTypeCnt == 1 && + ssl->options.rpkState.received_ServerCertTypes[0] == WOLFSSL_CERT_TYPE_RPK))) { + listSz += OPAQUE24_LEN; + } else +#endif /* HAVE_RPK */ + { + args->idx += OPAQUE24_LEN; + } if (listSz > MAX_CERTIFICATE_SZ) { ERROR_OUT(BUFFER_ERROR, exit_ppc); } @@ -23076,6 +23101,9 @@ int SendCertificate(WOLFSSL* ssl) int ret = 0; word32 certSz, certChainSz, headerSz, listSz, payloadSz; word32 length, maxFragment; +#ifdef HAVE_RPK + int usingRpkTls12 = 0; +#endif /* HAVE_RPK */ WOLFSSL_START(WC_FUNC_CERTIFICATE_SEND); WOLFSSL_ENTER("SendCertificate"); @@ -23085,6 +23113,21 @@ int SendCertificate(WOLFSSL* ssl) return 0; /* not needed */ } +#ifdef HAVE_RPK + if (!IsAtLeastTLSv1_3(ssl->version)) { + /* If this is (D)TLS1.2 and RPK, then single cert, not list. */ + if (ssl->options.side == WOLFSSL_SERVER_END) { + if (ssl->options.rpkState.sending_ServerCertTypeCnt == 1 && + ssl->options.rpkState.sending_ServerCertTypes[0] == WOLFSSL_CERT_TYPE_RPK) + usingRpkTls12 = 1; + } else if (ssl->options.side == WOLFSSL_CLIENT_END) { + if (ssl->options.rpkState.sending_ClientCertTypeCnt == 1 && + ssl->options.rpkState.sending_ClientCertTypes[0] == WOLFSSL_CERT_TYPE_RPK) + usingRpkTls12 = 1; + } + } +#endif /* HAVE_RPK */ + if (ssl->options.sendVerify == SEND_BLANK_CERT) { #ifdef OPENSSL_EXTRA if (ssl->version.major == SSLv3_MAJOR @@ -23107,10 +23150,19 @@ int SendCertificate(WOLFSSL* ssl) return BUFFER_ERROR; } certSz = ssl->buffers.certificate->length; - headerSz = 2 * CERT_HEADER_SZ; +#ifdef HAVE_RPK + if (usingRpkTls12) { + headerSz = 1 * CERT_HEADER_SZ; + listSz = certSz; + } else { +#endif /* HAVE_RPK */ + headerSz = 2 * CERT_HEADER_SZ; + listSz = certSz + CERT_HEADER_SZ; +#ifdef HAVE_RPK + } +#endif /* HAVE_RPK */ /* list + cert size */ length = certSz + headerSz; - listSz = certSz + CERT_HEADER_SZ; /* may need to send rest of chain, already has leading size(s) */ if (certSz && ssl->buffers.certChain) { @@ -23203,12 +23255,18 @@ int SendCertificate(WOLFSSL* ssl) } /* list total */ - c32to24(listSz, output + i); - if (ssl->options.dtls || !IsEncryptionOn(ssl, 1)) - HashRaw(ssl, output + i, CERT_HEADER_SZ); - i += CERT_HEADER_SZ; - length -= CERT_HEADER_SZ; - fragSz -= CERT_HEADER_SZ; +#ifdef HAVE_RPK + if (!usingRpkTls12) { +#endif /* HAVE_RPK */ + c32to24(listSz, output + i); + if (ssl->options.dtls || !IsEncryptionOn(ssl, 1)) + HashRaw(ssl, output + i, CERT_HEADER_SZ); + i += CERT_HEADER_SZ; + length -= CERT_HEADER_SZ; + fragSz -= CERT_HEADER_SZ; +#ifdef HAVE_RPK + } +#endif /* HAVE_RPK */ if (certSz) { c32to24(certSz, output + i); if (ssl->options.dtls || !IsEncryptionOn(ssl, 1)) @@ -27676,7 +27734,7 @@ int CreateDevPrivateKey(void** pkey, byte* data, word32 length, int hsType, * length The length of a signature. * returns 0 on success, otherwise failure. */ -int DecodePrivateKey(WOLFSSL *ssl, word16* length) +int DecodePrivateKey(WOLFSSL *ssl, word32* length) { int ret = BAD_FUNC_ARG; int keySz; @@ -27691,7 +27749,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx) #endif ) { - *length = (word16)GetPrivateKeySigSize(ssl); + *length = GetPrivateKeySigSize(ssl); return 0; } else @@ -27709,9 +27767,12 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) ssl->hsType = DYNAMIC_TYPE_RSA; else if (ssl->buffers.keyType == ecc_dsa_sa_algo) ssl->hsType = DYNAMIC_TYPE_ECC; - else if (ssl->buffers.keyType == falcon_level5_sa_algo) + else if ((ssl->buffers.keyType == falcon_level1_sa_algo) || + (ssl->buffers.keyType == falcon_level5_sa_algo)) ssl->hsType = DYNAMIC_TYPE_FALCON; - else if (ssl->buffers.keyType == dilithium_level5_sa_algo) + else if ((ssl->buffers.keyType == dilithium_level2_sa_algo) || + (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); if (ret != 0) { @@ -27738,7 +27799,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) } /* Return the maximum signature length. */ - *length = (word16)ssl->buffers.keySz; + *length = ssl->buffers.keySz; } #else ret = NOT_COMPILED_IN; @@ -27764,13 +27825,14 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) } /* Return the maximum signature length. */ - *length = (word16)wc_ecc_sig_size_calc(ssl->buffers.keySz); + *length = wc_ecc_sig_size_calc(ssl->buffers.keySz); } #else ret = NOT_COMPILED_IN; #endif } - else if (ssl->buffers.keyType == falcon_level5_sa_algo) { + else if ((ssl->buffers.keyType == falcon_level1_sa_algo) || + (ssl->buffers.keyType == falcon_level5_sa_algo)) { #if defined(HAVE_PQC) && defined(HAVE_FALCON) if (ssl->buffers.keyLabel) { ret = wc_falcon_init_label((falcon_key*)ssl->hsKey, @@ -27783,6 +27845,14 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) ssl->buffers.key->length, ssl->heap, ssl->buffers.keyDevId); } + if (ret == 0) { + if (ssl->buffers.keyType == falcon_level1_sa_algo) { + ret = wc_falcon_set_level((falcon_key*)ssl->hsKey, 1); + } + else if (ssl->buffers.keyType == falcon_level5_sa_algo) { + ret = wc_falcon_set_level((falcon_key*)ssl->hsKey, 5); + } + } if (ret == 0) { if (ssl->buffers.keySz < ssl->options.minFalconKeySz) { WOLFSSL_MSG("Falcon key size too small"); @@ -27790,13 +27860,15 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) } /* Return the maximum signature length. */ - *length = (word16)wc_falcon_sig_size((falcon_key*)ssl->hsKey); + *length = wc_falcon_sig_size((falcon_key*)ssl->hsKey); } #else ret = NOT_COMPILED_IN; #endif } - else if (ssl->buffers.keyType == dilithium_level5_sa_algo) { + else if ((ssl->buffers.keyType == dilithium_level2_sa_algo) || + (ssl->buffers.keyType == dilithium_level3_sa_algo) || + (ssl->buffers.keyType == dilithium_level5_sa_algo)) { #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) if (ssl->buffers.keyLabel) { ret = wc_dilithium_init_label((dilithium_key*)ssl->hsKey, @@ -27809,6 +27881,17 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) ssl->buffers.key->length, ssl->heap, ssl->buffers.keyDevId); } + if (ret == 0) { + if (ssl->buffers.keyType == dilithium_level2_sa_algo) { + ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, 2); + } + else if (ssl->buffers.keyType == dilithium_level3_sa_algo) { + ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, 3); + } + else if (ssl->buffers.keyType == dilithium_level5_sa_algo) { + ret = wc_dilithium_set_level((dilithium_key*)ssl->hsKey, 5); + } + } if (ret == 0) { if (ssl->buffers.keySz < ssl->options.minDilithiumKeySz) { WOLFSSL_MSG("Dilithium key size too small"); @@ -27816,7 +27899,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) } /* Return the maximum signature length. */ - *length = (word16)wc_dilithium_sig_size( + *length = wc_dilithium_sig_size( (dilithium_key*)ssl->hsKey); } #else @@ -27870,7 +27953,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) } /* Return the maximum signature length. */ - *length = (word16)keySz; + *length = keySz; goto exit_dpk; } @@ -27930,7 +28013,7 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) } /* Return the maximum signature length. */ - *length = (word16)wc_ecc_sig_size((ecc_key*)ssl->hsKey); + *length = wc_ecc_sig_size((ecc_key*)ssl->hsKey); goto exit_dpk; } @@ -28104,13 +28187,14 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) WOLFSSL_MSG("Using Falcon private key"); /* Check it meets the minimum Falcon key size requirements. */ - if (FALCON_MAX_KEY_SIZE < ssl->options.minFalconKeySz) { + keySz = wc_falcon_size((falcon_key*)ssl->hsKey); + if (keySz < ssl->options.minFalconKeySz) { WOLFSSL_MSG("Falcon key size too small"); ERROR_OUT(FALCON_KEY_SIZE_E, exit_dpk); } /* Return the maximum signature length. */ - *length = FALCON_MAX_SIG_SIZE; + *length = wc_falcon_sig_size((falcon_key*)ssl->hsKey); goto exit_dpk; } @@ -28175,13 +28259,14 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) WOLFSSL_MSG("Using Dilithium private key"); /* Check it meets the minimum Dilithium key size requirements. */ - if (DILITHIUM_MAX_KEY_SIZE < ssl->options.minDilithiumKeySz) { + keySz = wc_dilithium_size((dilithium_key*)ssl->hsKey); + if (keySz < ssl->options.minDilithiumKeySz) { WOLFSSL_MSG("Dilithium key size too small"); ERROR_OUT(DILITHIUM_KEY_SIZE_E, exit_dpk); } /* Return the maximum signature length. */ - *length = DILITHIUM_MAX_SIG_SIZE; + *length = wc_dilithium_sig_size((dilithium_key*)ssl->hsKey); goto exit_dpk; } @@ -28201,12 +28286,15 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) return ret; } -#if defined(HAVE_PQC) && defined(WOLFSSL_DUAL_ALG_CERTS) -/* This is just like the above, but only consider Falcon and Dilthium and - * only for the alternative key; not the native key. */ -int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length) +#if defined(WOLFSSL_DUAL_ALG_CERTS) +/* This is just like the above, but only consider RSA, ECC, Falcon and + * Dilthium; Furthermore, use the alternative key, not the native key. + */ +int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length) { int ret = BAD_FUNC_ARG; + int keySz; + word32 idx; /* make sure alt private key exists */ if (ssl->buffers.altKey == NULL || ssl->buffers.altKey->buffer == NULL) { @@ -28214,8 +28302,279 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length) ERROR_OUT(NO_PRIVATE_KEY, exit_dapk); } +#ifdef WOLF_PRIVATE_KEY_ID + if (ssl->buffers.altKeyDevId != INVALID_DEVID && + (ssl->buffers.altKeyId || ssl->buffers.altKeyLabel)) { + if (ssl->buffers.altKeyType == rsa_sa_algo) + ssl->hsAltType = DYNAMIC_TYPE_RSA; + else if (ssl->buffers.altKeyType == ecc_dsa_sa_algo) + ssl->hsAltType = DYNAMIC_TYPE_ECC; + else if ((ssl->buffers.altKeyType == falcon_level1_sa_algo) || + (ssl->buffers.altKeyType == falcon_level5_sa_algo)) + ssl->hsAltType = DYNAMIC_TYPE_FALCON; + else if ((ssl->buffers.altKeyType == dilithium_level2_sa_algo) || + (ssl->buffers.altKeyType == dilithium_level3_sa_algo) || + (ssl->buffers.altKeyType == dilithium_level5_sa_algo)) + ssl->hsAltType = DYNAMIC_TYPE_DILITHIUM; + ret = AllocKey(ssl, ssl->hsAltType, &ssl->hsAltKey); + if (ret != 0) { + goto exit_dapk; + } + + if (ssl->buffers.altKeyType == rsa_sa_algo) { + #ifndef NO_RSA + if (ssl->buffers.altKeyLabel) { + ret = wc_InitRsaKey_Label((RsaKey*)ssl->hsAltKey, + (char*)ssl->buffers.altKey->buffer, + ssl->heap, ssl->buffers.altKeyDevId); + } + else if (ssl->buffers.altKeyId) { + ret = wc_InitRsaKey_Id((RsaKey*)ssl->hsAltKey, + ssl->buffers.altKey->buffer, + ssl->buffers.altKey->length, ssl->heap, + ssl->buffers.altKeyDevId); + } + if (ret == 0) { + if (ssl->buffers.altKeySz < ssl->options.minRsaKeySz) { + WOLFSSL_MSG("RSA key size too small"); + ERROR_OUT(RSA_KEY_SIZE_E, exit_dapk); + } + + /* Return the maximum signature length. */ + *length = ssl->buffers.altKeySz; + } + #else + ret = NOT_COMPILED_IN; + #endif + } + else if (ssl->buffers.altKeyType == ecc_dsa_sa_algo) { + #ifdef HAVE_ECC + if (ssl->buffers.altKeyLabel) { + ret = wc_ecc_init_label((ecc_key*)ssl->hsAltKey, + (char*)ssl->buffers.altKey->buffer, + ssl->heap, ssl->buffers.altKeyDevId); + } + else if (ssl->buffers.altKeyId) { + ret = wc_ecc_init_id((ecc_key*)ssl->hsAltKey, + ssl->buffers.altKey->buffer, + ssl->buffers.altKey->length, ssl->heap, + ssl->buffers.altKeyDevId); + } + if (ret == 0) { + if (ssl->buffers.altKeySz < ssl->options.minEccKeySz) { + WOLFSSL_MSG("ECC key size too small"); + ERROR_OUT(ECC_KEY_SIZE_E, exit_dapk); + } + + /* Return the maximum signature length. */ + *length = wc_ecc_sig_size_calc(ssl->buffers.altKeySz); + } + #else + ret = NOT_COMPILED_IN; + #endif + } + else if ((ssl->buffers.altKeyType == falcon_level1_sa_algo) || + (ssl->buffers.altKeyType == falcon_level5_sa_algo)) { + #if defined(HAVE_PQC) && defined(HAVE_FALCON) + if (ssl->buffers.altKeyLabel) { + ret = wc_falcon_init_label((falcon_key*)ssl->hsAltKey, + (char*)ssl->buffers.altKey->buffer, + ssl->heap, ssl->buffers.altKeyDevId); + } + else if (ssl->buffers.altKeyId) { + ret = wc_falcon_init_id((falcon_key*)ssl->hsAltKey, + ssl->buffers.altKey->buffer, + ssl->buffers.altKey->length, ssl->heap, + ssl->buffers.altKeyDevId); + } + if (ret == 0) { + if (ssl->buffers.altKeyType == falcon_level1_sa_algo) { + ret = wc_falcon_set_level((falcon_key*)ssl->hsAltKey, 1); + } + else if (ssl->buffers.altKeyType == falcon_level5_sa_algo) { + ret = wc_falcon_set_level((falcon_key*)ssl->hsAltKey, 5); + } + } + if (ret == 0) { + if (ssl->buffers.altKeySz < ssl->options.minFalconKeySz) { + WOLFSSL_MSG("Falcon key size too small"); + ERROR_OUT(FALCON_KEY_SIZE_E, exit_dapk); + } + + /* Return the maximum signature length. */ + *length = wc_falcon_sig_size((falcon_key*)ssl->hsAltKey); + } + #else + ret = NOT_COMPILED_IN; + #endif + } + else if ((ssl->buffers.altKeyType == dilithium_level2_sa_algo) || + (ssl->buffers.altKeyType == dilithium_level3_sa_algo) || + (ssl->buffers.altKeyType == dilithium_level5_sa_algo)) { + #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + if (ssl->buffers.altKeyLabel) { + ret = wc_dilithium_init_label((dilithium_key*)ssl->hsAltKey, + (char*)ssl->buffers.altKey->buffer, + ssl->heap, ssl->buffers.altKeyDevId); + } + else if (ssl->buffers.altKeyId) { + ret = wc_dilithium_init_id((dilithium_key*)ssl->hsAltKey, + ssl->buffers.altKey->buffer, + ssl->buffers.altKey->length, ssl->heap, + ssl->buffers.altKeyDevId); + } + if (ret == 0) { + if (ssl->buffers.altKeyType == dilithium_level2_sa_algo) { + ret = wc_dilithium_set_level( + (dilithium_key*)ssl->hsAltKey, 2); + } + else if (ssl->buffers.altKeyType == dilithium_level3_sa_algo) { + ret = wc_dilithium_set_level( + (dilithium_key*)ssl->hsAltKey, 3); + } + else if (ssl->buffers.altKeyType == dilithium_level5_sa_algo) { + ret = wc_dilithium_set_level( + (dilithium_key*)ssl->hsAltKey, 5); + } + } + if (ret == 0) { + if (ssl->buffers.altKeySz < ssl->options.minDilithiumKeySz) { + WOLFSSL_MSG("Dilithium key size too small"); + ERROR_OUT(DILITHIUM_KEY_SIZE_E, exit_dapk); + } + + /* Return the maximum signature length. */ + *length = wc_dilithium_sig_size( + (dilithium_key*)ssl->hsAltKey); + } + #else + ret = NOT_COMPILED_IN; + #endif + } + goto exit_dapk; + } +#endif /* WOLF_PRIVATE_KEY_ID */ + +#ifndef NO_RSA + if (ssl->buffers.altKeyType == rsa_sa_algo || + ssl->buffers.altKeyType == 0) { + ssl->hsAltType = DYNAMIC_TYPE_RSA; + ret = AllocKey(ssl, ssl->hsAltType, &ssl->hsAltKey); + if (ret != 0) { + goto exit_dapk; + } + + WOLFSSL_MSG("Trying RSA private key"); + + /* Set start of data to beginning of buffer. */ + idx = 0; + /* Decode the key assuming it is an RSA private key. */ + ret = wc_RsaPrivateKeyDecode(ssl->buffers.altKey->buffer, &idx, + (RsaKey*)ssl->hsAltKey, ssl->buffers.altKey->length); + #ifdef WOLF_PRIVATE_KEY_ID + /* if using external key then allow using a public key */ + if (ret != 0 && (ssl->devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx) + #endif + )) { + WOLFSSL_MSG("Trying RSA public key with crypto callbacks"); + idx = 0; + ret = wc_RsaPublicKeyDecode(ssl->buffers.altKey->buffer, &idx, + (RsaKey*)ssl->hsAltKey, ssl->buffers.altKey->length); + } + #endif + if (ret == 0) { + WOLFSSL_MSG("Using RSA private key"); + + /* It worked so check it meets minimum key size requirements. */ + keySz = wc_RsaEncryptSize((RsaKey*)ssl->hsAltKey); + if (keySz < 0) { /* check if keySz has error case */ + ERROR_OUT(keySz, exit_dapk); + } + + if (keySz < ssl->options.minRsaKeySz) { + WOLFSSL_MSG("RSA key size too small"); + ERROR_OUT(RSA_KEY_SIZE_E, exit_dapk); + } + + /* Return the maximum signature length. */ + *length = keySz; + + goto exit_dapk; + } + } +#endif /* !NO_RSA */ + +#ifdef HAVE_ECC +#ifndef NO_RSA + FreeKey(ssl, ssl->hsAltType, (void**)&ssl->hsAltKey); +#endif /* !NO_RSA */ + + if (ssl->buffers.altKeyType == ecc_dsa_sa_algo || + ssl->buffers.altKeyType == 0 + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + || ssl->buffers.altKeyType == sm2_sa_algo + #endif + ) { + ssl->hsAltType = DYNAMIC_TYPE_ECC; + ret = AllocKey(ssl, ssl->hsAltType, &ssl->hsAltKey); + if (ret != 0) { + goto exit_dapk; + } + + #ifndef NO_RSA + WOLFSSL_MSG("Trying ECC private key, RSA didn't work"); + #else + WOLFSSL_MSG("Trying ECC private key"); + #endif + + /* Set start of data to beginning of buffer. */ + idx = 0; + /* Decode the key assuming it is an ECC private key. */ + ret = wc_EccPrivateKeyDecode(ssl->buffers.altKey->buffer, &idx, + (ecc_key*)ssl->hsAltKey, + ssl->buffers.altKey->length); + #ifdef WOLF_PRIVATE_KEY_ID + /* if using external key then allow using a public key */ + if (ret != 0 && (ssl->devId != INVALID_DEVID + #ifdef HAVE_PK_CALLBACKS + || wolfSSL_CTX_IsPrivatePkSet(ssl->ctx) + #endif + )) { + WOLFSSL_MSG("Trying ECC public key with crypto callbacks"); + idx = 0; + ret = wc_EccPublicKeyDecode(ssl->buffers.altKey->buffer, &idx, + (ecc_key*)ssl->hsAltKey, + ssl->buffers.altKey->length); + } + #endif + if (ret == 0) { + WOLFSSL_MSG("Using ECC private key"); + + /* Check it meets the minimum ECC key size requirements. */ + keySz = wc_ecc_size((ecc_key*)ssl->hsAltKey); + if (keySz < ssl->options.minEccKeySz) { + WOLFSSL_MSG("ECC key size too small"); + ERROR_OUT(ECC_KEY_SIZE_E, exit_dapk); + } + + /* Return the maximum signature length. */ + *length = wc_ecc_sig_size((ecc_key*)ssl->hsAltKey); + + goto exit_dapk; + } + } +#endif +#if defined(HAVE_PQC) +#if defined(HAVE_FALCON) + #if !defined(NO_RSA) || defined(HAVE_ECC) + FreeKey(ssl, ssl->hsAltType, (void**)&ssl->hsAltKey); + #endif + if (ssl->buffers.altKeyType == falcon_level1_sa_algo || - ssl->buffers.altKeyType == falcon_level5_sa_algo) { + ssl->buffers.altKeyType == falcon_level5_sa_algo || + ssl->buffers.altKeyType == 0) { ssl->hsAltType = DYNAMIC_TYPE_FALCON; ret = AllocKey(ssl, ssl->hsAltType, &ssl->hsAltKey); @@ -28230,14 +28589,25 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length) ret = wc_falcon_set_level((falcon_key*)ssl->hsAltKey, 5); } else { + /* What if ssl->buffers.keyType is 0? We might want to do something + * more graceful here. */ ret = ALGO_ID_E; } if (ret != 0) { goto exit_dapk; } - WOLFSSL_MSG("Trying Falcon private key"); + #if defined(HAVE_ECC) + WOLFSSL_MSG("Trying Falcon private key, ECC didn't work"); + #elif !defined(NO_RSA) + WOLFSSL_MSG("Trying Falcon private key, RSA didn't work"); + #else + WOLFSSL_MSG("Trying Falcon private key"); + #endif + + /* Set start of data to beginning of buffer. */ + idx = 0; /* Decode the key assuming it is a Falcon private key. */ ret = wc_falcon_import_private_only(ssl->buffers.altKey->buffer, ssl->buffers.altKey->length, @@ -28246,21 +28616,28 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length) WOLFSSL_MSG("Using Falcon private key"); /* Check it meets the minimum Falcon key size requirements. */ - if (FALCON_MAX_KEY_SIZE < ssl->options.minFalconKeySz) { + keySz = wc_falcon_size((falcon_key*)ssl->hsAltKey); + if (keySz < ssl->options.minFalconKeySz) { WOLFSSL_MSG("Falcon key size too small"); ERROR_OUT(FALCON_KEY_SIZE_E, exit_dapk); } + /* Return the maximum signature length. */ *length = wc_falcon_sig_size((falcon_key*)ssl->hsAltKey); goto exit_dapk; } } - FreeKey(ssl, ssl->hsAltType, (void**)&ssl->hsAltKey); +#endif /* HAVE_FALCON */ +#if defined(HAVE_DILITHIUM) + #if !defined(NO_RSA) || defined(HAVE_ECC) + FreeKey(ssl, ssl->hsAltType, (void**)&ssl->hsAltKey); + #endif if (ssl->buffers.altKeyType == dilithium_level2_sa_algo || ssl->buffers.altKeyType == dilithium_level3_sa_algo || - ssl->buffers.altKeyType == dilithium_level5_sa_algo) { + ssl->buffers.altKeyType == dilithium_level5_sa_algo || + ssl->buffers.altKeyType == 0) { ssl->hsAltType = DYNAMIC_TYPE_DILITHIUM; ret = AllocKey(ssl, ssl->hsAltType, &ssl->hsAltKey); @@ -28278,6 +28655,8 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length) ret = wc_dilithium_set_level((dilithium_key*)ssl->hsAltKey, 5); } else { + /* What if ssl->buffers.keyType is 0? We might want to do something + * more graceful here. */ ret = ALGO_ID_E; } @@ -28285,8 +28664,18 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length) goto exit_dapk; } - WOLFSSL_MSG("Trying Dilithium private key"); + #if defined(HAVE_FALCON) + WOLFSSL_MSG("Trying Dilithium private key, Falcon didn't work"); + #elif defined(HAVE_ECC) + WOLFSSL_MSG("Trying Dilithium private key, ECC didn't work"); + #elif !defined(NO_RSA) + WOLFSSL_MSG("Trying Dilithium private key, RSA didn't work"); + #else + WOLFSSL_MSG("Trying Dilithium private key"); + #endif + /* Set start of data to beginning of buffer. */ + idx = 0; /* Decode the key assuming it is a Dilithium private key. */ ret = wc_dilithium_import_private_only(ssl->buffers.altKey->buffer, ssl->buffers.altKey->length, @@ -28295,16 +28684,24 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length) WOLFSSL_MSG("Using Dilithium private key"); /* Check it meets the minimum Dilithium key size requirements. */ - if (DILITHIUM_MAX_KEY_SIZE < ssl->options.minDilithiumKeySz) { + keySz = wc_dilithium_size((dilithium_key*)ssl->hsAltKey); + if (keySz < ssl->options.minDilithiumKeySz) { WOLFSSL_MSG("Dilithium key size too small"); ERROR_OUT(DILITHIUM_KEY_SIZE_E, exit_dapk); } + /* Return the maximum signature length. */ *length = wc_dilithium_sig_size((dilithium_key*)ssl->hsAltKey); goto exit_dapk; } } +#endif /* HAVE_DILITHIUM */ +#endif /* HAVE_PQC */ + + (void)idx; + (void)keySz; + (void)length; exit_dapk: if (ret != 0) { @@ -28313,7 +28710,7 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length) return ret; } -#endif /* HAVE_PQC && WOLFSSL_DUAL_ALG_CERTS */ +#endif /* WOLFSSL_DUAL_ALG_CERTS */ #endif /* WOLFSSL_TLS13 || !NO_WOLFSSL_CLIENT */ #if defined(WOLFSSL_TLS13) && !defined(WOLFSSL_NO_TLS12) @@ -28384,7 +28781,7 @@ static int SigAlgoCachesMsgs(int sigAlgo) } static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, - const byte* data, int sz, byte sigAlgo) + const byte* data, word32 sz, byte sigAlgo) { int ret = 0; int digest_sz = wc_HashGetDigestSize(hashType); @@ -28394,11 +28791,16 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, } if (ret == 0) { + word32 new_size = SEED_LEN; /* buffer for signature */ - ssl->buffers.sig.buffer = (byte*)XMALLOC(SEED_LEN + sz, ssl->heap, - DYNAMIC_TYPE_SIGNATURE); - if (ssl->buffers.sig.buffer == NULL) { + if (! WC_SAFE_SUM_WORD32(new_size, sz, new_size)) ret = MEMORY_E; + else { + ssl->buffers.sig.buffer = (byte*)XMALLOC(new_size, ssl->heap, + DYNAMIC_TYPE_SIGNATURE); + if (ssl->buffers.sig.buffer == NULL) { + ret = MEMORY_E; + } } } if (ret == 0) { @@ -28477,7 +28879,7 @@ static int HashSkeData(WOLFSSL* ssl, enum wc_HashType hashType, int sendSz; int idSz; int ret; - word16 extSz = 0; + word32 extSz = 0; const Suites* suites; if (ssl == NULL) { @@ -30434,14 +30836,14 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, ERROR_OUT(NOT_COMPILED_IN, exit_dske); #else enum wc_HashType hashType; - word16 verifySz; + word32 verifySz; byte sigAlgo; if (ssl->options.usingAnon_cipher) { break; } - verifySz = (word16)(args->idx - args->begin); + verifySz = (args->idx - args->begin); if (verifySz > MAX_DH_SZ) { ERROR_OUT(BUFFER_ERROR, exit_dske); } @@ -32285,7 +32687,7 @@ typedef struct ScvArgs { word32 sigSz; int sendSz; int inputSz; - word16 length; + word32 length; byte sigAlgo; } ScvArgs; @@ -32504,7 +32906,7 @@ int SendCertificateVerify(WOLFSSL* ssl) } /* prepend hdr */ - c16toa(args->length, args->verify + args->extraSz); + c16toa((word16)args->length, args->verify + args->extraSz); } #ifdef WC_RSA_PSS else if (args->sigAlgo == rsa_pss_sa_algo) { @@ -32514,7 +32916,7 @@ int SendCertificateVerify(WOLFSSL* ssl) args->sigSz = ENCRYPT_LEN; /* prepend hdr */ - c16toa(args->length, args->verify + args->extraSz); + c16toa((word16)args->length, args->verify + args->extraSz); } #endif #endif /* !NO_RSA */ @@ -32693,7 +33095,7 @@ int SendCertificateVerify(WOLFSSL* ssl) #endif args->length = (word16)ssl->buffers.sig.length; /* prepend hdr */ - c16toa(args->length, args->verify + args->extraSz); + c16toa((word16)args->length, args->verify + args->extraSz); XMEMCPY(args->verify + args->extraSz + VERIFY_HEADER, ssl->buffers.sig.buffer, ssl->buffers.sig.length); break; @@ -33377,7 +33779,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) word32 exportSz; #endif - int sendSz; + word32 sendSz; int inputSz; } SskeArgs; @@ -34111,7 +34513,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif case rsa_sa_algo: { - word16 keySz; + word32 keySz; ssl->buffers.keyType = rsa_sa_algo; ret = DecodePrivateKey(ssl, &keySz); @@ -34129,7 +34531,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif case ecc_dsa_sa_algo: { - word16 keySz; + word32 keySz; ssl->buffers.keyType = ecc_dsa_sa_algo; ret = DecodePrivateKey(ssl, &keySz); @@ -34144,7 +34546,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef HAVE_ED25519 case ed25519_sa_algo: { - word16 keySz; + word32 keySz; ssl->buffers.keyType = ed25519_sa_algo; ret = DecodePrivateKey(ssl, &keySz); @@ -34160,7 +34562,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef HAVE_ED448 case ed448_sa_algo: { - word16 keySz; + word32 keySz; ssl->buffers.keyType = ed448_sa_algo; ret = DecodePrivateKey(ssl, &keySz); @@ -34363,7 +34765,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, preSigSz = args->length; if (!ssl->options.usingAnon_cipher) { - word16 keySz = 0; + word32 keySz = 0; /* sig length */ args->length += LENGTH_SZ; @@ -38611,7 +39013,7 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], #ifndef NO_RSA case rsa_kea: { - word16 keySz; + word32 keySz; ssl->buffers.keyType = rsa_sa_algo; ret = DecodePrivateKey(ssl, &keySz); @@ -38731,7 +39133,7 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], if (ssl->specs.static_ecdh && ssl->ecdhCurveOID != ECC_X25519_OID && ssl->ecdhCurveOID != ECC_X448_OID) { - word16 keySz; + word32 keySz; ssl->buffers.keyType = ecc_dsa_sa_algo; ret = DecodePrivateKey(ssl, &keySz); diff --git a/src/ssl.c b/src/ssl.c index ea66e429eb..b19b2c7f21 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -122,6 +122,9 @@ #if defined(HAVE_DILITHIUM) #include #endif /* HAVE_DILITHIUM */ + #if defined(HAVE_SPHINCS) + #include + #endif /* HAVE_SPHINCS */ #endif /* HAVE_PQC */ #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) #ifdef HAVE_OCSP @@ -5919,8 +5922,19 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) } #ifdef WOLFSSL_DUAL_ALG_CERTS - signer->sapkiDer = cert->sapkiDer; - signer->sapkiLen = cert->sapkiLen; + if (cert->extSapkiSet && cert->sapkiLen > 0) { + /* Allocated space for alternative public key. */ + signer->sapkiDer = (byte*)XMALLOC(cert->sapkiLen, cm->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (signer->sapkiDer == NULL) { + ret = MEMORY_E; + } + else { + XMEMCPY(signer->sapkiDer, cert->sapkiDer, cert->sapkiLen); + signer->sapkiLen = cert->sapkiLen; + signer->sapkiOID = cert->sapkiOID; + } + } #endif /* WOLFSSL_DUAL_ALG_CERTS */ if (cert->subjectCNStored) { @@ -6518,11 +6532,12 @@ static int ProcessUserChain(WOLFSSL_CTX* ctx, const unsigned char* buff, (HAVE_FIPS_VERSION > 2)) static int ProcessBufferTryDecodeRsa(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der, int* keySz, word32* idx, int* resetSuites, int* keyFormat, - int devId) + int devId, int type) { int ret; (void)devId; + (void)type; *idx = 0; ret = wc_RsaPrivateKeyValidate(der->buffer, idx, keySz, der->length); @@ -6566,12 +6581,30 @@ static int ProcessBufferTryDecodeRsa(WOLFSSL_CTX* ctx, WOLFSSL* ssl, } if (ssl) { - ssl->buffers.keyType = rsa_sa_algo; - ssl->buffers.keySz = *keySz; + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (type == ALT_PRIVATEKEY_TYPE) { + ssl->buffers.altKeyType = rsa_sa_algo; + ssl->buffers.altKeySz = *keySz; + } + else + #endif /* WOLFSSL_DUAL_ALG_CERTS */ + { + ssl->buffers.keyType = rsa_sa_algo; + ssl->buffers.keySz = *keySz; + } } else { - ctx->privateKeyType = rsa_sa_algo; - ctx->privateKeySz = *keySz; + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (type == ALT_PRIVATEKEY_TYPE) { + ctx->altPrivateKeyType = rsa_sa_algo; + ctx->altPrivateKeySz = *keySz; + } + else + #endif /* WOLFSSL_DUAL_ALG_CERTS */ + { + ctx->privateKeyType = rsa_sa_algo; + ctx->privateKeySz = *keySz; + } } *keyFormat = RSAk; @@ -6587,10 +6620,12 @@ static int ProcessBufferTryDecodeRsa(WOLFSSL_CTX* ctx, WOLFSSL* ssl, #else static int ProcessBufferTryDecodeRsa(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der, int* keySz, word32* idx, int* resetSuites, int* keyFormat, - void* heap, int devId) + void* heap, int devId, int type) { int ret; + (void)type; + /* make sure RSA key can be used */ #ifdef WOLFSSL_SMALL_STACK RsaKey* key; @@ -6643,12 +6678,30 @@ static int ProcessBufferTryDecodeRsa(WOLFSSL_CTX* ctx, WOLFSSL* ssl, } if (ssl) { - ssl->buffers.keyType = rsa_sa_algo; - ssl->buffers.keySz = *keySz; + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (type == ALT_PRIVATEKEY_TYPE) { + ssl->buffers.altKeyType = rsa_sa_algo; + ssl->buffers.altKeySz = *keySz; + } + else + #endif /* WOLFSSL_DUAL_ALG_CERTS */ + { + ssl->buffers.keyType = rsa_sa_algo; + ssl->buffers.keySz = *keySz; + } } else { - ctx->privateKeyType = rsa_sa_algo; - ctx->privateKeySz = *keySz; + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (type == ALT_PRIVATEKEY_TYPE) { + ctx->altPrivateKeyType = rsa_sa_algo; + ctx->altPrivateKeySz = *keySz; + } + else + #endif /* WOLFSSL_DUAL_ALG_CERTS */ + { + ctx->privateKeyType = rsa_sa_algo; + ctx->privateKeySz = *keySz; + } } *keyFormat = RSAk; @@ -6674,7 +6727,7 @@ static int ProcessBufferTryDecodeRsa(WOLFSSL_CTX* ctx, WOLFSSL* ssl, #ifdef HAVE_ECC static int ProcessBufferTryDecodeEcc(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der, int* keySz, word32* idx, int* resetSuites, int* keyFormat, - void* heap, int devId) + void* heap, int devId, int type) { int ret = 0; /* make sure ECC key can be used */ @@ -6684,6 +6737,8 @@ static int ProcessBufferTryDecodeEcc(WOLFSSL_CTX* ctx, WOLFSSL* ssl, ecc_key key[1]; #endif + (void)type; + #ifdef WOLFSSL_SMALL_STACK key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC); if (key == NULL) @@ -6716,26 +6771,42 @@ static int ProcessBufferTryDecodeEcc(WOLFSSL_CTX* ctx, WOLFSSL* ssl, *keyFormat = ECDSAk; if (ssl) { - ssl->options.haveStaticECC = 1; - ssl->buffers.keyType = ecc_dsa_sa_algo; - #ifdef WOLFSSL_SM2 - if (key->dp->id == ECC_SM2P256V1) - ssl->buffers.keyType = sm2_sa_algo; + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (type == ALT_PRIVATEKEY_TYPE) { + ssl->buffers.altKeyType = ecc_dsa_sa_algo; + ssl->buffers.altKeySz = *keySz; + } else - #endif - ssl->buffers.keyType = ecc_dsa_sa_algo; - ssl->buffers.keySz = *keySz; + #endif /* WOLFSSL_DUAL_ALG_CERTS */ + { + ssl->options.haveStaticECC = 1; + #ifdef WOLFSSL_SM2 + if (key->dp->id == ECC_SM2P256V1) + ssl->buffers.keyType = sm2_sa_algo; + else + #endif + ssl->buffers.keyType = ecc_dsa_sa_algo; + ssl->buffers.keySz = *keySz; + } } else { - ctx->haveStaticECC = 1; - ctx->privateKeyType = ecc_dsa_sa_algo; - #ifdef WOLFSSL_SM2 - if (key->dp->id == ECC_SM2P256V1) - ctx->privateKeyType = sm2_sa_algo; + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (type == ALT_PRIVATEKEY_TYPE) { + ctx->altPrivateKeyType = ecc_dsa_sa_algo; + ctx->altPrivateKeySz = *keySz; + } else - #endif - ctx->privateKeyType = ecc_dsa_sa_algo; - ctx->privateKeySz = *keySz; + #endif /* WOLFSSL_DUAL_ALG_CERTS */ + { + ctx->haveStaticECC = 1; + #ifdef WOLFSSL_SM2 + if (key->dp->id == ECC_SM2P256V1) + ctx->privateKeyType = sm2_sa_algo; + else + #endif + ctx->privateKeyType = ecc_dsa_sa_algo; + ctx->privateKeySz = *keySz; + } } if (ssl && ssl->options.side == WOLFSSL_SERVER_END) { @@ -6952,7 +7023,7 @@ static int ProcessBufferTryDecodeFalcon(WOLFSSL_CTX* ctx, WOLFSSL* ssl, /* check for minimum key size and then free */ int minKeySz = ssl ? ssl->options.minFalconKeySz : ctx->minFalconKeySz; - *keySz = FALCON_MAX_KEY_SIZE; + *keySz = wc_falcon_size(key); if (*keySz < minKeySz) { WOLFSSL_MSG("Falcon private key too small"); ret = FALCON_KEY_SIZE_E; @@ -7058,7 +7129,7 @@ static int ProcessBufferTryDecodeDilithium(WOLFSSL_CTX* ctx, WOLFSSL* ssl, /* check for minimum key size and then free */ int minKeySz = ssl ? ssl->options.minDilithiumKeySz : ctx->minDilithiumKeySz; - *keySz = DILITHIUM_MAX_KEY_SIZE; + *keySz = wc_dilithium_size(key); if (*keySz < minKeySz) { WOLFSSL_MSG("Dilithium private key too small"); ret = DILITHIUM_KEY_SIZE_E; @@ -7159,10 +7230,10 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, #if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) && \ (HAVE_FIPS_VERSION > 2)) ret = ProcessBufferTryDecodeRsa(ctx, ssl, der, keySz, idx, resetSuites, - keyFormat, devId); + keyFormat, devId, type); #else ret = ProcessBufferTryDecodeRsa(ctx, ssl, der, keySz, idx, resetSuites, - keyFormat, heap, devId); + keyFormat, heap, devId, type); #endif if (ret != 0) return ret; @@ -7175,7 +7246,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, #endif ) { ret = ProcessBufferTryDecodeEcc(ctx, ssl, der, keySz, idx, resetSuites, - keyFormat, heap, devId); + keyFormat, heap, devId, type); if (ret != 0) return ret; } @@ -7428,6 +7499,9 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, ForceZero(ssl->buffers.key->buffer, ssl->buffers.key->length); FreeDer(&ssl->buffers.key); } + ssl->buffers.keyId = 0; + ssl->buffers.keyLabel = 0; + ssl->buffers.keyDevId = INVALID_DEVID; ssl->buffers.key = der; #ifdef WOLFSSL_CHECK_MEM_ZERO wc_MemZero_Add("SSL Buffers key", der->buffer, der->length); @@ -7439,6 +7513,9 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, ForceZero(ctx->privateKey->buffer, ctx->privateKey->length); } FreeDer(&ctx->privateKey); + ctx->privateKeyId = 0; + ctx->privateKeyLabel = 0; + ctx->privateKeyDevId = INVALID_DEVID; ctx->privateKey = der; #ifdef WOLFSSL_CHECK_MEM_ZERO wc_MemZero_Add("CTX private key", der->buffer, der->length); @@ -7454,6 +7531,9 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, ssl->buffers.altKey->length); FreeDer(&ssl->buffers.altKey); } + ssl->buffers.altKeyId = 0; + ssl->buffers.altKeyLabel = 0; + ssl->buffers.altKeyDevId = INVALID_DEVID; ssl->buffers.altKey = der; #ifdef WOLFSSL_CHECK_MEM_ZERO wc_MemZero_Add("SSL Buffers key", der->buffer, der->length); @@ -7467,6 +7547,9 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, ctx->altPrivateKey->length); } FreeDer(&ctx->altPrivateKey); + ctx->altPrivateKeyId = 0; + ctx->altPrivateKeyLabel = 0; + ctx->altPrivateKeyDevId = INVALID_DEVID; ctx->altPrivateKey = der; #ifdef WOLFSSL_CHECK_MEM_ZERO wc_MemZero_Add("CTX private key", der->buffer, der->length); @@ -7570,9 +7653,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #else DecodedCert cert[1]; #endif - #ifdef WOLF_PRIVATE_KEY_ID int keyType = 0; - #endif #ifdef WOLFSSL_SMALL_STACK cert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap, @@ -7773,9 +7854,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, case RSAPSSk: #endif case RSAk: - #ifdef WOLF_PRIVATE_KEY_ID keyType = rsa_sa_algo; - #endif /* Determine RSA key size by parsing public key */ idx = 0; ret = wc_RsaPublicKeyDecode_ex(cert->publicKey, &idx, @@ -7803,9 +7882,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #endif /* !NO_RSA */ #ifdef HAVE_ECC case ECDSAk: - #ifdef WOLF_PRIVATE_KEY_ID keyType = ecc_dsa_sa_algo; - #endif /* Determine ECC key size based on curve */ #ifdef WOLFSSL_CUSTOM_CURVES if (cert->pkCurveOID == 0 && cert->pkCurveSize != 0) { @@ -7836,9 +7913,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #endif /* HAVE_ECC */ #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) case SM2k: - #ifdef WOLF_PRIVATE_KEY_ID keyType = sm2_sa_algo; - #endif /* Determine ECC key size based on curve */ keySz = wc_ecc_get_curve_size_from_id( wc_ecc_get_oid(cert->pkCurveOID, NULL, NULL)); @@ -7860,9 +7935,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #endif /* HAVE_ED25519 */ #ifdef HAVE_ED25519 case ED25519k: - #ifdef WOLF_PRIVATE_KEY_ID keyType = ed25519_sa_algo; - #endif /* ED25519 is fixed key size */ keySz = ED25519_KEY_SIZE; if (ssl && !ssl->options.verifyNone) { @@ -7883,9 +7956,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #endif /* HAVE_ED25519 */ #ifdef HAVE_ED448 case ED448k: - #ifdef WOLF_PRIVATE_KEY_ID keyType = ed448_sa_algo; - #endif /* ED448 is fixed key size */ keySz = ED448_KEY_SIZE; if (ssl && !ssl->options.verifyNone) { @@ -7907,12 +7978,28 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #if defined(HAVE_PQC) #if defined(HAVE_FALCON) case FALCON_LEVEL1k: + keyType = falcon_level1_sa_algo; + /* Falcon is fixed key size */ + keySz = FALCON_LEVEL1_KEY_SIZE; + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minFalconKeySz < 0 || + keySz < (int)ssl->options.minFalconKeySz) { + ret = FALCON_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Falcon key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minFalconKeySz < 0 || + keySz < (int)ctx->minFalconKeySz) { + ret = FALCON_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Falcon key size error"); + } + } + break; case FALCON_LEVEL5k: - #ifdef WOLF_PRIVATE_KEY_ID keyType = falcon_level5_sa_algo; - #endif /* Falcon is fixed key size */ - keySz = FALCON_MAX_KEY_SIZE; + keySz = FALCON_LEVEL5_KEY_SIZE; if (ssl && !ssl->options.verifyNone) { if (ssl->options.minFalconKeySz < 0 || keySz < (int)ssl->options.minFalconKeySz) { @@ -7931,13 +8018,47 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) case DILITHIUM_LEVEL2k: + keyType = dilithium_level2_sa_algo; + /* Dilithium is fixed key size */ + keySz = DILITHIUM_LEVEL2_KEY_SIZE; + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minDilithiumKeySz < 0 || + keySz < (int)ssl->options.minDilithiumKeySz) { + ret = DILITHIUM_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Dilithium key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minDilithiumKeySz < 0 || + keySz < (int)ctx->minDilithiumKeySz) { + ret = DILITHIUM_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Dilithium key size error"); + } + } + break; case DILITHIUM_LEVEL3k: + keyType = dilithium_level3_sa_algo; + /* Dilithium is fixed key size */ + keySz = DILITHIUM_LEVEL3_KEY_SIZE; + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minDilithiumKeySz < 0 || + keySz < (int)ssl->options.minDilithiumKeySz) { + ret = DILITHIUM_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Dilithium key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minDilithiumKeySz < 0 || + keySz < (int)ctx->minDilithiumKeySz) { + ret = DILITHIUM_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Dilithium key size error"); + } + } + break; case DILITHIUM_LEVEL5k: - #ifdef WOLF_PRIVATE_KEY_ID keyType = dilithium_level5_sa_algo; - #endif /* Dilithium is fixed key size */ - keySz = DILITHIUM_MAX_KEY_SIZE; + keySz = DILITHIUM_LEVEL5_KEY_SIZE; if (ssl && !ssl->options.verifyNone) { if (ssl->options.minDilithiumKeySz < 0 || keySz < (int)ssl->options.minDilithiumKeySz) { @@ -7961,7 +8082,6 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, break; /* do no check if not a case for the key */ } - #ifdef WOLF_PRIVATE_KEY_ID if (ssl != NULL) { ssl->buffers.keyType = (byte)keyType; ssl->buffers.keySz = keySz; @@ -7970,7 +8090,283 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, ctx->privateKeyType = (byte)keyType; ctx->privateKeySz = keySz; } - #endif + + #ifdef WOLFSSL_DUAL_ALG_CERTS + keyType = 0; + keySz = 0; + /* check alternative key size of cert */ + switch (cert->sapkiOID) { + case 0: + if (cert->sapkiLen != 0) + ret = NOT_COMPILED_IN; + break; + #ifndef NO_RSA + #ifdef WC_RSA_PSS + case RSAPSSk: + #endif + case RSAk: + keyType = rsa_sa_algo; + /* Determine RSA key size by parsing public key */ + idx = 0; + ret = wc_RsaPublicKeyDecode_ex(cert->sapkiDer, &idx, + cert->sapkiLen, NULL, (word32*)&keySz, NULL, NULL); + if (ret < 0) + break; + + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minRsaKeySz < 0 || + keySz < (int)ssl->options.minRsaKeySz || + keySz > (RSA_MAX_SIZE / 8)) { + ret = RSA_KEY_SIZE_E; + WOLFSSL_MSG("Certificate RSA key size too small"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minRsaKeySz < 0 || + keySz < (int)ctx->minRsaKeySz || + keySz > (RSA_MAX_SIZE / 8)) { + ret = RSA_KEY_SIZE_E; + WOLFSSL_MSG("Certificate RSA key size too small"); + } + } + break; + #endif /* !NO_RSA */ + #ifdef HAVE_ECC + case ECDSAk: + { + #ifdef WOLFSSL_SMALL_STACK + ecc_key* temp_key = NULL; + #else + ecc_key temp_key[1]; + #endif + keyType = ecc_dsa_sa_algo; + + #ifdef WOLFSSL_SMALL_STACK + temp_key = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, + DYNAMIC_TYPE_ECC); + if (temp_key == NULL) + ret = MEMORY_E; + #endif + + /* Determine ECC key size. We have to decode the sapki for + * that. */ + if (ret == 0) { + ret = wc_ecc_init_ex(temp_key, heap, INVALID_DEVID); + } + if (ret == 0) { + idx = 0; + ret = wc_EccPublicKeyDecode(cert->sapkiDer, &idx, temp_key, + cert->sapkiLen); + } + if (ret == 0) { + keySz = wc_ecc_size(temp_key); + } + wc_ecc_free(temp_key); + #ifdef WOLFSSL_SMALL_STACK + XFREE(temp_key, heap, DYNAMIC_TYPE_ECC); + #endif + + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minEccKeySz < 0 || + keySz < (int)ssl->options.minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("Certificate ECC key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minEccKeySz < 0 || + keySz < (int)ctx->minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("Certificate ECC key size error"); + } + } + break; + } + #endif /* HAVE_ECC */ + #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) + case SM2k: + keyType = sm2_sa_algo; + /* Determine ECC key size based on curve */ + keySz = wc_ecc_get_curve_size_from_id( + wc_ecc_get_oid(cert->pkCurveOID, NULL, NULL)); + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minEccKeySz < 0 || + keySz < (int)ssl->options.minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Ed key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minEccKeySz < 0 || + keySz < (int)ctx->minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("Certificate ECC key size error"); + } + } + break; + #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED25519 + case ED25519k: + keyType = ed25519_sa_algo; + /* ED25519 is fixed key size */ + keySz = ED25519_KEY_SIZE; + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minEccKeySz < 0 || + keySz < (int)ssl->options.minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Ed key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minEccKeySz < 0 || + keySz < (int)ctx->minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("Certificate ECC key size error"); + } + } + break; + #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + case ED448k: + keyType = ed448_sa_algo; + /* ED448 is fixed key size */ + keySz = ED448_KEY_SIZE; + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minEccKeySz < 0 || + keySz < (int)ssl->options.minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Ed key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minEccKeySz < 0 || + keySz < (int)ctx->minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("Certificate ECC key size error"); + } + } + break; + #endif /* HAVE_ED448 */ + #if defined(HAVE_PQC) + #if defined(HAVE_FALCON) + case FALCON_LEVEL1k: + keyType = falcon_level1_sa_algo; + /* Falcon is fixed key size */ + keySz = FALCON_LEVEL1_KEY_SIZE; + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minFalconKeySz < 0 || + keySz < (int)ssl->options.minFalconKeySz) { + ret = FALCON_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Falcon key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minFalconKeySz < 0 || + keySz < (int)ctx->minFalconKeySz) { + ret = FALCON_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Falcon key size error"); + } + } + break; + case FALCON_LEVEL5k: + keyType = falcon_level5_sa_algo; + /* Falcon is fixed key size */ + keySz = FALCON_LEVEL5_KEY_SIZE; + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minFalconKeySz < 0 || + keySz < (int)ssl->options.minFalconKeySz) { + ret = FALCON_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Falcon key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minFalconKeySz < 0 || + keySz < (int)ctx->minFalconKeySz) { + ret = FALCON_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Falcon key size error"); + } + } + break; + #endif /* HAVE_FALCON */ + #if defined(HAVE_DILITHIUM) + case DILITHIUM_LEVEL2k: + keyType = dilithium_level2_sa_algo; + /* Dilithium is fixed key size */ + keySz = DILITHIUM_LEVEL2_KEY_SIZE; + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minDilithiumKeySz < 0 || + keySz < (int)ssl->options.minDilithiumKeySz) { + ret = DILITHIUM_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Dilithium key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minDilithiumKeySz < 0 || + keySz < (int)ctx->minDilithiumKeySz) { + ret = DILITHIUM_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Dilithium key size error"); + } + } + break; + case DILITHIUM_LEVEL3k: + keyType = dilithium_level3_sa_algo; + /* Dilithium is fixed key size */ + keySz = DILITHIUM_LEVEL3_KEY_SIZE; + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minDilithiumKeySz < 0 || + keySz < (int)ssl->options.minDilithiumKeySz) { + ret = DILITHIUM_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Dilithium key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minDilithiumKeySz < 0 || + keySz < (int)ctx->minDilithiumKeySz) { + ret = DILITHIUM_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Dilithium key size error"); + } + } + break; + case DILITHIUM_LEVEL5k: + keyType = dilithium_level5_sa_algo; + /* Dilithium is fixed key size */ + keySz = DILITHIUM_LEVEL5_KEY_SIZE; + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minDilithiumKeySz < 0 || + keySz < (int)ssl->options.minDilithiumKeySz) { + ret = DILITHIUM_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Dilithium key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minDilithiumKeySz < 0 || + keySz < (int)ctx->minDilithiumKeySz) { + ret = DILITHIUM_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Dilithium key size error"); + } + } + break; + #endif /* HAVE_DILITHIUM */ + #endif /* HAVE_PQC */ + + default: + /* In this case, there was an OID that we didn't recognize. + * This is an error. Use not compiled in because likely the + * given algorithm was not enabled. */ + ret = NOT_COMPILED_IN; + WOLFSSL_MSG("No alt key size check done on certificate"); + break; + } + + if (ssl != NULL) { + ssl->buffers.altKeyType = (byte)keyType; + ssl->buffers.altKeySz = keySz; + } + else if (ctx != NULL) { + ctx->altPrivateKeyType = (byte)keyType; + ctx->altPrivateKeySz = keySz; + } + #endif /* WOLFSSL_DUAL_ALG_CERTS */ FreeDecodedCert(cert); #ifdef WOLFSSL_SMALL_STACK @@ -8399,6 +8795,25 @@ int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type, #ifdef HAVE_CRL else if (type == CRL_TYPE) ret = BufferLoadCRL(crl, myBuffer, sz, format, verify); +#endif +#ifdef WOLFSSL_DUAL_ALG_CERTS + else if (type == PRIVATEKEY_TYPE) + { + /* When support for dual algorithm certificates is enabled, the + * private key file may contain both the primary and the + * alternative private key. Hence, we have to parse both of them. + */ + long consumed = 0; + + ret = ProcessBuffer(ctx, myBuffer, sz, format, PRIVATEKEY_TYPE, + ssl, &consumed, 0, verify); + + if (ret == WOLFSSL_SUCCESS && consumed < sz) { + ret = ProcessBuffer(ctx, myBuffer + consumed, sz - consumed, + format, ALT_PRIVATEKEY_TYPE, ssl, NULL, 0, + verify); + } + } #endif else ret = ProcessBuffer(ctx, myBuffer, sz, format, type, ssl, NULL, @@ -9182,52 +9597,174 @@ static int wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl, XFCLOSE(file); return WOLFSSL_BAD_FILE; } - dynamic = 1; - } - - if ((size_t)XFREAD(myBuffer, 1, sz, file) != (size_t)sz) - ret = WOLFSSL_BAD_FILE; - else { - if (ssl) - ret = wolfSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format); - else - ret = wolfSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format); + dynamic = 1; + } + + if ((size_t)XFREAD(myBuffer, 1, sz, file) != (size_t)sz) + ret = WOLFSSL_BAD_FILE; + else { + if (ssl) + ret = wolfSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format); + else + ret = wolfSSL_CTX_SetTmpDH_buffer(ctx, myBuffer, sz, format); + } + + XFCLOSE(file); + if (dynamic) + XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE); + + return ret; +} + +/* server Diffie-Hellman parameters */ +int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* fname, int format) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + + return wolfSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format); +} + + +/* server Diffie-Hellman parameters */ +int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format) +{ + return wolfSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format); +} + +#endif /* NO_DH */ + +#endif /* NO_FILESYSTEM */ + +#ifndef NO_CHECK_PRIVATE_KEY + +#ifdef WOLF_PRIVATE_KEY_ID +/* Check private against public in certificate for match using external + * device with given devId */ +static int check_cert_key_dev(word32 keyOID, byte* privKey, word32 privSz, + const byte* pubKey, word32 pubSz, int label, int id, void* heap, int devId) +{ + int ret = 0; + int type = 0; + void *pkey = NULL; + + if (privKey == NULL) { + return MISSING_KEY; + } + +#ifndef NO_RSA + if (keyOID == RSAk) { + type = DYNAMIC_TYPE_RSA; + } +#ifdef WC_RSA_PSS + if (keyOID == RSAPSSk) { + type = DYNAMIC_TYPE_RSA; + } +#endif +#endif +#ifdef HAVE_ECC + if (keyOID == ECDSAk) { + type = DYNAMIC_TYPE_ECC; + } +#endif +#if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + if ((keyOID == DILITHIUM_LEVEL2k) || + (keyOID == DILITHIUM_LEVEL3k) || + (keyOID == DILITHIUM_LEVEL5k)) { + type = DYNAMIC_TYPE_DILITHIUM; + } +#endif +#if defined(HAVE_PQC) && defined(HAVE_FALCON) + if ((keyOID == FALCON_LEVEL1k) || + (keyOID == FALCON_LEVEL5k)) { + type = DYNAMIC_TYPE_FALCON; + } +#endif + + ret = CreateDevPrivateKey(&pkey, privKey, privSz, type, label, id, + heap, devId); + #ifdef WOLF_CRYPTO_CB + if (ret == 0) { + #ifndef NO_RSA + if (keyOID == RSAk + #ifdef WC_RSA_PSS + || keyOID == RSAPSSk + #endif + ) { + ret = wc_CryptoCb_RsaCheckPrivKey((RsaKey*)pkey, pubKey, pubSz); + } + #endif + #ifdef HAVE_ECC + if (keyOID == ECDSAk) { + ret = wc_CryptoCb_EccCheckPrivKey((ecc_key*)pkey, pubKey, pubSz); + } + #endif + #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + if ((keyOID == DILITHIUM_LEVEL2k) || + (keyOID == DILITHIUM_LEVEL3k) || + (keyOID == DILITHIUM_LEVEL5k)) { + ret = wc_CryptoCb_PqcSignatureCheckPrivKey(pkey, + WC_PQC_SIG_TYPE_DILITHIUM, + pubKey, pubSz); + } + #endif + #if defined(HAVE_PQC) && defined(HAVE_FALCON) + if ((keyOID == FALCON_LEVEL1k) || + (keyOID == FALCON_LEVEL5k)) { + ret = wc_CryptoCb_PqcSignatureCheckPrivKey(pkey, + WC_PQC_SIG_TYPE_FALCON, + pubKey, pubSz); + } + #endif + } + #else + /* devId was set, don't check, for now */ + /* TODO: Add callback for private key check? */ + (void) pubKey; + (void) pubSz; + #endif + if (pkey != NULL) { + #ifndef NO_RSA + if (keyOID == RSAk + #ifdef WC_RSA_PSS + || keyOID == RSAPSSk + #endif + ) { + wc_FreeRsaKey((RsaKey*)pkey); + } + #endif + #ifdef HAVE_ECC + if (keyOID == ECDSAk) { + wc_ecc_free((ecc_key*)pkey); + } + #endif + #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + if ((keyOID == DILITHIUM_LEVEL2k) || + (keyOID == DILITHIUM_LEVEL3k) || + (keyOID == DILITHIUM_LEVEL5k)) { + wc_dilithium_free((dilithium_key*)pkey); + } + #endif + #if defined(HAVE_PQC) && defined(HAVE_FALCON) + if ((keyOID == FALCON_LEVEL1k) || + (keyOID == FALCON_LEVEL5k)) { + wc_falcon_free((falcon_key*)pkey); + } + #endif + XFREE(pkey, heap, type); } - XFCLOSE(file); - if (dynamic) - XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE); - return ret; } +#endif /* WOLF_PRIVATE_KEY_ID */ -/* server Diffie-Hellman parameters */ -int wolfSSL_SetTmpDH_file(WOLFSSL* ssl, const char* fname, int format) -{ - if (ssl == NULL) - return BAD_FUNC_ARG; - - return wolfSSL_SetTmpDH_file_wrapper(ssl->ctx, ssl, fname, format); -} - - -/* server Diffie-Hellman parameters */ -int wolfSSL_CTX_SetTmpDH_file(WOLFSSL_CTX* ctx, const char* fname, int format) -{ - return wolfSSL_SetTmpDH_file_wrapper(ctx, NULL, fname, format); -} - -#endif /* NO_DH */ - -#endif /* NO_FILESYSTEM */ - -#ifndef NO_CHECK_PRIVATE_KEY /* Check private against public in certificate for match * * Returns WOLFSSL_SUCCESS on good private key * WOLFSSL_FAILURE if mismatched */ -static int check_cert_key(DerBuffer* cert, DerBuffer* key, void* heap, - int devId, int isKeyLabel, int isKeyId) +static int check_cert_key(DerBuffer* cert, DerBuffer* key, DerBuffer* altKey, + void* heap, int devId, int isKeyLabel, int isKeyId, int altDevId, + int isAltKeyLabel, int isAltKeyId) { #ifdef WOLFSSL_SMALL_STACK DecodedCert* der = NULL; @@ -9245,7 +9782,7 @@ static int check_cert_key(DerBuffer* cert, DerBuffer* key, void* heap, } #ifdef WOLFSSL_SMALL_STACK - der = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT); + der = (DecodedCert*)XMALLOC(sizeof(DecodedCert), heap, DYNAMIC_TYPE_DCERT); if (der == NULL) return MEMORY_E; #endif @@ -9256,7 +9793,7 @@ static int check_cert_key(DerBuffer* cert, DerBuffer* key, void* heap, if (ParseCertRelative(der, CERT_TYPE, NO_VERIFY, NULL) != 0) { FreeDecodedCert(der); #ifdef WOLFSSL_SMALL_STACK - XFREE(der, NULL, DYNAMIC_TYPE_DCERT); + XFREE(der, heap, DYNAMIC_TYPE_DCERT); #endif return WOLFSSL_FAILURE; } @@ -9265,110 +9802,9 @@ static int check_cert_key(DerBuffer* cert, DerBuffer* key, void* heap, buff = key->buffer; #ifdef WOLF_PRIVATE_KEY_ID if (devId != INVALID_DEVID) { - int type = 0; - void *pkey = NULL; - - #ifndef NO_RSA - if (der->keyOID == RSAk) { - type = DYNAMIC_TYPE_RSA; - } - #ifdef WC_RSA_PSS - if (der->keyOID == RSAPSSk) { - type = DYNAMIC_TYPE_RSA; - } - #endif - #endif - #ifdef HAVE_ECC - if (der->keyOID == ECDSAk) { - type = DYNAMIC_TYPE_ECC; - } - #endif - #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) - if ((der->keyOID == DILITHIUM_LEVEL2k) || - (der->keyOID == DILITHIUM_LEVEL3k) || - (der->keyOID == DILITHIUM_LEVEL5k)) { - type = DYNAMIC_TYPE_DILITHIUM; - } - #endif - #if defined(HAVE_PQC) && defined(HAVE_FALCON) - if ((der->keyOID == FALCON_LEVEL1k) || - (der->keyOID == FALCON_LEVEL5k)) { - type = DYNAMIC_TYPE_FALCON; - } - #endif - - ret = CreateDevPrivateKey(&pkey, buff, size, type, - isKeyLabel, isKeyId, heap, devId); - #ifdef WOLF_CRYPTO_CB - if (ret == 0) { - #ifndef NO_RSA - if (der->keyOID == RSAk - #ifdef WC_RSA_PSS - || der->keyOID == RSAPSSk - #endif - ) { - ret = wc_CryptoCb_RsaCheckPrivKey((RsaKey*)pkey, - der->publicKey, der->pubKeySize); - } - #endif - #ifdef HAVE_ECC - if (der->keyOID == ECDSAk) { - ret = wc_CryptoCb_EccCheckPrivKey((ecc_key*)pkey, - der->publicKey, der->pubKeySize); - } - #endif - #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) - if ((der->keyOID == DILITHIUM_LEVEL2k) || - (der->keyOID == DILITHIUM_LEVEL3k) || - (der->keyOID == DILITHIUM_LEVEL5k)) { - ret = wc_CryptoCb_PqcSignatureCheckPrivKey(pkey, - WC_PQC_SIG_TYPE_DILITHIUM, - der->publicKey, der->pubKeySize); - } - #endif - #if defined(HAVE_PQC) && defined(HAVE_FALCON) - if ((der->keyOID == FALCON_LEVEL1k) || - (der->keyOID == FALCON_LEVEL5k)) { - ret = wc_CryptoCb_PqcSignatureCheckPrivKey(pkey, - WC_PQC_SIG_TYPE_FALCON, - der->publicKey, der->pubKeySize); - } - #endif - } - #else - /* devId was set, don't check, for now */ - /* TODO: Add callback for private key check? */ - #endif - if (pkey != NULL) { - #ifndef NO_RSA - if (der->keyOID == RSAk - #ifdef WC_RSA_PSS - || der->keyOID == RSAPSSk - #endif - ) { - wc_FreeRsaKey((RsaKey*)pkey); - } - #endif - #ifdef HAVE_ECC - if (der->keyOID == ECDSAk) { - wc_ecc_free((ecc_key*)pkey); - } - #endif - #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) - if ((der->keyOID == DILITHIUM_LEVEL2k) || - (der->keyOID == DILITHIUM_LEVEL3k) || - (der->keyOID == DILITHIUM_LEVEL5k)) { - wc_dilithium_free((dilithium_key*)pkey); - } - #endif - #if defined(HAVE_PQC) && defined(HAVE_FALCON) - if ((der->keyOID == FALCON_LEVEL1k) || - (der->keyOID == FALCON_LEVEL5k)) { - wc_falcon_free((falcon_key*)pkey); - } - #endif - XFREE(pkey, heap, type); - } + ret = check_cert_key_dev(der->keyOID, buff, size, der->publicKey, + der->pubKeySize, isKeyLabel, isKeyId, heap, + devId); if (ret != CRYPTOCB_UNAVAILABLE) { ret = (ret == 0) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE; } @@ -9381,17 +9817,83 @@ static int check_cert_key(DerBuffer* cert, DerBuffer* key, void* heap, if (ret == CRYPTOCB_UNAVAILABLE) #endif /* WOLF_PRIVATE_KEY_ID */ { - ret = wc_CheckPrivateKeyCert(buff, size, der); + ret = wc_CheckPrivateKeyCert(buff, size, der, 0); ret = (ret == 1) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE; } + +#ifdef WOLFSSL_DUAL_ALG_CERTS + if (ret == WOLFSSL_SUCCESS && der->extSapkiSet && der->sapkiDer != NULL) { + /* Certificate contains an alternative public key. Hence, we also + * need an alternative private key. */ + if (altKey == NULL) { + ret = MISSING_KEY; + buff = NULL; + size = 0; + } + else { + size = altKey->length; + buff = altKey->buffer; + } +#ifdef WOLF_PRIVATE_KEY_ID + if (ret == WOLFSSL_SUCCESS && altDevId != INVALID_DEVID) { + /* We have to decode the public key first */ + word32 idx = 0; + /* Dilithium has the largest public key at the moment */ + word32 pubKeyLen = DILITHIUM_MAX_PUB_KEY_SIZE; + byte* decodedPubKey = (byte*)XMALLOC(pubKeyLen, heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (decodedPubKey == NULL) { + ret = MEMORY_E; + } + if (ret == WOLFSSL_SUCCESS) { + if (der->sapkiOID == RSAk || der->sapkiOID == ECDSAk) { + /* Simply copy the data */ + XMEMCPY(decodedPubKey, der->sapkiDer, der->sapkiLen); + pubKeyLen = der->sapkiLen; + ret = 0; + } + else { + ret = DecodeAsymKeyPublic(der->sapkiDer, &idx, + der->sapkiLen, decodedPubKey, + &pubKeyLen, der->sapkiOID); + } + } + if (ret == 0) { + ret = check_cert_key_dev(der->sapkiOID, buff, size, + decodedPubKey, pubKeyLen, + isAltKeyLabel, isAltKeyId, + heap, altDevId); + } + XFREE(decodedPubKey, heap, DYNAMIC_TYPE_PUBLIC_KEY); + if (ret != CRYPTOCB_UNAVAILABLE) { + ret = (ret == 0) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE; + } + } + else { + /* fall through if unavailable */ + ret = CRYPTOCB_UNAVAILABLE; + } + + if (ret == CRYPTOCB_UNAVAILABLE) +#endif /* WOLF_PRIVATE_KEY_ID */ + { + ret = wc_CheckPrivateKeyCert(buff, size, der, 1); + ret = (ret == 1) ? WOLFSSL_SUCCESS: WOLFSSL_FAILURE; + } + } +#endif /* WOLFSSL_DUAL_ALG_CERTS */ FreeDecodedCert(der); #ifdef WOLFSSL_SMALL_STACK - XFREE(der, NULL, DYNAMIC_TYPE_DCERT); + XFREE(der, heap, DYNAMIC_TYPE_DCERT); #endif (void)devId; (void)isKeyLabel; (void)isKeyId; + (void)altKey; + (void)altDevId; + (void)isAltKeyLabel; + (void)isAltKeyId; return ret; } @@ -9407,8 +9909,17 @@ int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx) if (ctx == NULL) { return WOLFSSL_FAILURE; } - return check_cert_key(ctx->certificate, ctx->privateKey, ctx->heap, - ctx->privateKeyDevId, ctx->privateKeyLabel, ctx->privateKeyId); + +#ifdef WOLFSSL_DUAL_ALG_CERTS + return check_cert_key(ctx->certificate, ctx->privateKey, ctx->altPrivateKey, + ctx->heap, ctx->privateKeyDevId, ctx->privateKeyLabel, + ctx->privateKeyId, ctx->altPrivateKeyDevId, ctx->altPrivateKeyLabel, + ctx->altPrivateKeyId); +#else + return check_cert_key(ctx->certificate, ctx->privateKey, NULL, ctx->heap, + ctx->privateKeyDevId, ctx->privateKeyLabel, ctx->privateKeyId, + INVALID_DEVID, 0, 0); +#endif } #endif /* !NO_CHECK_PRIVATE_KEY */ @@ -10440,8 +10951,16 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl) if (ssl == NULL) { return WOLFSSL_FAILURE; } - return check_cert_key(ssl->buffers.certificate, ssl->buffers.key, ssl->heap, - ssl->buffers.keyDevId, ssl->buffers.keyLabel, ssl->buffers.keyId); +#ifdef WOLFSSL_DUAL_ALG_CERTS + return check_cert_key(ssl->buffers.certificate, ssl->buffers.key, + ssl->buffers.altKey, ssl->heap, ssl->buffers.keyDevId, + ssl->buffers.keyLabel, ssl->buffers.keyId, ssl->buffers.altKeyDevId, + ssl->buffers.altKeyLabel, ssl->buffers.altKeyId); +#else + return check_cert_key(ssl->buffers.certificate, ssl->buffers.key, NULL, + ssl->heap, ssl->buffers.keyDevId, ssl->buffers.keyLabel, + ssl->buffers.keyId, INVALID_DEVID, 0, 0); +#endif } #endif /* !NO_CHECK_PRIVATE_KEY */ @@ -14429,7 +14948,7 @@ int wolfSSL_GetSessionFromCache(WOLFSSL* ssl, WOLFSSL_SESSION* output) XFREE(preallocNonce, output->heap, DYNAMIC_TYPE_SESSION_TICK); preallocNonce = NULL; #else - output->ticketNonce.data = XREALLOC(preallocNonce, + output->ticketNonce.data = (byte*)XREALLOC(preallocNonce, preallocNonceLen, output->heap, DYNAMIC_TYPE_SESSION_TICK); if (output->ticketNonce.data != NULL) { /* don't free the reallocated pointer */ @@ -16041,14 +16560,44 @@ int wolfSSL_set_compression(WOLFSSL* ssl) const unsigned char* in, long sz, int format) { int ret = WOLFSSL_FAILURE; + long consumed = 0; WOLFSSL_ENTER("wolfSSL_CTX_use_PrivateKey_buffer"); - ret = ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL, NULL, - 0, GET_VERIFY_SETTING_CTX(ctx)); + ret = ProcessBuffer(ctx, in, sz, format, PRIVATEKEY_TYPE, NULL, + &consumed, 0, GET_VERIFY_SETTING_CTX(ctx)); + + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ret == WOLFSSL_SUCCESS && consumed < sz) { + /* When support for dual algorithm certificates is enabled, the + * buffer may contain both the primary and the alternative + * private key. Hence, we have to parse both of them. + */ + ret = ProcessBuffer(ctx, in + consumed, sz - consumed, format, + ALT_PRIVATEKEY_TYPE, NULL, NULL, 0, + GET_VERIFY_SETTING_CTX(ctx)); + } + #endif + WOLFSSL_LEAVE("wolfSSL_CTX_use_PrivateKey_buffer", ret); return ret; } + +#ifdef WOLFSSL_DUAL_ALG_CERTS + int wolfSSL_CTX_use_AltPrivateKey_buffer(WOLFSSL_CTX* ctx, + const unsigned char* in, long sz, int format) + { + int ret = WOLFSSL_FAILURE; + + WOLFSSL_ENTER("wolfSSL_CTX_use_AltPrivateKey_buffer"); + ret = ProcessBuffer(ctx, in, sz, format, ALT_PRIVATEKEY_TYPE, NULL, + NULL, 0, GET_VERIFY_SETTING_CTX(ctx)); + WOLFSSL_LEAVE("wolfSSL_CTX_use_AltPrivateKey_buffer", ret); + return ret; + } +#endif /* WOLFSSL_DUAL_ALG_CERTS */ + + #ifdef WOLF_PRIVATE_KEY_ID int wolfSSL_CTX_use_PrivateKey_id(WOLFSSL_CTX* ctx, const unsigned char* id, long sz, int devId, long keySz) @@ -16058,6 +16607,13 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if (ret == WOLFSSL_SUCCESS) ctx->privateKeySz = (word32)keySz; + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ret == WOLFSSL_SUCCESS) + /* Set the ID for the alternative key, too. User can still + * override that afterwards. */ + ret = wolfSSL_CTX_use_AltPrivateKey_id(ctx, id, sz, devId, keySz); + #endif + return ret; } @@ -16079,6 +16635,13 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ret = WOLFSSL_SUCCESS; } + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ret == WOLFSSL_SUCCESS) + /* Set the ID for the alternative key, too. User can still + * override that afterwards. */ + ret = wolfSSL_CTX_use_AltPrivateKey_Id(ctx, id, sz, devId); + #endif + return ret; } @@ -16101,10 +16664,84 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ret = WOLFSSL_SUCCESS; } + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ret == WOLFSSL_SUCCESS) + /* Set the label for the alternative key, too. User can still + * override that afterwards. */ + ret = wolfSSL_CTX_use_AltPrivateKey_Label(ctx, label, devId); + #endif + return ret; } #endif /* WOLF_PRIVATE_KEY_ID */ +#if defined(WOLF_PRIVATE_KEY_ID) && defined(WOLFSSL_DUAL_ALG_CERTS) + int wolfSSL_CTX_use_AltPrivateKey_id(WOLFSSL_CTX* ctx, + const unsigned char* id, + long sz, int devId, long keySz) + { + int ret = wolfSSL_CTX_use_AltPrivateKey_Id(ctx, id, sz, devId); + + if (ret == WOLFSSL_SUCCESS) + ctx->altPrivateKeySz = (word32)keySz; + + return ret; + } + + int wolfSSL_CTX_use_AltPrivateKey_Id(WOLFSSL_CTX* ctx, + const unsigned char* id, + long sz, int devId) + { + int ret = WOLFSSL_FAILURE; + + if (ctx == NULL || id == NULL) { + return ret; + } + + FreeDer(&ctx->altPrivateKey); + if (AllocDer(&ctx->altPrivateKey, (word32)sz, ALT_PRIVATEKEY_TYPE, + ctx->heap) == 0) { + XMEMCPY(ctx->altPrivateKey->buffer, id, sz); + ctx->altPrivateKeyId = 1; + if (devId != INVALID_DEVID) + ctx->altPrivateKeyDevId = devId; + else + ctx->altPrivateKeyDevId = ctx->devId; + + ret = WOLFSSL_SUCCESS; + } + + return ret; + } + + int wolfSSL_CTX_use_AltPrivateKey_Label(WOLFSSL_CTX* ctx, const char* label, + int devId) + { + int ret = WOLFSSL_FAILURE; + word32 sz; + + if (ctx == NULL || label == NULL) { + return ret; + } + + sz = (word32)XSTRLEN(label) + 1; + FreeDer(&ctx->altPrivateKey); + if (AllocDer(&ctx->altPrivateKey, (word32)sz, ALT_PRIVATEKEY_TYPE, + ctx->heap) == 0) { + XMEMCPY(ctx->altPrivateKey->buffer, label, sz); + ctx->altPrivateKeyLabel = 1; + if (devId != INVALID_DEVID) + ctx->altPrivateKeyDevId = devId; + else + ctx->altPrivateKeyDevId = ctx->devId; + + ret = WOLFSSL_SUCCESS; + } + + return ret; + } +#endif /* WOLF_PRIVATE_KEY_ID && WOLFSSL_DUAL_ALG_CERTS */ + int wolfSSL_CTX_use_certificate_chain_buffer_format(WOLFSSL_CTX* ctx, const unsigned char* in, long sz, int format) { @@ -16244,13 +16881,44 @@ int wolfSSL_set_compression(WOLFSSL* ssl) int wolfSSL_use_PrivateKey_buffer(WOLFSSL* ssl, const unsigned char* in, long sz, int format) { + int ret = WOLFSSL_FAILURE; + long consumed = 0; + WOLFSSL_ENTER("wolfSSL_use_PrivateKey_buffer"); if (ssl == NULL) return BAD_FUNC_ARG; - return ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE, - ssl, NULL, 0, GET_VERIFY_SETTING_SSL(ssl)); + ret = ProcessBuffer(ssl->ctx, in, sz, format, PRIVATEKEY_TYPE, + ssl, &consumed, 0, GET_VERIFY_SETTING_SSL(ssl)); + + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ret == WOLFSSL_SUCCESS && consumed < sz) { + /* When support for dual algorithm certificates is enabled, the + * buffer may contain both the primary and the alternative + * private key. Hence, we have to parse both of them. + */ + ret = ProcessBuffer(ssl->ctx, in + consumed, sz - consumed, format, + ALT_PRIVATEKEY_TYPE, ssl, NULL, 0, + GET_VERIFY_SETTING_SSL(ssl)); + } + #endif + + return ret; + } + +#ifdef WOLFSSL_DUAL_ALG_CERTS + int wolfSSL_use_AltPrivateKey_buffer(WOLFSSL* ssl, const unsigned char* in, + long sz, int format) + { + int ret = WOLFSSL_FAILURE; + + WOLFSSL_ENTER("wolfSSL_use_AltPrivateKey_buffer"); + ret = ProcessBuffer(ssl->ctx, in, sz, format, ALT_PRIVATEKEY_TYPE, ssl, + NULL, 0, GET_VERIFY_SETTING_SSL(ssl)); + WOLFSSL_LEAVE("wolfSSL_use_AltPrivateKey_buffer", ret); + return ret; } +#endif /* WOLFSSL_DUAL_ALG_CERTS */ #ifdef WOLF_PRIVATE_KEY_ID int wolfSSL_use_PrivateKey_id(WOLFSSL* ssl, const unsigned char* id, @@ -16261,6 +16929,13 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if (ret == WOLFSSL_SUCCESS) ssl->buffers.keySz = (word32)keySz; + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ret == WOLFSSL_SUCCESS) + /* Set the ID for the alternative key, too. User can still + * override that afterwards. */ + ret = wolfSSL_use_AltPrivateKey_id(ssl, id, sz, devId, keySz); + #endif + return ret; } @@ -16284,6 +16959,13 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ret = WOLFSSL_SUCCESS; } + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ret == WOLFSSL_SUCCESS) + /* Set the ID for the alternative key, too. User can still + * override that afterwards. */ + ret = wolfSSL_use_AltPrivateKey_Id(ssl, id, sz, devId); + #endif + return ret; } @@ -16307,10 +16989,86 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ret = WOLFSSL_SUCCESS; } + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ret == WOLFSSL_SUCCESS) + /* Set the label for the alternative key, too. User can still + * override that afterwards. */ + ret = wolfSSL_use_AltPrivateKey_Label(ssl, label, devId); + #endif + return ret; } #endif /* WOLF_PRIVATE_KEY_ID */ +#if defined(WOLF_PRIVATE_KEY_ID) && defined(WOLFSSL_DUAL_ALG_CERTS) + int wolfSSL_use_AltPrivateKey_id(WOLFSSL* ssl, const unsigned char* id, + long sz, int devId, long keySz) + { + int ret = wolfSSL_use_AltPrivateKey_Id(ssl, id, sz, devId); + + if (ret == WOLFSSL_SUCCESS) + ssl->buffers.altKeySz = (word32)keySz; + + return ret; + } + + int wolfSSL_use_AltPrivateKey_Id(WOLFSSL* ssl, const unsigned char* id, + long sz, int devId) + { + int ret = WOLFSSL_FAILURE; + + if (ssl == NULL || id == NULL) { + return ret; + } + + if (ssl->buffers.weOwnAltKey) + FreeDer(&ssl->buffers.altKey); + if (AllocDer(&ssl->buffers.altKey, (word32)sz, ALT_PRIVATEKEY_TYPE, + ssl->heap) == 0) { + XMEMCPY(ssl->buffers.altKey->buffer, id, sz); + ssl->buffers.weOwnAltKey = 1; + ssl->buffers.altKeyId = 1; + if (devId != INVALID_DEVID) + ssl->buffers.altKeyDevId = devId; + else + ssl->buffers.altKeyDevId = ssl->devId; + + ret = WOLFSSL_SUCCESS; + } + + return ret; + } + + int wolfSSL_use_AltPrivateKey_Label(WOLFSSL* ssl, const char* label, + int devId) + { + int ret = WOLFSSL_FAILURE; + word32 sz; + + if (ssl == NULL || label == NULL) { + return ret; + } + + sz = (word32)XSTRLEN(label) + 1; + if (ssl->buffers.weOwnAltKey) + FreeDer(&ssl->buffers.altKey); + if (AllocDer(&ssl->buffers.altKey, (word32)sz, ALT_PRIVATEKEY_TYPE, + ssl->heap) == 0) { + XMEMCPY(ssl->buffers.altKey->buffer, label, sz); + ssl->buffers.weOwnAltKey = 1; + ssl->buffers.altKeyLabel = 1; + if (devId != INVALID_DEVID) + ssl->buffers.altKeyDevId = devId; + else + ssl->buffers.altKeyDevId = ssl->devId; + + ret = WOLFSSL_SUCCESS; + } + + return ret; + } +#endif /* WOLF_PRIVATE_KEY_ID && WOLFSSL_DUAL_ALG_CERTS */ + int wolfSSL_use_certificate_chain_buffer_format(WOLFSSL* ssl, const unsigned char* in, long sz, int format) { diff --git a/src/tls.c b/src/tls.c index a28568c69e..ca5159d3f8 100644 --- a/src/tls.c +++ b/src/tls.c @@ -8437,7 +8437,7 @@ static int TLSX_KeyShare_ProcessPqc(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) XMEMCPY(ssl->arrays->preMasterSecret, keyShareEntry->ke, keyShareEntry->keLen); ssl->arrays->preMasterSz = keyShareEntry->keLen; - XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_SECRET) + XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_SECRET); keyShareEntry->ke = NULL; keyShareEntry->keLen = 0; return 0; @@ -9583,7 +9583,7 @@ int TLSX_CKS_Parse(WOLFSSL* ssl, byte* input, word16 length, case WOLFSSL_CKS_SIGSPEC_EXTERNAL: default: /* All other values (including external) are not. */ - return WOLFSSL_NOT_IMPLEMENTED; + return BAD_FUNC_ARG; } } @@ -9618,7 +9618,7 @@ int TLSX_CKS_Parse(WOLFSSL* ssl, byte* input, word16 length, for (j = 0; j < length; j++) { if (ssl->sigSpec[i] == input[j]) { /* Got the match, set to this one. */ - ret = wolfSSL_UseCKS(ssl, &ssl->peerSigSpec[i], 1); + ret = wolfSSL_UseCKS(ssl, &ssl->sigSpec[i], 1); if (ret == WOLFSSL_SUCCESS) { ret = TLSX_UseCKS(&ssl->extensions, ssl, ssl->heap); TLSX_SetResponse(ssl, TLSX_CKS); @@ -11212,8 +11212,10 @@ static int TLSX_ClientCertificateType_GetSize(WOLFSSL* ssl, byte msgType) ret = (int)(OPAQUE8_LEN + cnt * OPAQUE8_LEN); } else if (msgType == server_hello || msgType == encrypted_extensions) { - /* sever side */ + /* server side */ cnt = ssl->options.rpkState.sending_ClientCertTypeCnt;/* must be one */ + if (cnt != 1) + return SANITY_MSG_E; ret = OPAQUE8_LEN; } else { @@ -13570,7 +13572,7 @@ static int TLSX_GetSizeWithEch(WOLFSSL* ssl, byte* semaphore, byte msgType, #endif /** Tells the buffered size of extensions to be sent into the client hello. */ -int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word16* pLength) +int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, word32* pLength) { int ret = 0; word16 length = 0; @@ -13800,7 +13802,7 @@ static int TLSX_WriteWithEch(WOLFSSL* ssl, byte* output, byte* semaphore, #endif /** Writes the extensions to be sent into the client hello. */ -int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word16* pOffset) +int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, byte msgType, word32* pOffset) { int ret = 0; word16 offset = 0; diff --git a/src/tls13.c b/src/tls13.c index 9a2e240cdd..81518edacb 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -1910,10 +1910,12 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store) #elif defined(WOLFSSL_ZEPHYR) word32 TimeNowInMilliseconds(void) { + int64_t t; #if defined(CONFIG_ARCH_POSIX) k_cpu_idle(); #endif - return (word32)k_uptime_get() / 1000; + t = k_uptime_get(); /* returns current uptime in milliseconds */ + return (word32)t; } #else @@ -2201,10 +2203,12 @@ int DeriveTls13Keys(WOLFSSL* ssl, int secret, int side, int store) #elif defined(WOLFSSL_ZEPHYR) sword64 TimeNowInMilliseconds(void) { + int64_t t; #if defined(CONFIG_ARCH_POSIX) k_cpu_idle(); #endif - return (sword64)k_uptime_get() / 1000; + t = k_uptime_get(); /* returns current uptime in milliseconds */ + return (sword64)t; } #else @@ -4234,7 +4238,7 @@ typedef struct Sch13Args { byte* output; word32 idx; int sendSz; - word16 length; + word32 length; #if defined(HAVE_ECH) int clientRandomOffset; int preXLength; @@ -7622,7 +7626,7 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, int ret; int sendSz; word32 i; - word16 reqSz; + word32 reqSz; word16 hashSigAlgoSz = 0; SignatureAlgorithms* sa; int haveSig = SIG_RSA | SIG_ECDSA | SIG_FALCON | SIG_DILITHIUM; @@ -7821,9 +7825,19 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) #define HYBRID_RSA3072_DILITHIUM_LEVEL2_SA_MINOR 0xA2 #define HYBRID_P384_DILITHIUM_LEVEL3_SA_MINOR 0xA4 #define HYBRID_P521_DILITHIUM_LEVEL5_SA_MINOR 0xA6 -#define HYBRID_P256_FALCON_LEVEL1_SA_MINOR 0x0C -#define HYBRID_RSA3072_FALCON_LEVEL1_SA_MINOR 0x0D -#define HYBRID_P521_FALCON_LEVEL5_SA_MINOR 0x0F +#define HYBRID_P256_FALCON_LEVEL1_SA_MINOR 0xAF +#define HYBRID_RSA3072_FALCON_LEVEL1_SA_MINOR 0xB0 +#define HYBRID_P521_FALCON_LEVEL5_SA_MINOR 0xB2 + +/* Custom defined ones for PQC first */ +#define HYBRID_DILITHIUM_LEVEL2_P256_SA_MINOR 0xD1 +#define HYBRID_DILITHIUM_LEVEL2_RSA3072_SA_MINOR 0xD2 +#define HYBRID_DILITHIUM_LEVEL3_P384_SA_MINOR 0xD3 +#define HYBRID_DILITHIUM_LEVEL5_P521_SA_MINOR 0xD4 +#define HYBRID_FALCON_LEVEL1_P256_SA_MINOR 0xD5 +#define HYBRID_FALCON_LEVEL1_RSA3072_SA_MINOR 0xD6 +#define HYBRID_FALCON_LEVEL5_P521_SA_MINOR 0xD7 + static void EncodeDualSigAlg(byte sigAlg, byte altSigAlg, byte* output) { @@ -7846,15 +7860,46 @@ static void EncodeDualSigAlg(byte sigAlg, byte altSigAlg, byte* output) altSigAlg == dilithium_level5_sa_algo) { output[1] = HYBRID_P521_DILITHIUM_LEVEL5_SA_MINOR; } - else if (sigAlg == ecc_dsa_sa_algo && altSigAlg == falcon_level1_sa_algo) { + else if (sigAlg == ecc_dsa_sa_algo && + altSigAlg == falcon_level1_sa_algo) { output[1] = HYBRID_P256_FALCON_LEVEL1_SA_MINOR; } - else if (sigAlg == rsa_pss_sa_algo && altSigAlg == falcon_level1_sa_algo) { + else if (sigAlg == rsa_pss_sa_algo && + altSigAlg == falcon_level1_sa_algo) { output[1] = HYBRID_RSA3072_FALCON_LEVEL1_SA_MINOR; } - else if (sigAlg == ecc_dsa_sa_algo && altSigAlg == falcon_level5_sa_algo) { + else if (sigAlg == ecc_dsa_sa_algo && + altSigAlg == falcon_level5_sa_algo) { output[1] = HYBRID_P521_FALCON_LEVEL5_SA_MINOR; } + else if (sigAlg == dilithium_level2_sa_algo && + altSigAlg == ecc_dsa_sa_algo) { + output[1] = HYBRID_DILITHIUM_LEVEL2_P256_SA_MINOR; + } + else if (sigAlg == dilithium_level2_sa_algo && + altSigAlg == rsa_pss_sa_algo) { + output[1] = HYBRID_DILITHIUM_LEVEL2_RSA3072_SA_MINOR; + } + else if (sigAlg == dilithium_level3_sa_algo && + altSigAlg == ecc_dsa_sa_algo) { + output[1] = HYBRID_DILITHIUM_LEVEL3_P384_SA_MINOR; + } + else if (sigAlg == dilithium_level5_sa_algo && + altSigAlg == ecc_dsa_sa_algo) { + output[1] = HYBRID_DILITHIUM_LEVEL5_P521_SA_MINOR; + } + else if (sigAlg == falcon_level1_sa_algo && + altSigAlg == ecc_dsa_sa_algo) { + output[1] = HYBRID_FALCON_LEVEL1_P256_SA_MINOR; + } + else if (sigAlg == falcon_level1_sa_algo && + altSigAlg == rsa_pss_sa_algo) { + output[1] = HYBRID_FALCON_LEVEL1_RSA3072_SA_MINOR; + } + else if (sigAlg == falcon_level5_sa_algo && + altSigAlg == ecc_dsa_sa_algo) { + output[1] = HYBRID_FALCON_LEVEL5_P521_SA_MINOR; + } if (output[1] != 0x0) { output[0] = HYBRID_SA_MAJOR; @@ -7972,39 +8017,74 @@ static WC_INLINE int DecodeTls13HybridSigAlg(byte* input, byte* hashAlg, if (input[1] == HYBRID_P256_DILITHIUM_LEVEL2_SA_MINOR) { *sigAlg = ecc_dsa_sa_algo; - *hashAlg = 4; /* WC_HASH_TYPE_SHA? Reviewer? */ + *hashAlg = sha256_mac; *altSigAlg = dilithium_level2_sa_algo; } else if (input[1] == HYBRID_RSA3072_DILITHIUM_LEVEL2_SA_MINOR) { *sigAlg = rsa_pss_sa_algo; - *hashAlg = 4; + *hashAlg = sha256_mac; *altSigAlg = dilithium_level2_sa_algo; } else if (input[1] == HYBRID_P384_DILITHIUM_LEVEL3_SA_MINOR) { *sigAlg = ecc_dsa_sa_algo; - *hashAlg = 5; + *hashAlg = sha384_mac; *altSigAlg = dilithium_level3_sa_algo; } else if (input[1] == HYBRID_P521_DILITHIUM_LEVEL5_SA_MINOR) { *sigAlg = ecc_dsa_sa_algo; - *hashAlg = 6; + *hashAlg = sha512_mac; *altSigAlg = dilithium_level5_sa_algo; } else if (input[1] == HYBRID_P256_FALCON_LEVEL1_SA_MINOR) { *sigAlg = ecc_dsa_sa_algo; - *hashAlg = 4; + *hashAlg = sha256_mac; *altSigAlg = falcon_level1_sa_algo; } else if (input[1] == HYBRID_RSA3072_FALCON_LEVEL1_SA_MINOR) { *sigAlg = rsa_pss_sa_algo; - *hashAlg = 4; + *hashAlg = sha256_mac; *altSigAlg = falcon_level1_sa_algo; } else if (input[1] == HYBRID_P521_FALCON_LEVEL5_SA_MINOR) { *sigAlg = ecc_dsa_sa_algo; - *hashAlg = 6; + *hashAlg = sha512_mac; *altSigAlg = falcon_level5_sa_algo; } + else if (input[1] == HYBRID_DILITHIUM_LEVEL2_P256_SA_MINOR) { + *sigAlg = dilithium_level2_sa_algo; + *hashAlg = sha256_mac; + *altSigAlg = ecc_dsa_sa_algo; + } + else if (input[1] == HYBRID_DILITHIUM_LEVEL2_RSA3072_SA_MINOR) { + *sigAlg = dilithium_level2_sa_algo; + *hashAlg = sha256_mac; + *altSigAlg = rsa_pss_sa_algo; + } + else if (input[1] == HYBRID_DILITHIUM_LEVEL3_P384_SA_MINOR) { + *sigAlg = dilithium_level3_sa_algo; + *hashAlg = sha384_mac; + *altSigAlg = ecc_dsa_sa_algo; + } + else if (input[1] == HYBRID_DILITHIUM_LEVEL5_P521_SA_MINOR) { + *sigAlg = dilithium_level5_sa_algo; + *hashAlg = sha512_mac; + *altSigAlg = ecc_dsa_sa_algo; + } + else if (input[1] == HYBRID_FALCON_LEVEL1_P256_SA_MINOR) { + *sigAlg = falcon_level1_sa_algo; + *hashAlg = sha256_mac; + *altSigAlg = ecc_dsa_sa_algo; + } + else if (input[1] == HYBRID_FALCON_LEVEL1_RSA3072_SA_MINOR) { + *sigAlg = falcon_level1_sa_algo; + *hashAlg = sha256_mac; + *altSigAlg = rsa_pss_sa_algo; + } + else if (input[1] == HYBRID_FALCON_LEVEL5_P521_SA_MINOR) { + *sigAlg = falcon_level5_sa_algo; + *hashAlg = sha512_mac; + *altSigAlg = ecc_dsa_sa_algo; + } else { return INVALID_PARAMETER; } @@ -8668,7 +8748,9 @@ typedef struct Scv13Args { word16 sigDataSz; #ifdef WOLFSSL_DUAL_ALG_CERTS byte altSigAlgo; - word16 altSigLen; /* Only used in the case of both native and alt. */ + word32 altSigLen; /* Only used in the case of both native and alt. */ + byte* altSigData; + word16 altSigDataSz; #endif } Scv13Args; @@ -8682,6 +8764,12 @@ static void FreeScv13Args(WOLFSSL* ssl, void* pArgs) XFREE(args->sigData, ssl->heap, DYNAMIC_TYPE_SIGNATURE); args->sigData = NULL; } +#ifdef WOLFSSL_DUAL_ALG_CERTS + if (args && args->altSigData != NULL) { + XFREE(args->altSigData, ssl->heap, DYNAMIC_TYPE_SIGNATURE); + args->altSigData = NULL; + } +#endif } /* handle generation TLS v1.3 certificate_verify (15) */ @@ -8697,7 +8785,10 @@ static void FreeScv13Args(WOLFSSL* ssl, void* pArgs) static int SendTls13CertificateVerify(WOLFSSL* ssl) { int ret = 0; - buffer* sig = &ssl->buffers.sig; +#ifndef NO_RSA + /* Use this as a temporary buffer for RSA signature verification. */ + buffer* rsaSigBuf = &ssl->buffers.sig; +#endif #ifdef WOLFSSL_ASYNC_CRYPT Scv13Args* args = NULL; WOLFSSL_ASSERT_SIZEOF_GE(ssl->async->args, *args); @@ -8813,11 +8904,10 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) } else { #ifdef WOLFSSL_DUAL_ALG_CERTS - if (wolfSSL_is_server(ssl) && - ssl->sigSpec != NULL && + if (ssl->sigSpec != NULL && *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_ALTERNATIVE) { /* In the case of alternative, we swap in the alt. */ - if (ssl->ctx->altPrivateKey == NULL) { + if (ssl->buffers.altKey == NULL) { ERROR_OUT(NO_PRIVATE_KEY, exit_scv); } ssl->buffers.keyType = ssl->buffers.altKeyType; @@ -8827,24 +8917,21 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) FreeDer(&ssl->buffers.key); } - /* Transfer ownership. ssl->ctx always owns the alt private - * key. */ - ssl->buffers.key = ssl->ctx->altPrivateKey; - ssl->ctx->altPrivateKey = NULL; - ssl->buffers.weOwnKey = 1; - ssl->buffers.weOwnAltKey = 0; + /* Swap keys */ + ssl->buffers.key = ssl->buffers.altKey; + ssl->buffers.weOwnKey = ssl->buffers.weOwnAltKey; } #endif /* WOLFSSL_DUAL_ALG_CERTS */ - ret = DecodePrivateKey(ssl, &args->length); + ret = DecodePrivateKey(ssl, &args->sigLen); if (ret != 0) goto exit_scv; } - if (rem < 0 || args->length > rem) { + if (rem < 0 || (int)args->sigLen > rem) { ERROR_OUT(BUFFER_E, exit_scv); } - if (args->length == 0) { + if (args->sigLen == 0) { ERROR_OUT(NO_PRIVATE_KEY, exit_scv); } @@ -8917,7 +9004,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) ERROR_OUT(ALGO_ID_E, exit_scv); } -#ifdef WOLFSSL_DUAL_ALG_CERTS + #ifdef WOLFSSL_DUAL_ALG_CERTS if (ssl->peerSigSpec == NULL) { /* The peer did not respond. We didn't send CKS or they don't * support it. Either way, we do not need to handle dual @@ -8926,8 +9013,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) ssl->sigSpecSz = 0; } - if (wolfSSL_is_server(ssl) && - ssl->sigSpec != NULL && + if (ssl->sigSpec != NULL && *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { /* The native was already decoded. Now we need to do the * alternative. Note that no swap was done because this case is @@ -8936,21 +9022,27 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) ERROR_OUT(NO_PRIVATE_KEY, exit_scv); } - if (ssl->buffers.altKeyType == falcon_level1_sa_algo || + /* After this call, args->altSigLen has the length we need for + * the alternative signature. */ + ret = DecodeAltPrivateKey(ssl, &args->altSigLen); + if (ret != 0) + goto exit_scv; + + if (ssl->buffers.altKeyType == ecc_dsa_sa_algo || + ssl->buffers.altKeyType == falcon_level1_sa_algo || ssl->buffers.altKeyType == falcon_level5_sa_algo || ssl->buffers.altKeyType == dilithium_level2_sa_algo || ssl->buffers.altKeyType == dilithium_level3_sa_algo || ssl->buffers.altKeyType == dilithium_level5_sa_algo) { args->altSigAlgo = ssl->buffers.altKeyType; } + else if (ssl->buffers.altKeyType == rsa_sa_algo && + ssl->hsAltType == DYNAMIC_TYPE_RSA) { + args->altSigAlgo = rsa_pss_sa_algo; + } else { ERROR_OUT(ALGO_ID_E, exit_scv); } - /* After this call, args->altSigLen has the length we need for - * the alternative signature. */ - ret = DecodeAltPrivateKey(ssl, &args->altSigLen); - if (ret != 0) - goto exit_scv; EncodeDualSigAlg(args->sigAlgo, args->altSigAlgo, args->verify); if (args->verify[0] == 0) { @@ -8958,57 +9050,79 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) } } else -#endif /* WOLFSSL_DUAL_ALG_CERTS */ + #endif /* WOLFSSL_DUAL_ALG_CERTS */ EncodeSigAlg(ssl->options.hashAlgo, args->sigAlgo, args->verify); if (args->sigData == NULL) { - if (ssl->hsType == DYNAMIC_TYPE_RSA) { - int sigLen = MAX_SIG_DATA_SZ; - if (args->length > MAX_SIG_DATA_SZ) - sigLen = args->length; - args->sigData = (byte*)XMALLOC(sigLen, ssl->heap, - DYNAMIC_TYPE_SIGNATURE); - } - else { - args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap, - DYNAMIC_TYPE_SIGNATURE); + word32 sigLen = MAX_SIG_DATA_SZ; + if ((ssl->hsType == DYNAMIC_TYPE_RSA) && + (args->sigLen > MAX_SIG_DATA_SZ)) { + /* We store the RSA signature in the sigData buffer + * temporarly, hence its size must be fitting. */ + sigLen = args->sigLen; } + args->sigData = (byte*)XMALLOC(sigLen, ssl->heap, + DYNAMIC_TYPE_SIGNATURE); if (args->sigData == NULL) { ERROR_OUT(MEMORY_E, exit_scv); } } + #ifdef WOLFSSL_DUAL_ALG_CERTS + if ((ssl->sigSpec != NULL) && + (*ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) && + (args->altSigData == NULL)) { + word32 sigLen = MAX_SIG_DATA_SZ; + if (ssl->hsAltType == DYNAMIC_TYPE_RSA && + args->altSigLen > MAX_SIG_DATA_SZ) { + /* We store the RSA signature in the sigData buffer + * temporarly, hence its size must be fitting. */ + sigLen = args->altSigLen; + } + args->altSigData = (byte*)XMALLOC(sigLen, ssl->heap, + DYNAMIC_TYPE_SIGNATURE); + if (args->altSigData == NULL) { + ERROR_OUT(MEMORY_E, exit_scv); + } + } + #endif /* WOLFSSL_DUAL_ALG_CERTS */ + /* Create the data to be signed. */ ret = CreateSigData(ssl, args->sigData, &args->sigDataSz, 0); if (ret != 0) goto exit_scv; + #ifdef WOLFSSL_DUAL_ALG_CERTS + if ((ssl->sigSpec != NULL) && + (*ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH)) { + XMEMCPY(args->altSigData, args->sigData, args->sigDataSz); + args->altSigDataSz = args->sigDataSz; + } + #endif /* WOLFSSL_DUAL_ALG_CERTS */ + #ifndef NO_RSA if (ssl->hsType == DYNAMIC_TYPE_RSA) { /* build encoded signature buffer */ - sig->length = WC_MAX_DIGEST_SIZE; - sig->buffer = (byte*)XMALLOC(sig->length, ssl->heap, - DYNAMIC_TYPE_SIGNATURE); - if (sig->buffer == NULL) { + rsaSigBuf->length = WC_MAX_DIGEST_SIZE; + rsaSigBuf->buffer = (byte*)XMALLOC(rsaSigBuf->length, ssl->heap, + DYNAMIC_TYPE_SIGNATURE); + if (rsaSigBuf->buffer == NULL) { ERROR_OUT(MEMORY_E, exit_scv); } - ret = CreateRSAEncodedSig(sig->buffer, args->sigData, + ret = CreateRSAEncodedSig(rsaSigBuf->buffer, args->sigData, args->sigDataSz, args->sigAlgo, ssl->options.hashAlgo); if (ret < 0) goto exit_scv; - sig->length = ret; + rsaSigBuf->length = ret; ret = 0; - - /* Maximum size of RSA Signature. */ - args->sigLen = args->length; } #endif /* !NO_RSA */ #ifdef HAVE_ECC if (ssl->hsType == DYNAMIC_TYPE_ECC) { - sig->length = args->sendSz - args->idx - HASH_SIG_SIZE - - VERIFY_HEADER; + args->sigLen = args->sendSz - args->idx - HASH_SIG_SIZE - + VERIFY_HEADER; #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) if (ssl->buffers.keyType != sm2_sa_algo) #endif @@ -9028,7 +9142,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) if (ret < 0) { ERROR_OUT(ret, exit_scv); } - sig->length = ED25519_SIG_SIZE; + args->sigLen = ED25519_SIG_SIZE; } #endif /* HAVE_ED25519 */ #ifdef HAVE_ED448 @@ -9037,23 +9151,60 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) if (ret < 0) { ERROR_OUT(ret, exit_scv); } - sig->length = ED448_SIG_SIZE; + args->sigLen = ED448_SIG_SIZE; } #endif /* HAVE_ED448 */ #if defined(HAVE_PQC) #if defined(HAVE_FALCON) if (ssl->hsType == DYNAMIC_TYPE_FALCON) { - sig->length = FALCON_MAX_SIG_SIZE; + args->sigLen = FALCON_MAX_SIG_SIZE; } - #endif + #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) if (ssl->hsType == DYNAMIC_TYPE_DILITHIUM) { - sig->length = DILITHIUM_MAX_SIG_SIZE; + args->sigLen = DILITHIUM_MAX_SIG_SIZE; } - #endif + #endif /* HAVE_DILITHIUM */ #endif /* HAVE_PQC */ + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ssl->sigSpec != NULL && + *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { + + #ifndef NO_RSA + if (ssl->hsAltType == DYNAMIC_TYPE_RSA) { + /* build encoded signature buffer */ + rsaSigBuf->length = WC_MAX_DIGEST_SIZE; + rsaSigBuf->buffer = (byte*)XMALLOC(rsaSigBuf->length, + ssl->heap, + DYNAMIC_TYPE_SIGNATURE); + if (rsaSigBuf->buffer == NULL) { + ERROR_OUT(MEMORY_E, exit_scv); + } + + ret = CreateRSAEncodedSig(rsaSigBuf->buffer, + args->altSigData, args->altSigDataSz, + args->altSigAlgo, ssl->options.hashAlgo); + if (ret < 0) + goto exit_scv; + rsaSigBuf->length = ret; + ret = 0; + } + #endif /* !NO_RSA */ + #ifdef HAVE_ECC + if (ssl->hsAltType == DYNAMIC_TYPE_ECC) { + ret = CreateECCEncodedSig(args->altSigData, + args->altSigDataSz, ssl->options.hashAlgo); + if (ret < 0) + goto exit_scv; + args->altSigDataSz = (word16)ret; + ret = 0; + } + #endif /* HAVE_ECC */ + } + #endif /* WOLFSSL_DUAL_ALG_CERTS */ + /* Advance state and proceed */ ssl->options.asyncState = TLS_ASYNC_DO; } /* case TLS_ASYNC_BUILD */ @@ -9061,21 +9212,30 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) case TLS_ASYNC_DO: { + byte* sigOut = args->verify + HASH_SIG_SIZE + VERIFY_HEADER; + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ssl->sigSpec != NULL && + *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { + /* As we have two signatures in the message, we store + * the length of each before the actual signature. This + * is necessary, as we could have two algorithms with + * variable length signatures. */ + sigOut += OPAQUE16_LEN; + } + #endif #ifdef HAVE_ECC if (ssl->hsType == DYNAMIC_TYPE_ECC) { #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) if (ssl->buffers.keyType == sm2_sa_algo) { ret = Sm2wSm3Sign(ssl, TLS13_SM2_SIG_ID, TLS13_SM2_SIG_ID_SZ, args->sigData, args->sigDataSz, - args->verify + HASH_SIG_SIZE + VERIFY_HEADER, - (word32*)&sig->length, (ecc_key*)ssl->hsKey, NULL); + sigOut, &args->sigLen, (ecc_key*)ssl->hsKey, NULL); } else #endif { ret = EccSign(ssl, args->sigData, args->sigDataSz, - args->verify + HASH_SIG_SIZE + VERIFY_HEADER, - (word32*)&sig->length, (ecc_key*)ssl->hsKey, + sigOut, &args->sigLen, (ecc_key*)ssl->hsKey, #ifdef HAVE_PK_CALLBACKS ssl->buffers.key #else @@ -9083,127 +9243,62 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) #endif ); } - -#ifdef WOLFSSL_DUAL_ALG_CERTS - if (wolfSSL_is_server(ssl) && - ssl->sigSpec != NULL && - *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { - if (ssl->hsAltType == DYNAMIC_TYPE_DILITHIUM) { - /* note the + sig->length; we are appending. */ - ret = wc_dilithium_sign_msg( - args->sigData, args->sigDataSz, - args->verify + HASH_SIG_SIZE + - VERIFY_HEADER + sig->length, - (word32*)&args->altSigLen, - (dilithium_key*)ssl->hsAltKey, ssl->rng); - - } - else if (ssl->hsAltType == DYNAMIC_TYPE_FALCON) { - /* note the sig->length; we are appending. */ - ret = wc_falcon_sign_msg(args->sigData, args->sigDataSz, - args->verify + HASH_SIG_SIZE + - VERIFY_HEADER + sig->length, - (word32*)&args->altSigLen, - (falcon_key*)ssl->hsAltKey, - ssl->rng); - } - } -#endif /* WOLFSSL_DUAL_ALG_CERTS */ - args->length = (word16)sig->length; + args->length = (word16)args->sigLen; } #endif /* HAVE_ECC */ #ifdef HAVE_ED25519 if (ssl->hsType == DYNAMIC_TYPE_ED25519) { ret = Ed25519Sign(ssl, args->sigData, args->sigDataSz, - args->verify + HASH_SIG_SIZE + VERIFY_HEADER, - (word32*)&sig->length, (ed25519_key*)ssl->hsKey, + sigOut, &args->sigLen, (ed25519_key*)ssl->hsKey, #ifdef HAVE_PK_CALLBACKS ssl->buffers.key #else NULL #endif ); - args->length = (word16)sig->length; + args->length = (word16)args->sigLen; } #endif #ifdef HAVE_ED448 if (ssl->hsType == DYNAMIC_TYPE_ED448) { ret = Ed448Sign(ssl, args->sigData, args->sigDataSz, - args->verify + HASH_SIG_SIZE + VERIFY_HEADER, - (word32*)&sig->length, (ed448_key*)ssl->hsKey, + sigOut, &args->sigLen, (ed448_key*)ssl->hsKey, #ifdef HAVE_PK_CALLBACKS ssl->buffers.key #else NULL #endif ); - args->length = (word16)sig->length; + args->length = (word16)args->sigLen; } #endif #if defined(HAVE_PQC) #if defined(HAVE_FALCON) if (ssl->hsType == DYNAMIC_TYPE_FALCON) { ret = wc_falcon_sign_msg(args->sigData, args->sigDataSz, - args->verify + HASH_SIG_SIZE + - VERIFY_HEADER, (word32*)&sig->length, + sigOut, &args->sigLen, (falcon_key*)ssl->hsKey, ssl->rng); - args->length = (word16)sig->length; + args->length = (word16)args->sigLen; } - #endif + #endif /* HAVE_FALCON */ #if defined(HAVE_DILITHIUM) if (ssl->hsType == DYNAMIC_TYPE_DILITHIUM) { ret = wc_dilithium_sign_msg(args->sigData, args->sigDataSz, - args->verify + HASH_SIG_SIZE + - VERIFY_HEADER, (word32*)&sig->length, + sigOut, &args->sigLen, (dilithium_key*)ssl->hsKey, ssl->rng); - args->length = (word16)sig->length; + args->length = (word16)args->sigLen; } - #endif + #endif /* HAVE_DILITHIUM */ #endif /* HAVE_PQC */ #ifndef NO_RSA if (ssl->hsType == DYNAMIC_TYPE_RSA) { - ret = RsaSign(ssl, sig->buffer, (word32)sig->length, - args->verify + HASH_SIG_SIZE + VERIFY_HEADER, &args->sigLen, - args->sigAlgo, ssl->options.hashAlgo, - (RsaKey*)ssl->hsKey, - ssl->buffers.key - ); - -#ifdef WOLFSSL_DUAL_ALG_CERTS - /* In the case of RSA, we need to do the CKS both case here - * BEFORE args->sigData is overwritten!! We keep the sig - * separate and then append later so we don't interfere with the - * checks below. */ - if (wolfSSL_is_server(ssl) && - ssl->sigSpec != NULL && - *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { - if (ssl->hsAltType == DYNAMIC_TYPE_DILITHIUM) { - /* note the + args->sigLen; we are appending. */ - ret = wc_dilithium_sign_msg(args->sigData, - args->sigDataSz, - args->verify + HASH_SIG_SIZE + VERIFY_HEADER + - args->sigLen, - (word32*)&args->altSigLen, - (dilithium_key*)ssl->hsAltKey, ssl->rng); - } - else if (ssl->hsAltType == DYNAMIC_TYPE_FALCON) { - /* note the + args->sigLen; we are appending. */ - ret = wc_falcon_sign_msg(args->sigData, args->sigDataSz, - args->verify + HASH_SIG_SIZE + - VERIFY_HEADER + args->sigLen, - (word32*)&args->altSigLen, - (falcon_key*)ssl->hsAltKey, - ssl->rng); - } - } -#endif /* WOLFSSL_DUAL_ALG_CERTS */ - + ret = RsaSign(ssl, rsaSigBuf->buffer, (word32)rsaSigBuf->length, + sigOut, &args->sigLen, args->sigAlgo, + ssl->options.hashAlgo, (RsaKey*)ssl->hsKey, + ssl->buffers.key); if (ret == 0) { args->length = (word16)args->sigLen; - - XMEMCPY(args->sigData, - args->verify + HASH_SIG_SIZE + VERIFY_HEADER, - args->sigLen); + XMEMCPY(args->sigData, sigOut, args->sigLen); } } #endif /* !NO_RSA */ @@ -9213,10 +9308,78 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) goto exit_scv; } -#ifdef WOLFSSL_DUAL_ALG_CERTS - /* Add in length of the alt sig which will be appended to the sig */ - args->length += args->altSigLen; -#endif /* WOLFSSL_DUAL_ALG_CERTS */ + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ssl->sigSpec != NULL && + *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { + /* Add signature length for the first signature. */ + c16toa((word16)args->sigLen, sigOut - OPAQUE16_LEN); + args->length += OPAQUE16_LEN; + + /* Advance our pointer to where we store the alt signature. + * We also add additional space for the length field of the + * second signature. */ + sigOut += args->sigLen + OPAQUE16_LEN; + + /* Generate the alternative signature */ + #ifdef HAVE_ECC + if (ssl->hsAltType == DYNAMIC_TYPE_ECC) { + ret = EccSign(ssl, args->altSigData, args->altSigDataSz, + sigOut, &args->altSigLen, + (ecc_key*)ssl->hsAltKey, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.altKey + #else + NULL + #endif + ); + } + #endif /* HAVE_ECC */ + #ifndef NO_RSA + if (ssl->hsAltType == DYNAMIC_TYPE_RSA) { + ret = RsaSign(ssl, rsaSigBuf->buffer, + (word32)rsaSigBuf->length, sigOut, + &args->altSigLen, args->altSigAlgo, + ssl->options.hashAlgo, (RsaKey*)ssl->hsAltKey, + ssl->buffers.altKey); + + if (ret == 0) { + XMEMCPY(args->altSigData, sigOut, args->altSigLen); + } + } + #endif /* !NO_RSA */ + #if defined(HAVE_PQC) + #if defined(HAVE_FALCON) + if (ssl->hsAltType == DYNAMIC_TYPE_FALCON) { + ret = wc_falcon_sign_msg(args->altSigData, + args->altSigDataSz, sigOut, + &args->altSigLen, + (falcon_key*)ssl->hsAltKey, + ssl->rng); + } + #endif /* HAVE_FALCON */ + #if defined(HAVE_DILITHIUM) + if (ssl->hsAltType == DYNAMIC_TYPE_DILITHIUM) { + ret = wc_dilithium_sign_msg(args->altSigData, + args->altSigDataSz, sigOut, + &args->altSigLen, + (dilithium_key*)ssl->hsAltKey, + ssl->rng); + } + #endif /* HAVE_DILITHIUM */ + #endif /* HAVE_PQC */ + + /* Check for error */ + if (ret != 0) { + goto exit_scv; + } + + /* Add signature length for the alternative signature. */ + c16toa((word16)args->altSigLen, sigOut - OPAQUE16_LEN); + + /* Add length of the alt sig to the total length */ + args->length += args->altSigLen + OPAQUE16_LEN; + } + #endif /* WOLFSSL_DUAL_ALG_CERTS */ /* Add signature length. */ c16toa(args->length, args->verify + HASH_SIG_SIZE); @@ -9232,38 +9395,72 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) if (ssl->hsType == DYNAMIC_TYPE_RSA) { /* check for signature faults */ ret = VerifyRsaSign(ssl, args->sigData, args->sigLen, - sig->buffer, (word32)sig->length, args->sigAlgo, + rsaSigBuf->buffer, (word32)rsaSigBuf->length, args->sigAlgo, ssl->options.hashAlgo, (RsaKey*)ssl->hsKey, - ssl->buffers.key - ); + ssl->buffers.key); + } + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ssl->sigSpec != NULL && + *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH && + ssl->hsAltType == DYNAMIC_TYPE_RSA) { + /* check for signature faults */ + ret = VerifyRsaSign(ssl, args->altSigData, args->altSigLen, + rsaSigBuf->buffer, (word32)rsaSigBuf->length, + args->altSigAlgo, ssl->options.hashAlgo, + (RsaKey*)ssl->hsAltKey, ssl->buffers.altKey); } + #endif /* WOLFSSL_DUAL_ALG_CERTS */ #endif /* !NO_RSA */ #if defined(HAVE_ECC) && defined(WOLFSSL_CHECK_SIG_FAULTS) if (ssl->hsType == DYNAMIC_TYPE_ECC) { + byte* sigOut = args->verify + HASH_SIG_SIZE + VERIFY_HEADER; + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ssl->sigSpec != NULL && + *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { + /* Add our length offset. */ + sigOut += OPAQUE16_LEN; + } + #endif #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) if (ssl->buffers.keyType == sm2_sa_algo) { ret = Sm2wSm3Verify(ssl, TLS13_SM2_SIG_ID, TLS13_SM2_SIG_ID_SZ, - args->verify + HASH_SIG_SIZE + VERIFY_HEADER, - sig->length, args->sigData, args->sigDataSz, + sigOut, args->sigLen, args->sigData, args->sigDataSz, (ecc_key*)ssl->hsKey, NULL); } else #endif { - ret = EccVerify(ssl, - args->verify + HASH_SIG_SIZE + VERIFY_HEADER, - sig->length, args->sigData, args->sigDataSz, - (ecc_key*)ssl->hsKey, + ret = EccVerify(ssl, sigOut, args->sigLen, + args->sigData, args->sigDataSz, + (ecc_key*)ssl->hsKey, #ifdef HAVE_PK_CALLBACKS - ssl->buffers.key + ssl->buffers.key #else - NULL + NULL #endif - ); + ); } } - #endif + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ssl->sigSpec != NULL && + *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH && + ssl->hsAltType == DYNAMIC_TYPE_ECC) { + /* check for signature faults */ + byte* sigOut = args->verify + HASH_SIG_SIZE + VERIFY_HEADER + + args->sigLen + OPAQUE16_LEN + OPAQUE16_LEN; + ret = EccVerify(ssl, sigOut, args->altSigLen, + args->altSigData, args->altSigDataSz, + (ecc_key*)ssl->hsAltKey, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.altKey + #else + NULL + #endif + ); + } + #endif /* WOLFSSL_DUAL_ALG_CERTS */ + #endif /* HAVE_ECC && WOLFSSL_CHECK_SIG_FAULTS */ /* Check for error */ if (ret != 0) { @@ -9282,7 +9479,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) VERIFY_HEADER, certificate_verify, ssl); args->sendSz = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ + - args->length + HASH_SIG_SIZE + VERIFY_HEADER; + args->length + HASH_SIG_SIZE + VERIFY_HEADER; #ifdef WOLFSSL_DTLS13 if (ssl->options.dtls) args->sendSz += recordLayerHdrExtra + DTLS_HANDSHAKE_EXTRA; @@ -9442,8 +9639,8 @@ typedef struct Dcv13Args { #ifdef WOLFSSL_DUAL_ALG_CERTS byte altSigAlgo; byte* altSigData; - word16 altSigDataSz; - word16 altSignatureSz; + word32 altSigDataSz; + word32 altSignatureSz; byte altPeerAuthGood; #endif } Dcv13Args; @@ -9466,6 +9663,54 @@ static void FreeDcv13Args(WOLFSSL* ssl, void* pArgs) } #ifdef WOLFSSL_DUAL_ALG_CERTS +/* ssl->peerCert->sapkiDer is the alternative public key. Hopefully it is a + * RSA public key. Convert it into a usable public key. */ +static int decodeRsaKey(WOLFSSL* ssl) +{ + int keyRet; + word32 tmpIdx = 0; + + if (ssl->peerRsaKeyPresent) + return INVALID_PARAMETER; + + keyRet = AllocKey(ssl, DYNAMIC_TYPE_RSA, (void**)&ssl->peerRsaKey); + if (keyRet != 0) + return PEER_KEY_ERROR; + + ssl->peerRsaKeyPresent = 1; + keyRet = wc_RsaPublicKeyDecode(ssl->peerCert.sapkiDer, &tmpIdx, + ssl->peerRsaKey, + ssl->peerCert.sapkiLen); + if (keyRet != 0) + return PEER_KEY_ERROR; + + return 0; +} + +/* ssl->peerCert->sapkiDer is the alternative public key. Hopefully it is a + * ECC public key. Convert it into a usable public key. */ +static int decodeEccKey(WOLFSSL* ssl) +{ + int keyRet; + word32 tmpIdx = 0; + + if (ssl->peerEccDsaKeyPresent) + return INVALID_PARAMETER; + + keyRet = AllocKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccDsaKey); + if (keyRet != 0) + return PEER_KEY_ERROR; + + ssl->peerEccDsaKeyPresent = 1; + keyRet = wc_EccPublicKeyDecode(ssl->peerCert.sapkiDer, &tmpIdx, + ssl->peerEccDsaKey, + ssl->peerCert.sapkiLen); + if (keyRet != 0) + return PEER_KEY_ERROR; + + return 0; +} + /* ssl->peerCert->sapkiDer is the alternative public key. Hopefully it is a * dilithium public key. Convert it into a usable public key. */ static int decodeDilithiumKey(WOLFSSL* ssl, int level) @@ -9482,10 +9727,6 @@ static int decodeDilithiumKey(WOLFSSL* ssl, int level) return PEER_KEY_ERROR; ssl->peerDilithiumKeyPresent = 1; - keyRet = wc_dilithium_init(ssl->peerDilithiumKey); - if (keyRet != 0) - return PEER_KEY_ERROR; - keyRet = wc_dilithium_set_level(ssl->peerDilithiumKey, level); if (keyRet != 0) return PEER_KEY_ERROR; @@ -9514,10 +9755,6 @@ static int decodeFalconKey(WOLFSSL* ssl, int level) return PEER_KEY_ERROR; ssl->peerFalconKeyPresent = 1; - keyRet = wc_falcon_init(ssl->peerFalconKey); - if (keyRet != 0) - return PEER_KEY_ERROR; - keyRet = wc_falcon_set_level(ssl->peerFalconKey, level); if (keyRet != 0) return PEER_KEY_ERROR; @@ -9530,7 +9767,7 @@ static int decodeFalconKey(WOLFSSL* ssl, int level) return 0; } -#endif +#endif /* WOLFSSL_DUAL_ALG_CERTS */ /* handle processing TLS v1.3 certificate_verify (15) */ /* Parse and handle a TLS v1.3 CertificateVerify message. @@ -9547,7 +9784,11 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, word32* inOutIdx, word32 totalSz) { int ret = 0; - buffer* sig = &ssl->buffers.sig; + byte* sig = NULL; +#ifndef NO_RSA + /* Use this as a temporary buffer for RSA signature verification. */ + buffer* rsaSigBuf = &ssl->buffers.sig; +#endif #ifdef WOLFSSL_ASYNC_CRYPT Dcv13Args* args = NULL; WOLFSSL_ASSERT_SIZEOF_GE(ssl->async->args, *args); @@ -9634,8 +9875,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, /* If no CKS extension or either native or alternative, then just * get a normal sigalgo. But if BOTH, then get the native and alt * sig algos. */ - if (wolfSSL_is_server(ssl) || - ssl->sigSpec == NULL || + if (ssl->sigSpec == NULL || *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_NATIVE || *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_ALTERNATIVE) { #endif /* WOLFSSL_DUAL_ALG_CERTS */ @@ -9669,8 +9909,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, } #ifdef WOLFSSL_DUAL_ALG_CERTS - if (!wolfSSL_is_server(ssl) && - (ssl->sigSpec != NULL) && + if ((ssl->sigSpec != NULL) && (*ssl->sigSpec != WOLFSSL_CKS_SIGSPEC_NATIVE)) { word16 sa; @@ -9680,6 +9919,12 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, sa = args->altSigAlgo; switch(sa) { + case rsa_pss_sa_algo: + ret = decodeRsaKey(ssl); + break; + case ecc_dsa_sa_algo: + ret = decodeEccKey(ssl); + break; case dilithium_level2_sa_algo: ret = decodeDilithiumKey(ssl, 2); break; @@ -9697,62 +9942,43 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, break; default: ERROR_OUT(PEER_KEY_ERROR, exit_dcv); - break; } if (ret != 0) ERROR_OUT(ret, exit_dcv); if (*ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_ALTERNATIVE) { - /* Now swap in the alternative. We only support hybrid certs - * where native is RSA or ECC so check that either of those - * are present and then remove it. */ - if (ssl->peerRsaKeyPresent && - ssl->peerEccDsaKeyPresent) { - /* They shouldn't both be present. */ - ERROR_OUT(PEER_KEY_ERROR, exit_dcv); - } - else if (ssl->peerRsaKeyPresent) { + /* Now swap in the alternative by removing the native. + * sa contains the alternative signature type. */ + if (ssl->peerRsaKeyPresent && sa != rsa_pss_sa_algo) { FreeKey(ssl, DYNAMIC_TYPE_RSA, (void**)&ssl->peerRsaKey); ssl->peerRsaKeyPresent = 0; } - else if (ssl->peerEccDsaKeyPresent) { + else if (ssl->peerEccDsaKeyPresent && + sa != ecc_dsa_sa_algo) { FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccDsaKey); ssl->peerEccDsaKeyPresent = 0; } - else { - ERROR_OUT(WOLFSSL_NOT_IMPLEMENTED, exit_dcv); + else if (ssl->peerDilithiumKeyPresent && + sa != dilithium_level2_sa_algo && + sa != dilithium_level3_sa_algo && + sa != dilithium_level5_sa_algo) { + FreeKey(ssl, DYNAMIC_TYPE_DILITHIUM, + (void**)&ssl->peerDilithiumKey); + ssl->peerDilithiumKeyPresent = 0; } - } - else if (*ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { - /* Use alternative public key to figure out the expected - * alt sig size. We only support Post-quantum key as SAPKI. - */ - switch(sa) { - case dilithium_level2_sa_algo: - case dilithium_level3_sa_algo: - case dilithium_level5_sa_algo: - ret = wc_dilithium_sig_size(ssl->peerDilithiumKey); - break; - case falcon_level1_sa_algo: - case falcon_level5_sa_algo: - ret = wc_falcon_sig_size(ssl->peerFalconKey); - break; - default: - ERROR_OUT(PEER_KEY_ERROR, exit_dcv); - break; + else if (ssl->peerFalconKeyPresent && + sa != falcon_level1_sa_algo && + sa != falcon_level5_sa_algo) { + FreeKey(ssl, DYNAMIC_TYPE_FALCON, + (void**)&ssl->peerFalconKey); + ssl->peerFalconKeyPresent = 0; } - - if (ret <= 0) { + else { ERROR_OUT(PEER_KEY_ERROR, exit_dcv); } - args->altSignatureSz = ret; - ret = 0; - } - else { - ERROR_OUT(WOLFSSL_NOT_IMPLEMENTED, exit_dcv); } } #endif /* WOLFSSL_DUAL_ALG_CERTS */ @@ -9831,61 +10057,86 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, ERROR_OUT(SIG_VERIFY_E, exit_dcv); } - sig->length = args->sz; + args->sigSz = args->sz; #ifdef WOLFSSL_DUAL_ALG_CERTS - if (!wolfSSL_is_server(ssl) && - ssl->sigSpec != NULL && + if (ssl->sigSpec != NULL && *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { - /* If its RSA, we only hybridize with RSA3072 which has a sig - * size of 384. For ECC, this is actually encoded as an RFC5912 - * formatted signature which means we can use the ASN APIs to - * figure out the length. Note that some post-quantum sig algs - * have variable length signatures (Falcon). That is why we - * don't do: - * sig->length -= args->altSignatureSz; */ - #define RSA3072_SIG_LEN 384 - if (ssl->options.peerSigAlgo == rsa_pss_sa_algo) { - sig->length = RSA3072_SIG_LEN; - } - else if (ssl->options.peerSigAlgo == ecc_dsa_sa_algo) { - word32 tmpIdx = args->idx; - sig->length = wc_SignatureGetSize(WC_SIGNATURE_TYPE_ECC, - ssl->peerEccDsaKey, - sizeof(*ssl->peerEccDsaKey)); - if (GetSequence(input, &tmpIdx, (int*)&sig->length, - args->sz) < 0) { - ERROR_OUT(SIG_VERIFY_E, exit_dcv); - } - /* We have to increment by the size of the header. */ - sig->length += tmpIdx - args->idx; - } - else { - ERROR_OUT(WOLFSSL_NOT_IMPLEMENTED, exit_dcv); + /* In case we received two signatures, both of them are encoded + * with their size as 16-bit integeter prior in memory. Hence, + * we can decode both lengths here now. */ + word32 tmpIdx = args->idx; + ato32(input + tmpIdx, &args->sigSz); + + tmpIdx += OPAQUE16_LEN + args->sigSz; + ato32(input + tmpIdx, &args->altSignatureSz); + + if (args->sz != (args->sigSz + args->altSignatureSz + + OPAQUE16_LEN + OPAQUE16_LEN)) { + ERROR_OUT(BUFFER_ERROR, exit_dcv); } } -#endif +#endif /* WOLFSSL_DUAL_ALG_CERTS */ - sig->buffer = (byte*)XMALLOC(sig->length, ssl->heap, + #if !defined(NO_RSA) && defined(WC_RSA_PSS) + /* In case we have to verify an RSA signature, we have to store the + * signature in the 'rsaSigBuf' structure for further processing. + */ + if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) { + word32 sigSz = args->sigSz; + sig = input + args->idx; + #ifdef WOLFSSL_DUAL_ALG_CERTS + /* Check if our alternative signature was RSA */ + if (ssl->sigSpec != NULL && + *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { + if (ssl->options.peerSigAlgo != rsa_pss_sa_algo) { + /* We have to skip the first signature (length field + * and signature itself) and the length field of the + * alternative signature. */ + sig += OPAQUE16_LEN + OPAQUE16_LEN + args->sigSz; + sigSz = args->altSignatureSz; + } + else { + /* We have to skip the length field */ + sig += OPAQUE16_LEN; + } + } + #endif + rsaSigBuf->buffer = (byte*)XMALLOC(sigSz, ssl->heap, DYNAMIC_TYPE_SIGNATURE); + if (rsaSigBuf->buffer == NULL) { + ERROR_OUT(MEMORY_E, exit_dcv); + } + rsaSigBuf->length = sigSz; + XMEMCPY(rsaSigBuf->buffer, sig, rsaSigBuf->length); + } + #endif /* !NO_RSA && WC_RSA_PSS */ - if (sig->buffer == NULL) { + args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap, + DYNAMIC_TYPE_SIGNATURE); + if (args->sigData == NULL) { ERROR_OUT(MEMORY_E, exit_dcv); } - XMEMCPY(sig->buffer, input + args->idx, sig->length); - #ifdef HAVE_ECC - if (ssl->peerEccDsaKeyPresent) { - WOLFSSL_MSG("Doing ECC peer cert verify"); + ret = CreateSigData(ssl, args->sigData, &args->sigDataSz, 1); + if (ret < 0) + goto exit_dcv; - args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap, + #ifdef WOLFSSL_DUAL_ALG_CERTS + if ((ssl->sigSpec != NULL) && + (*ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH)) { + args->altSigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap, DYNAMIC_TYPE_SIGNATURE); - if (args->sigData == NULL) { + if (args->altSigData == NULL) { ERROR_OUT(MEMORY_E, exit_dcv); } + XMEMCPY(args->altSigData, args->sigData, args->sigDataSz); + args->altSigDataSz = args->sigDataSz; + } + #endif /* WOLFSSL_DUAL_ALG_CERTS */ - ret = CreateSigData(ssl, args->sigData, &args->sigDataSz, 1); - if (ret != 0) - goto exit_dcv; + #ifdef HAVE_ECC + if ((ssl->options.peerSigAlgo == ecc_dsa_sa_algo) && + (ssl->peerEccDsaKeyPresent)) { #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) if (ssl->options.peerSigAlgo != sm2_sa_algo) #endif @@ -9898,68 +10149,21 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, ret = 0; } } - #endif - #ifdef HAVE_ED25519 - if (ssl->peerEd25519KeyPresent) { - WOLFSSL_MSG("Doing ED25519 peer cert verify"); - - args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap, - DYNAMIC_TYPE_SIGNATURE); - if (args->sigData == NULL) { - ERROR_OUT(MEMORY_E, exit_dcv); - } - - ret = CreateSigData(ssl, args->sigData, &args->sigDataSz, 1); - if (ret < 0) - goto exit_dcv; - } - #endif - #ifdef HAVE_ED448 - if (ssl->peerEd448KeyPresent) { - WOLFSSL_MSG("Doing ED448 peer cert verify"); - - args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap, - DYNAMIC_TYPE_SIGNATURE); - if (args->sigData == NULL) { - ERROR_OUT(MEMORY_E, exit_dcv); - } - - ret = CreateSigData(ssl, args->sigData, &args->sigDataSz, 1); - if (ret < 0) - goto exit_dcv; - } - #endif - #ifdef HAVE_PQC - if (ssl->peerFalconKeyPresent || ssl->peerDilithiumKeyPresent) { - word16 sigDataSz; - byte *sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap, - DYNAMIC_TYPE_SIGNATURE); - if (sigData == NULL) { - ERROR_OUT(MEMORY_E, exit_dcv); - } - - ret = CreateSigData(ssl, sigData, &sigDataSz, 1); - if (ret < 0) { - goto exit_dcv; - } -#ifdef WOLFSSL_DUAL_ALG_CERTS - if (!wolfSSL_is_server(ssl) && - ssl->sigSpec != NULL && - *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { - /* In this case (BOTH), the pq sig is the alternative. */ - args->altSigData = sigData; - args->altSigDataSz = sigDataSz; - } - else -#endif /* WOLFSSL_DUAL_ALG_CERTS */ - { - args->sigData = sigData; - args->sigDataSz = sigDataSz; - } - ret = 0; + #ifdef WOLFSSL_DUAL_ALG_CERTS + if ((ssl->sigSpec != NULL) && + (*ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) && + (args->altSigAlgo == ecc_dsa_sa_algo) && + (ssl->peerEccDsaKeyPresent)) { + ret = CreateECCEncodedSig(args->altSigData, + args->altSigDataSz, ssl->options.peerHashAlgo); + if (ret < 0) + goto exit_dcv; + args->altSigDataSz = (word16)ret; + ret = 0; } - #endif + #endif /* WOLFSSL_DUAL_ALG_CERTS */ + #endif /* HAVE_ECC */ /* Advance state and proceed */ ssl->options.asyncState = TLS_ASYNC_DO; @@ -9968,16 +10172,31 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, case TLS_ASYNC_DO: { + sig = input + args->idx; + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ssl->sigSpec != NULL && + *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { + /* As we have two signatures in the message, we stored + * the length of each before the actual signature. This + * is necessary, as we could have two algorithms with + * variable length signatures. */ + sig += OPAQUE16_LEN; + } + #endif #ifndef NO_RSA - if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) { - ret = RsaVerify(ssl, sig->buffer, (word32)sig->length, &args->output, - ssl->options.peerSigAlgo, ssl->options.peerHashAlgo, ssl->peerRsaKey, + if ((ssl->options.peerSigAlgo == rsa_pss_sa_algo) && + (ssl->peerRsaKey != NULL) && (ssl->peerRsaKeyPresent != 0)) { + WOLFSSL_MSG("Doing RSA peer cert verify"); + ret = RsaVerify(ssl, rsaSigBuf->buffer, + (word32)rsaSigBuf->length, &args->output, + ssl->options.peerSigAlgo, + ssl->options.peerHashAlgo, ssl->peerRsaKey, #ifdef HAVE_PK_CALLBACKS - &ssl->buffers.peerRsaKey + &ssl->buffers.peerRsaKey #else - NULL + NULL #endif - ); + ); if (ret >= 0) { args->sendSz = ret; ret = 0; @@ -9985,18 +10204,20 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, } #endif /* !NO_RSA */ #ifdef HAVE_ECC - if (ssl->peerEccDsaKeyPresent) { + if ((ssl->options.peerSigAlgo == ecc_dsa_sa_algo) && + (ssl->peerEccDsaKeyPresent)) { #if defined(WOLFSSL_SM2) && defined(WOLFSSL_SM3) if (ssl->options.peerSigAlgo == sm2_sa_algo) { ret = Sm2wSm3Verify(ssl, TLS13_SM2_SIG_ID, - TLS13_SM2_SIG_ID_SZ, input + args->idx, args->sz, + TLS13_SM2_SIG_ID_SZ, sig, args->sigSz, args->sigData, args->sigDataSz, ssl->peerEccDsaKey, NULL); } else #endif { - ret = EccVerify(ssl, input + args->idx, sig->length, + WOLFSSL_MSG("Doing ECC peer cert verify"); + ret = EccVerify(ssl, sig, args->sigSz, args->sigData, args->sigDataSz, ssl->peerEccDsaKey, #ifdef HAVE_PK_CALLBACKS @@ -10004,21 +10225,24 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, #else NULL #endif - ); + ); } if (ret >= 0) { /* CLIENT/SERVER: data verified with public key from * certificate. */ ssl->options.peerAuthGood = 1; + FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccDsaKey); ssl->peerEccDsaKeyPresent = 0; } } #endif /* HAVE_ECC */ #ifdef HAVE_ED25519 - if (ssl->peerEd25519KeyPresent) { - ret = Ed25519Verify(ssl, input + args->idx, args->sz, + if ((ssl->options.peerSigAlgo == ed25519_sa_algo) && + (ssl->peerEd25519KeyPresent)) { + WOLFSSL_MSG("Doing ED25519 peer cert verify"); + ret = Ed25519Verify(ssl, sig, args->sigSz, args->sigData, args->sigDataSz, ssl->peerEd25519Key, #ifdef HAVE_PK_CALLBACKS @@ -10026,7 +10250,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, #else NULL #endif - ); + ); if (ret >= 0) { /* CLIENT/SERVER: data verified with public key from @@ -10039,8 +10263,10 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, } #endif #ifdef HAVE_ED448 - if (ssl->peerEd448KeyPresent) { - ret = Ed448Verify(ssl, input + args->idx, args->sz, + if ((ssl->options.peerSigAlgo == ed448_sa_algo) && + (ssl->peerEd448KeyPresent)) { + WOLFSSL_MSG("Doing ED448 peer cert verify"); + ret = Ed448Verify(ssl, sig, args->sigSz, args->sigData, args->sigDataSz, ssl->peerEd448Key, #ifdef HAVE_PK_CALLBACKS @@ -10061,44 +10287,19 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, } #endif #if defined(HAVE_PQC) && defined(HAVE_FALCON) - if (ssl->peerFalconKeyPresent) { + if (((ssl->options.peerSigAlgo == falcon_level1_sa_algo) || + (ssl->options.peerSigAlgo == falcon_level5_sa_algo)) && + (ssl->peerFalconKeyPresent)) { int res = 0; - byte *sigIn = input + args->idx; - word32 sigInLen = args->sz; - byte *sigData = args->sigData; - word32 sigDataSz = args->sigDataSz; WOLFSSL_MSG("Doing Falcon peer cert verify"); -#ifdef WOLFSSL_DUAL_ALG_CERTS - if (!wolfSSL_is_server(ssl) && - ssl->sigSpec != NULL && - *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { - /* Note: + sig->length; we are skipping the native sig. */ - sigIn = input + args->idx + sig->length; - sigInLen = args->sz - sig->length; - - /* For RSA, something different was verified. */ - if (ssl->peerRsaKeyPresent) { - sigData = args->altSigData; - sigDataSz = args->altSigDataSz; - } - } -#endif /* WOLFSSL_DUAL_ALG_CERTS */ - ret = wc_falcon_verify_msg(sigIn, sigInLen, - sigData, sigDataSz, + ret = wc_falcon_verify_msg(sig, args->sigSz, + args->sigData, args->sigDataSz, &res, ssl->peerFalconKey); if ((ret >= 0) && (res == 1)) { /* CLIENT/SERVER: data verified with public key from * certificate. */ -#ifdef WOLFSSL_DUAL_ALG_CERTS - if (!wolfSSL_is_server(ssl) && - ssl->sigSpec != NULL && - *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { - args->altPeerAuthGood = 1; - } - else -#endif /* WOLFSSL_DUAL_ALG_CERTS */ - ssl->options.peerAuthGood = 1; + ssl->options.peerAuthGood = 1; FreeKey(ssl, DYNAMIC_TYPE_FALCON, (void**)&ssl->peerFalconKey); @@ -10107,44 +10308,20 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, } #endif /* HAVE_PQC && HAVE_FALCON */ #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) - if (ssl->peerDilithiumKeyPresent) { + if (((ssl->options.peerSigAlgo == dilithium_level2_sa_algo) || + (ssl->options.peerSigAlgo == dilithium_level3_sa_algo) || + (ssl->options.peerSigAlgo == dilithium_level5_sa_algo)) && + (ssl->peerDilithiumKeyPresent)) { int res = 0; - byte *sigIn = input + args->idx; - word32 sigInLen = args->sz; - byte *sigData = args->sigData; - word32 sigDataSz = args->sigDataSz; WOLFSSL_MSG("Doing Dilithium peer cert verify"); -#ifdef WOLFSSL_DUAL_ALG_CERTS - if (!wolfSSL_is_server(ssl) && - ssl->sigSpec != NULL && - *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { - /* Go backwards from the end of the signature the size of - * the alt sig to find the beginning of the alt sig. */ - sigIn = input + args->idx + args->sz - args->altSignatureSz; - sigInLen = args->altSignatureSz; - /* For RSA, something different was verified. */ - if (ssl->peerRsaKeyPresent) { - sigData = args->altSigData; - sigDataSz = args->altSigDataSz; - } - } -#endif /* WOLFSSL_DUAL_ALG_CERTS */ - ret = wc_dilithium_verify_msg(sigIn, sigInLen, - sigData, sigDataSz, + ret = wc_dilithium_verify_msg(sig, args->sigSz, + args->sigData, args->sigDataSz, &res, ssl->peerDilithiumKey); if ((ret >= 0) && (res == 1)) { /* CLIENT/SERVER: data verified with public key from * certificate. */ -#ifdef WOLFSSL_DUAL_ALG_CERTS - if (!wolfSSL_is_server(ssl) && - ssl->sigSpec != NULL && - *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { - args->altPeerAuthGood = 1; - } - else -#endif /* WOLFSSL_DUAL_ALG_CERTS */ - ssl->options.peerAuthGood = 1; + ssl->options.peerAuthGood = 1; FreeKey(ssl, DYNAMIC_TYPE_DILITHIUM, (void**)&ssl->peerDilithiumKey); @@ -10158,6 +10335,110 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, goto exit_dcv; } + #ifdef WOLFSSL_DUAL_ALG_CERTS + if (ssl->sigSpec != NULL && + *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { + /* Move forward to the alternative signature. */ + sig += args->sigSz + OPAQUE16_LEN; + + /* Verify the alternative signature */ + #ifndef NO_RSA + if ((args->altSigAlgo == rsa_pss_sa_algo) && + (ssl->peerRsaKey != NULL) && + (ssl->peerRsaKeyPresent != 0)) { + WOLFSSL_MSG("Doing RSA peer cert alt verify"); + ret = RsaVerify(ssl, rsaSigBuf->buffer, + (word32)rsaSigBuf->length, + &args->output, args->altSigAlgo, + ssl->options.peerHashAlgo, ssl->peerRsaKey, + #ifdef HAVE_PK_CALLBACKS + &ssl->buffers.peerRsaKey + #else + NULL + #endif + ); + if (ret >= 0) { + args->sendSz = ret; + ret = 0; + } + } + #endif /* !NO_RSA */ + #ifdef HAVE_ECC + if ((args->altSigAlgo == ecc_dsa_sa_algo) && + (ssl->peerEccDsaKeyPresent)) { + WOLFSSL_MSG("Doing ECC peer cert alt verify"); + ret = EccVerify(ssl, sig, args->altSignatureSz, + args->altSigData, args->altSigDataSz, + ssl->peerEccDsaKey, + #ifdef HAVE_PK_CALLBACKS + &ssl->buffers.peerEccDsaKey + #else + NULL + #endif + ); + + if (ret >= 0) { + /* CLIENT/SERVER: data verified with public key from + * certificate. */ + args->altPeerAuthGood = 1; + + FreeKey(ssl, DYNAMIC_TYPE_ECC, + (void**)&ssl->peerEccDsaKey); + ssl->peerEccDsaKeyPresent = 0; + } + } + #endif /* HAVE_ECC */ + #if defined(HAVE_PQC) && defined(HAVE_FALCON) + if (((args->altSigAlgo == falcon_level1_sa_algo) || + (args->altSigAlgo == falcon_level5_sa_algo)) && + (ssl->peerFalconKeyPresent)) { + int res = 0; + WOLFSSL_MSG("Doing Falcon peer cert alt verify"); + ret = wc_falcon_verify_msg(sig, args->altSignatureSz, + args->altSigData, args->altSigDataSz, + &res, ssl->peerFalconKey); + + if ((ret >= 0) && (res == 1)) { + /* CLIENT/SERVER: data verified with public key from + * certificate. */ + args->altPeerAuthGood = 1; + + FreeKey(ssl, DYNAMIC_TYPE_FALCON, + (void**)&ssl->peerFalconKey); + ssl->peerFalconKeyPresent = 0; + } + } + #endif /* HAVE_PQC && HAVE_FALCON */ + #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + if (((args->altSigAlgo == dilithium_level2_sa_algo) || + (args->altSigAlgo == dilithium_level3_sa_algo) || + (args->altSigAlgo == dilithium_level5_sa_algo)) && + (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); + + if ((ret >= 0) && (res == 1)) { + /* CLIENT/SERVER: data verified with public key from + * certificate. */ + args->altPeerAuthGood = 1; + + FreeKey(ssl, DYNAMIC_TYPE_DILITHIUM, + (void**)&ssl->peerDilithiumKey); + ssl->peerDilithiumKeyPresent = 0; + } + } + #endif /* HAVE_PQC && HAVE_DILITHIUM */ + + /* Check for error */ + if (ret != 0) { + goto exit_dcv; + } + } + #endif /* WOLFSSL_DUAL_ALG_CERTS */ + /* Advance state and proceed */ ssl->options.asyncState = TLS_ASYNC_VERIFY; } /* case TLS_ASYNC_DO */ @@ -10167,7 +10448,16 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, { #if !defined(NO_RSA) && defined(WC_RSA_PSS) if (ssl->peerRsaKey != NULL && ssl->peerRsaKeyPresent != 0) { - ret = CheckRSASignature(ssl, ssl->options.peerSigAlgo, + int sigAlgo = ssl->options.peerSigAlgo; + #ifdef WOLFSSL_DUAL_ALG_CERTS + /* Check if our alternative signature was RSA */ + if (ssl->sigSpec != NULL && + *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH && + ssl->options.peerSigAlgo != rsa_pss_sa_algo) { + sigAlgo = args->altSigAlgo; + } + #endif + ret = CheckRSASignature(ssl, sigAlgo, ssl->options.peerHashAlgo, args->output, args->sendSz); if (ret != 0) goto exit_dcv; @@ -10176,7 +10466,16 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, * certificate. */ ssl->peerRsaKeyPresent = 0; FreeKey(ssl, DYNAMIC_TYPE_RSA, (void**)&ssl->peerRsaKey); - ssl->options.peerAuthGood = 1; + #ifdef WOLFSSL_DUAL_ALG_CERTS + /* Check if our alternative signature was RSA */ + if (ssl->sigSpec != NULL && + *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH && + ssl->options.peerSigAlgo != rsa_pss_sa_algo) { + args->altPeerAuthGood = 1; + } + else + #endif + ssl->options.peerAuthGood = 1; } #endif /* !NO_RSA && WC_RSA_PSS */ @@ -10188,8 +10487,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, case TLS_ASYNC_FINALIZE: { #ifdef WOLFSSL_DUAL_ALG_CERTS - if (!wolfSSL_is_server(ssl) && - ssl->options.peerAuthGood && + if (ssl->options.peerAuthGood && ssl->sigSpec != NULL && *ssl->sigSpec == WOLFSSL_CKS_SIGSPEC_BOTH) { ssl->options.peerAuthGood = args->altPeerAuthGood; diff --git a/src/wolfio.c b/src/wolfio.c index 041e0b77d8..c7962f47f7 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -78,11 +78,15 @@ #elif !defined(DEVKITPRO) && !defined(WOLFSSL_PICOTCP) \ && !defined(WOLFSSL_CONTIKI) && !defined(WOLFSSL_WICED) \ && !defined(WOLFSSL_GNRC) && !defined(WOLFSSL_RIOT_OS) - #include + #ifdef HAVE_NETDB_H + #include + #endif #ifdef __PPU #include #else - #include + #ifdef HAVE_SYS_IOCTL_H + #include + #endif #endif #endif #endif diff --git a/src/x509.c b/src/x509.c index eefa69cb27..f39df7743f 100644 --- a/src/x509.c +++ b/src/x509.c @@ -10171,6 +10171,15 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref( #endif #ifndef NO_DSA DsaKey* dsa = NULL; + #endif + #if defined(HAVE_PQC) && defined(HAVE_FALCON) + falcon_key* falcon = NULL; + #endif + #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + dilithium_key* dilithium = NULL; + #endif + #if defined(HAVE_PQC) && defined(HAVE_SPHINCS) + sphincs_key* sphincs = NULL; #endif WC_RNG rng; word32 idx = 0; @@ -10297,6 +10306,148 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref( } key = (void*)dsa; } + #endif + #if defined(HAVE_PQC) && defined(HAVE_FALCON) + if ((x509->pubKeyOID == FALCON_LEVEL1k) || + (x509->pubKeyOID == FALCON_LEVEL5k)) { + falcon = (falcon_key*)XMALLOC(sizeof(falcon_key), NULL, + DYNAMIC_TYPE_FALCON); + if (falcon == NULL) { + WOLFSSL_MSG("Failed to allocate memory for falcon_key"); + XFREE(cert, NULL, DYNAMIC_TYPE_CERT); + return WOLFSSL_FAILURE; + } + + ret = wc_falcon_init(falcon); + if (ret != 0) { + XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON); + XFREE(cert, NULL, DYNAMIC_TYPE_CERT); + return ret; + } + + if (x509->pubKeyOID == FALCON_LEVEL1k) { + type = FALCON_LEVEL1_TYPE; + wc_falcon_set_level(falcon, 1); + } + else if (x509->pubKeyOID == FALCON_LEVEL5k) { + type = FALCON_LEVEL5_TYPE; + wc_falcon_set_level(falcon, 5); + } + + ret = wc_Falcon_PublicKeyDecode(x509->pubKey.buffer, &idx, falcon, + x509->pubKey.length); + if (ret != 0) { + WOLFSSL_ERROR_VERBOSE(ret); + wc_falcon_free(falcon); + XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON); + XFREE(cert, NULL, DYNAMIC_TYPE_CERT); + return ret; + } + key = (void*)falcon; + } + #endif + #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + if ((x509->pubKeyOID == DILITHIUM_LEVEL2k) || + (x509->pubKeyOID == DILITHIUM_LEVEL3k) || + (x509->pubKeyOID == DILITHIUM_LEVEL5k)) { + dilithium = (dilithium_key*)XMALLOC(sizeof(dilithium_key), NULL, + DYNAMIC_TYPE_DILITHIUM); + if (dilithium == NULL) { + WOLFSSL_MSG("Failed to allocate memory for dilithium_key"); + XFREE(cert, NULL, DYNAMIC_TYPE_CERT); + return WOLFSSL_FAILURE; + } + + ret = wc_dilithium_init(dilithium); + if (ret != 0) { + XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM); + XFREE(cert, NULL, DYNAMIC_TYPE_CERT); + return ret; + } + + if (x509->pubKeyOID == DILITHIUM_LEVEL2k) { + type = DILITHIUM_LEVEL2_TYPE; + wc_dilithium_set_level(dilithium, 2); + } + else if (x509->pubKeyOID == DILITHIUM_LEVEL3k) { + type = DILITHIUM_LEVEL3_TYPE; + wc_dilithium_set_level(dilithium, 3); + } + else if (x509->pubKeyOID == DILITHIUM_LEVEL5k) { + type = DILITHIUM_LEVEL5_TYPE; + wc_dilithium_set_level(dilithium, 5); + } + + ret = wc_Dilithium_PublicKeyDecode(x509->pubKey.buffer, &idx, + dilithium, x509->pubKey.length); + if (ret != 0) { + WOLFSSL_ERROR_VERBOSE(ret); + wc_dilithium_free(dilithium); + XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM); + XFREE(cert, NULL, DYNAMIC_TYPE_CERT); + return ret; + } + key = (void*)dilithium; + } + #endif + #if defined(HAVE_PQC) && defined(HAVE_SPHINCS) + if ((x509->pubKeyOID == SPHINCS_FAST_LEVEL1k) || + (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) || + (x509->pubKeyOID == SPHINCS_FAST_LEVEL5k) || + (x509->pubKeyOID == SPHINCS_SMALL_LEVEL1k) || + (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) || + (x509->pubKeyOID == SPHINCS_SMALL_LEVEL5k)) { + sphincs = (sphincs_key*)XMALLOC(sizeof(sphincs_key), NULL, + DYNAMIC_TYPE_SPHINCS); + if (sphincs == NULL) { + WOLFSSL_MSG("Failed to allocate memory for sphincs_key"); + XFREE(cert, NULL, DYNAMIC_TYPE_CERT); + return WOLFSSL_FAILURE; + } + + ret = wc_sphincs_init(sphincs); + if (ret != 0) { + XFREE(sphincs, NULL, DYNAMIC_TYPE_SPHINCS); + XFREE(cert, NULL, DYNAMIC_TYPE_CERT); + return ret; + } + + if (x509->pubKeyOID == SPHINCS_FAST_LEVEL1k) { + type = SPHINCS_FAST_LEVEL1_TYPE; + wc_sphincs_set_level_and_optim(sphincs, 1, FAST_VARIANT); + } + else if (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) { + type = SPHINCS_FAST_LEVEL3_TYPE; + wc_sphincs_set_level_and_optim(sphincs, 3, FAST_VARIANT); + } + else if (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) { + type = SPHINCS_FAST_LEVEL5_TYPE; + wc_sphincs_set_level_and_optim(sphincs, 5, FAST_VARIANT); + } + else if (x509->pubKeyOID == SPHINCS_SMALL_LEVEL1k) { + type = SPHINCS_SMALL_LEVEL1_TYPE; + wc_sphincs_set_level_and_optim(sphincs, 1, SMALL_VARIANT); + } + else if (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) { + type = SPHINCS_SMALL_LEVEL3_TYPE; + wc_sphincs_set_level_and_optim(sphincs, 3, SMALL_VARIANT); + } + else if (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) { + type = SPHINCS_SMALL_LEVEL5_TYPE; + wc_sphincs_set_level_and_optim(sphincs, 5, SMALL_VARIANT); + } + + ret = wc_Sphincs_PublicKeyDecode(x509->pubKey.buffer, &idx, sphincs, + x509->pubKey.length); + if (ret != 0) { + WOLFSSL_ERROR_VERBOSE(ret); + wc_sphincs_free(sphincs); + XFREE(sphincs, NULL, DYNAMIC_TYPE_SPHINCS); + XFREE(cert, NULL, DYNAMIC_TYPE_CERT); + return ret; + } + key = (void*)sphincs; + } #endif if (key == NULL) { WOLFSSL_MSG("No public key found for certificate"); @@ -10397,6 +10548,32 @@ WOLF_STACK_OF(WOLFSSL_X509)* wolfSSL_X509_chain_up_ref( wc_FreeDsaKey(dsa); XFREE(dsa, NULL, DYNAMIC_TYPE_DSA); } + #endif + #if defined(HAVE_PQC) && defined(HAVE_FALCON) + if ((x509->pubKeyOID == FALCON_LEVEL1k) || + (x509->pubKeyOID == FALCON_LEVEL5k)) { + wc_falcon_free(falcon); + XFREE(falcon, NULL, DYNAMIC_TYPE_FALCON); + } + #endif + #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + if ((x509->pubKeyOID == DILITHIUM_LEVEL2k) || + (x509->pubKeyOID == DILITHIUM_LEVEL3k) || + (x509->pubKeyOID == DILITHIUM_LEVEL5k)) { + wc_dilithium_free(dilithium); + XFREE(dilithium, NULL, DYNAMIC_TYPE_DILITHIUM); + } + #endif + #if defined(HAVE_PQC) && defined(HAVE_SPHINCS) + if ((x509->pubKeyOID == SPHINCS_FAST_LEVEL1k) || + (x509->pubKeyOID == SPHINCS_FAST_LEVEL3k) || + (x509->pubKeyOID == SPHINCS_FAST_LEVEL5k) || + (x509->pubKeyOID == SPHINCS_SMALL_LEVEL1k) || + (x509->pubKeyOID == SPHINCS_SMALL_LEVEL3k) || + (x509->pubKeyOID == SPHINCS_SMALL_LEVEL5k)) { + wc_sphincs_free(sphincs); + XFREE(sphincs, NULL, DYNAMIC_TYPE_SPHINCS); + } #endif XFREE(cert, NULL, DYNAMIC_TYPE_CERT); diff --git a/tests/api.c b/tests/api.c index c6c6cc90b4..cb309db433 100644 --- a/tests/api.c +++ b/tests/api.c @@ -878,7 +878,10 @@ static int do_dual_alg_root_certgen(byte **out, char *caKeyFile, XMEMSET(caKeyBuf, 0, caKeySz); ExpectNotNull(file = fopen(caKeyFile, "rb")); ExpectIntGT(caKeySz = (word32)fread(caKeyBuf, 1, caKeySz, file), 0); - fclose(file); + if (file) { + fclose(file); + file = NULL; + } ExpectIntEQ(wc_InitRsaKey_ex(&caKey, NULL, INVALID_DEVID), 0); idx = 0; ExpectIntEQ(wc_RsaPrivateKeyDecode(caKeyBuf, &idx, &caKey, caKeySz), @@ -886,11 +889,17 @@ static int do_dual_alg_root_certgen(byte **out, char *caKeyFile, XMEMSET(sapkiBuf, 0, sapkiSz); ExpectNotNull(file = fopen(sapkiFile, "rb")); ExpectIntGT(sapkiSz = (word32)fread(sapkiBuf, 1, sapkiSz, file), 0); - fclose(file); + if (file) { + fclose(file); + file = NULL; + } XMEMSET(altPrivBuf, 0, altPrivSz); ExpectNotNull(file = fopen(altPrivFile, "rb")); ExpectIntGT(altPrivSz = (word32)fread(altPrivBuf, 1, altPrivSz, file), 0); - fclose(file); + if (file) { + fclose(file); + file = NULL; + } wc_ecc_init(&altCaKey); idx = 0; ExpectIntEQ(wc_EccPrivateKeyDecode(altPrivBuf, &idx, &altCaKey, @@ -938,6 +947,7 @@ static int do_dual_alg_root_certgen(byte **out, char *caKeyFile, *out = outBuf; wc_FreeRsaKey(&caKey); wc_FreeRng(&rng); + wc_FreeDecodedCert(&preTBS); return outSz; } @@ -981,7 +991,10 @@ static int do_dual_alg_server_certgen(byte **out, char *caKeyFile, ExpectNotNull(file = fopen(serverKeyFile, "rb")); ExpectIntGT(serverKeySz = (word32)fread(serverKeyBuf, 1, serverKeySz, file), 0); - fclose(file); + if (file) { + fclose(file); + file = NULL; + } ExpectIntEQ(wc_InitRsaKey_ex(&serverKey, NULL, INVALID_DEVID), 0); idx = 0; ExpectIntEQ(wc_RsaPrivateKeyDecode(serverKeyBuf, &idx, &serverKey, @@ -989,7 +1002,10 @@ static int do_dual_alg_server_certgen(byte **out, char *caKeyFile, XMEMSET(caKeyBuf, 0, caKeySz); ExpectNotNull(file = fopen(caKeyFile, "rb")); ExpectIntGT(caKeySz = (word32)fread(caKeyBuf, 1, caKeySz, file), 0); - fclose(file); + if (file) { + fclose(file); + file = NULL; + } ExpectIntEQ(wc_InitRsaKey_ex(&caKey, NULL, INVALID_DEVID), 0); idx = 0; ExpectIntEQ(wc_RsaPrivateKeyDecode(caKeyBuf, &idx, &caKey, @@ -997,11 +1013,17 @@ static int do_dual_alg_server_certgen(byte **out, char *caKeyFile, XMEMSET(sapkiBuf, 0, sapkiSz); ExpectNotNull(file = fopen(sapkiFile, "rb")); ExpectIntGT(sapkiSz = (word32)fread(sapkiBuf, 1, sapkiSz, file), 0); - fclose(file); + if (file) { + fclose(file); + file = NULL; + } XMEMSET(altPrivBuf, 0, altPrivSz); ExpectNotNull(file = fopen(altPrivFile, "rb")); ExpectIntGT(altPrivSz = (word32)fread(altPrivBuf, 1, altPrivSz, file), 0); - fclose(file); + if (file) { + fclose(file); + file = NULL; + } wc_ecc_init(&altCaKey); idx = 0; ExpectIntEQ(wc_EccPrivateKeyDecode(altPrivBuf, &idx, &altCaKey, @@ -1052,6 +1074,7 @@ static int do_dual_alg_server_certgen(byte **out, char *caKeyFile, wc_FreeRsaKey(&caKey); wc_FreeRsaKey(&serverKey); wc_FreeRng(&rng); + wc_FreeDecodedCert(&preTBS); return outSz; } @@ -1136,7 +1159,9 @@ static int test_dual_alg_support(void) /* Now we try a negative case. Note that we use wrongPrivFile to generate * the alternative signature and then set negative_test to true for the * call to do_dual_alg_tls13_connection(). Its expecting a failed connection - * because the signature won't verify. */ + * because the signature won't verify. The exception is if + * WOLFSSL_TRUST_PEER_CERT is defined. In that case, no verfication happens + * and this is no longer a negative test. */ rootSz = do_dual_alg_root_certgen(&root, keyFile, sapkiFile, wrongPrivFile); ExpectNotNull(root); ExpectIntGT(rootSz, 0); @@ -1144,9 +1169,15 @@ static int test_dual_alg_support(void) wrongPrivFile, keyFile, root, rootSz); ExpectNotNull(server); ExpectIntGT(serverSz, 0); +#ifdef WOLFSSL_TRUST_PEER_CERT + ExpectIntEQ(do_dual_alg_tls13_connection(root, rootSz, + server, serverSz, serverKey, (word32)serverKeySz, 0), + TEST_SUCCESS); +#else ExpectIntEQ(do_dual_alg_tls13_connection(root, rootSz, server, serverSz, serverKey, (word32)serverKeySz, 1), TEST_SUCCESS); +#endif /* Lets see if CertManager can find the new extensions */ extCount = 0; @@ -1156,7 +1187,7 @@ static int test_dual_alg_support(void) SSL_FILETYPE_ASN1), WOLFSSL_SUCCESS); ExpectIntEQ(wolfSSL_CertManagerVerifyBuffer(cm, server, serverSz, SSL_FILETYPE_ASN1), WOLFSSL_SUCCESS); - /* There is only 1 unknown exension (1.2.3.4.5). The other ones are known + /* There is only 1 unknown extension (1.2.3.4.5). The other ones are known * because they are for the dual alg extensions. */ ExpectIntEQ(extCount, 1); wolfSSL_CertManagerFree(cm); @@ -67467,7 +67498,7 @@ static int test_tls13_rpk_handshake(void) certType_s[1] = WOLFSSL_CERT_TYPE_X509; typeCnt_s = 2; - /* both clien and server do not call client/server_cert_type APIs, + /* both client and server do not call client/server_cert_type APIs, * expecting default settings works and no negotiation performed. */ @@ -67489,6 +67520,9 @@ static int test_tls13_rpk_handshake(void) WOLFSSL_SUCCESS); ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_UNKNOWN); + (void)typeCnt_c; + (void)typeCnt_s; + wolfSSL_free(ssl_c); wolfSSL_CTX_free(ctx_c); wolfSSL_free(ssl_s); @@ -67520,7 +67554,7 @@ static int test_tls13_rpk_handshake(void) certType_s[1] = WOLFSSL_CERT_TYPE_X509; typeCnt_s = 2; - /* both clien and server do not call client/server_cert_type APIs, + /* both client and server do not call client/server_cert_type APIs, * expecting default settings works and no negotiation performed. */ @@ -67544,6 +67578,9 @@ static int test_tls13_rpk_handshake(void) WOLFSSL_SUCCESS); ExpectIntEQ(tp, WOLFSSL_CERT_TYPE_UNKNOWN); + (void)typeCnt_c; + (void)typeCnt_s; + wolfSSL_free(ssl_c); wolfSSL_CTX_free(ctx_c); wolfSSL_free(ssl_s); @@ -67702,12 +67739,9 @@ static int test_tls13_rpk_handshake(void) svrKeyFile, WOLFSSL_FILETYPE_PEM ) , 0); - /* set client certificate type in client end */ - certType_c[0] = WOLFSSL_CERT_TYPE_RPK; - certType_c[1] = WOLFSSL_CERT_TYPE_X509; - typeCnt_c = 2; - - /* client indicates both RPK and x509 certs are available but loaded RPK + /* set client certificate type in client end + * + * client indicates both RPK and x509 certs are available but loaded RPK * cert only. It does not have client add client-cert-type extension in CH. */ certType_c[0] = WOLFSSL_CERT_TYPE_RPK; diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 2f51aeffc4..61e51a36e5 100644 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -1378,9 +1378,9 @@ static const char* bench_result_words3[][5] = { /* unsigned int max = 4,294,967,295 */ uint64_t thisVal = 0; /* CPU counter, "this current value" as read. */ uint64_t thisIncrement = 0; /* The adjusted increment amount. */ - uint64_t expected_diff = 0; /* FreeRTOS esimated expected CPU diff. */ + uint64_t expected_diff = 0; /* FreeRTOS estimated expected CPU diff.*/ #ifdef DEBUG_WOLFSSL_BENCHMARK_TIMING - uint32_t tickCount = 0; /* Currrent rtos tick counter. */ + uint32_t tickCount = 0; /* Current rtos tick counter. */ uint32_t tickDiff = 0; /* Tick difference from last check. */ uint32_t tickBeginDiff = 0; /* Tick difference from beginning. */ #endif @@ -1459,7 +1459,7 @@ static const char* bench_result_words3[][5] = { if (expected_diff > UINT_MAX) { /* The number of cycles expected from FreeRTOS ticks is * greater than the maximum size of an unsigned 32-bit - * integer, meaning multiple overflows occured. */ + * integer, meaning multiple overflows occurred. */ #ifdef DEBUG_WOLFSSL_BENCHMARK_TIMING ESP_LOGW(TAG, "expected_diff > UINT_MAX (%u)", UINT_MAX); #endif @@ -1538,7 +1538,7 @@ static const char* bench_result_words3[][5] = { _esp_cpu_count_last = esp_cpu_get_cycle_count(); #else /* TODO: Why doesn't esp_cpu_get_cycle_count work for Xtensa - * when resetting CPU cycle counter? FreeRTOS tick collison? + * when resetting CPU cycle counter? FreeRTOS tick collision? * thisVal = esp_cpu_get_cycle_count(); See also, above * or thisVal = xthal_get_ccount(); */ #if ESP_IDF_VERSION_MAJOR < 5 @@ -12998,13 +12998,13 @@ void bench_sphincsKeySign(byte level, byte optim) double current_time(int reset) { + int64_t t; (void)reset; - #if defined(CONFIG_ARCH_POSIX) k_cpu_idle(); #endif - - return (double)k_uptime_get() / 1000; + t = k_uptime_get(); /* returns current uptime in milliseconds */ + return (double)(t / 1000); } #elif defined(WOLFSSL_NETBURNER) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ac50995875..97c6e367f0 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -1209,8 +1209,8 @@ static int GetASN_ObjectId(const byte* input, word32 idx, int length) #endif ret = ASN_PARSE_E; } - /* Last octet of a subidentifier has bit 8 clear. Last octet must be last - * of a subidentifier. Ensure last octet hasn't got top bit set indicating. + /* 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. */ else if ((input[(int)idx + length - 1] & 0x80) != 0x00) { WOLFSSL_MSG("OID last octet has top bit set"); @@ -7770,17 +7770,59 @@ int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz, * return 1 (true) on match * return 0 or negative value on failure/error * - * key : buffer holding DER format key - * keySz : size of key buffer - * der : a initialized and parsed DecodedCert holding a certificate */ -int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der) + * key : buffer holding DER format key + * keySz : size of key buffer + * der : a initialized and parsed DecodedCert holding a certificate + * checkAlt : indicate if we check primary or alternative key + */ +int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der, + int checkAlt) { + int ret = 0; + if (key == NULL || der == NULL) { return BAD_FUNC_ARG; } - return wc_CheckPrivateKey(key, keySz, der->publicKey, - der->pubKeySize, (enum Key_Sum) der->keyOID); +#ifdef WOLFSSL_DUAL_ALG_CERTS + if (checkAlt && der->sapkiDer != NULL) { + /* We have to decode the public key first */ + word32 idx = 0; + /* Dilithium has the largest public key at the moment */ + word32 pubKeyLen = DILITHIUM_MAX_PUB_KEY_SIZE; + byte* decodedPubKey = (byte*)XMALLOC(pubKeyLen, NULL, + DYNAMIC_TYPE_PUBLIC_KEY); + if (decodedPubKey == NULL) { + ret = MEMORY_E; + } + if (ret == 0) { + if (der->sapkiOID == RSAk || der->sapkiOID == ECDSAk) { + /* Simply copy the data */ + XMEMCPY(decodedPubKey, der->sapkiDer, der->sapkiLen); + pubKeyLen = der->sapkiLen; + } + else { + ret = DecodeAsymKeyPublic(der->sapkiDer, &idx, der->sapkiLen, + decodedPubKey, &pubKeyLen, + der->sapkiOID); + } + } + if (ret == 0) { + ret = wc_CheckPrivateKey(key, keySz, decodedPubKey, pubKeyLen, + (enum Key_Sum) der->sapkiOID); + } + XFREE(decodedPubKey, NULL, DYNAMIC_TYPE_PUBLIC_KEY); + } + else +#endif + { + ret = wc_CheckPrivateKey(key, keySz, der->publicKey, + der->pubKeySize, (enum Key_Sum) der->keyOID); + } + + (void)checkAlt; + + return ret; } #endif /* HAVE_PKCS12 || !NO_CHECK_PRIVATE_KEY */ @@ -15585,8 +15627,15 @@ int DecodeToKey(DecodedCert* cert, int verify) int ret; int badDate = 0; +#ifdef WOLFSSL_DUAL_ALG_CERTS + /* Call internal version and decode completely to also handle extensions. + * This is required to parse a potential alternative public key in the + * SubjectAlternativeKey extension. */ + ret = DecodeCertInternal(cert, verify, NULL, &badDate, 0, 0); +#else /* Call internal version and stop after public key. */ ret = DecodeCertInternal(cert, verify, NULL, &badDate, 0, 1); +#endif /* Always return date errors. */ if (ret == 0) { ret = badDate; @@ -21072,7 +21121,13 @@ static int DecodeExtensionType(const byte* input, word32 length, word32 oid, ret = ASN_PARSE_E; } #else - WOLFSSL_MSG("Certificate Policy extension not supported yet."); + WOLFSSL_MSG("Certificate Policy extension not supported."); + #ifndef WOLFSSL_NO_ASN_STRICT + if (critical) { + WOLFSSL_ERROR_VERBOSE(ASN_CRIT_EXT_E); + ret = ASN_CRIT_EXT_E; + } + #endif #endif break; @@ -23753,6 +23808,45 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) WOLFSSL_ERROR_VERBOSE(ret); return ret; } + + #ifdef WOLFSSL_DUAL_ALG_CERTS + if ((ret == 0) && cert->extAltSigAlgSet && + cert->extAltSigValSet) { + #ifndef WOLFSSL_SMALL_STACK + byte der[MAX_CERT_VERIFY_SZ]; + #else + byte *der = (byte*)XMALLOC(MAX_CERT_VERIFY_SZ, ssl->heap, + DYNAMIC_TYPE_DCERT); + if (der == NULL) { + ret = MEMORY_E; + } else + #endif /* ! WOLFSSL_SMALL_STACK */ + + { + ret = wc_GeneratePreTBS(cert, der, MAX_CERT_VERIFY_SZ); + + if (ret > 0) { + ret = ConfirmSignature(&cert->sigCtx, der, ret, + cert->ca->sapkiDer, cert->ca->sapkiLen, + cert->ca->sapkiOID, cert->altSigValDer, + cert->altSigValLen, cert->altSigAlgOID, + NULL, 0, NULL); + } + #ifdef WOLFSSL_SMALL_STACK + XFREE(der, ssl->heap, DYNAMIC_TYPE_DCERT); + #endif /* WOLFSSL_SMALL_STACK */ + + if (ret != 0) { + WOLFSSL_MSG("Confirm alternative signature failed"); + WOLFSSL_ERROR_VERBOSE(ret); + return ret; + } + else { + WOLFSSL_MSG("Alt signature has been verified!"); + } + } + } + #endif /* WOLFSSL_DUAL_ALG_CERTS */ } #ifndef IGNORE_NAME_CONSTRAINTS if (verify == VERIFY || verify == VERIFY_OCSP || @@ -23852,6 +23946,9 @@ void FreeSigner(Signer* signer, void* heap) (void)heap; XFREE(signer->name, heap, DYNAMIC_TYPE_SUBJECT_CN); XFREE((void*)signer->publicKey, heap, DYNAMIC_TYPE_PUBLIC_KEY); +#ifdef WOLFSSL_DUAL_ALG_CERTS + XFREE(signer->sapkiDer, heap, DYNAMIC_TYPE_PUBLIC_KEY); +#endif #ifndef IGNORE_NAME_CONSTRAINTS if (signer->permittedNames) FreeNameSubtrees(signer->permittedNames, heap); @@ -25937,11 +26034,16 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) { #ifndef WOLFSSL_ASN_TEMPLATE int ret = 0, i; + int mpSz; word32 seqSz = 0, verSz = 0, intTotalLen = 0, outLen = 0; word32 sizes[RSA_INTS]; byte seq[MAX_SEQ_SZ]; byte ver[MAX_VERSION_SZ]; + mp_int* keyInt; +#ifndef WOLFSSL_NO_MALLOC + word32 rawLen; byte* tmps[RSA_INTS]; +#endif if (key == NULL) return BAD_FUNC_ARG; @@ -25949,18 +26051,18 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) if (key->type != RSA_PRIVATE) return BAD_FUNC_ARG; +#ifndef WOLFSSL_NO_MALLOC for (i = 0; i < RSA_INTS; i++) tmps[i] = NULL; +#endif /* write all big ints from key to DER tmps */ for (i = 0; i < RSA_INTS; i++) { - mp_int* keyInt = GetRsaInt(key, i); - int mpSz; - word32 rawLen; - + keyInt = GetRsaInt(key, i); ret = mp_unsigned_bin_size(keyInt); if (ret < 0) - return ret; + break; +#ifndef WOLFSSL_NO_MALLOC rawLen = (word32)ret + 1; ret = 0; if (output != NULL) { @@ -25971,8 +26073,11 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) break; } } - mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, tmps[i]); +#else + ret = 0; + mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, NULL); +#endif if (mpSz < 0) { ret = mpSz; break; @@ -26004,15 +26109,33 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) j += verSz; for (i = 0; i < RSA_INTS; i++) { +/* copy from tmps if we have malloc, otherwise re-export with buffer */ +#ifndef WOLFSSL_NO_MALLOC XMEMCPY(output + j, tmps[i], sizes[i]); j += sizes[i]; +#else + keyInt = GetRsaInt(key, i); + ret = mp_unsigned_bin_size(keyInt); + if (ret < 0) + break; + ret = 0; + /* This won't overrun output due to the outLen check above */ + mpSz = SetASNIntMP(keyInt, MAX_RSA_INT_SZ, output + j); + if (mpSz < 0) { + ret = mpSz; + break; + } + j += mpSz; +#endif } } +#ifndef WOLFSSL_NO_MALLOC for (i = 0; i < RSA_INTS; i++) { if (tmps[i]) XFREE(tmps[i], key->heap, DYNAMIC_TYPE_RSA); } +#endif if (ret == 0) ret = (int)outLen; @@ -27565,6 +27688,17 @@ static int EncodeName(EncodedName* name, const char* nameStr, ret = BAD_FUNC_ARG; } +#ifdef WOLFSSL_CUSTOM_OID + if (ret == 0 && type == ASN_CUSTOM_NAME) { + if (cname == NULL || cname->custom.oidSz == 0) { + name->used = 0; + return 0; + } + } +#else + (void)cname; +#endif + CALLOC_ASNSETDATA(dataASN, rdnASN_Length, ret, NULL); if (ret == 0) { nameSz = (word32)XSTRLEN(nameStr); @@ -28164,7 +28298,8 @@ int SetName(byte* output, word32 outputSz, CertName* name) static int EncodePublicKey(int keyType, byte* output, int outLen, RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, ed448_key* ed448Key, - DsaKey* dsaKey) + DsaKey* dsaKey, falcon_key* falconKey, + dilithium_key* dilithiumKey, sphincs_key* sphincsKey) { int ret = 0; @@ -28174,6 +28309,9 @@ static int EncodePublicKey(int keyType, byte* output, int outLen, (void)ed25519Key; (void)ed448Key; (void)dsaKey; + (void)falconKey; + (void)dilithiumKey; + (void)sphincsKey; switch (keyType) { #ifndef NO_RSA @@ -28209,6 +28347,41 @@ static int EncodePublicKey(int keyType, byte* output, int outLen, } break; #endif + #if defined(HAVE_PQC) && defined(HAVE_FALCON) + case FALCON_LEVEL1_KEY: + case FALCON_LEVEL5_KEY: + ret = wc_Falcon_PublicKeyToDer(falconKey, output, + (word32)outLen, 1); + if (ret <= 0) { + ret = PUBLIC_KEY_E; + } + break; + #endif /* HAVE_PQC && HAVE_FALCON */ + #if defined(HAVE_PQC) && defined(HAVE_DILITHIUM) + case DILITHIUM_LEVEL2_KEY: + case DILITHIUM_LEVEL3_KEY: + case DILITHIUM_LEVEL5_KEY: + ret = wc_Dilithium_PublicKeyToDer(dilithiumKey, output, + (word32)outLen, 1); + if (ret <= 0) { + ret = PUBLIC_KEY_E; + } + break; + #endif /* HAVE_PQC && HAVE_DILITHIUM */ + #if defined(HAVE_PQC) && defined(HAVE_SPHINCS) + case SPHINCS_FAST_LEVEL1_KEY: + case SPHINCS_FAST_LEVEL3_KEY: + case SPHINCS_FAST_LEVEL5_KEY: + case SPHINCS_SMALL_LEVEL1_KEY: + case SPHINCS_SMALL_LEVEL3_KEY: + case SPHINCS_SMALL_LEVEL5_KEY: + ret = wc_Sphincs_PublicKeyToDer(sphincsKey, output, + (word32)outLen, 1); + if (ret <= 0) { + ret = PUBLIC_KEY_E; + } + break; + #endif /* HAVE_PQC && HAVE_SPHINCS */ default: ret = PUBLIC_KEY_E; break; @@ -29975,7 +30148,8 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, if (ret >= 0) { /* Calculate public key encoding size. */ ret = EncodePublicKey(cert->keyType, NULL, 0, rsaKey, - eccKey, ed25519Key, ed448Key, dsaKey); + eccKey, ed25519Key, ed448Key, dsaKey, falconKey, + dilithiumKey, sphincsKey); publicKeySz = (word32)ret; } if (ret >= 0) { @@ -30155,7 +30329,8 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, .data.buffer.data, (int)dataASN[X509CERTASN_IDX_TBS_SPUBKEYINFO_SEQ] .data.buffer.length, - rsaKey, eccKey, ed25519Key, ed448Key, dsaKey); + rsaKey, eccKey, ed25519Key, ed448Key, dsaKey, + falconKey, dilithiumKey, sphincsKey); } if ((ret >= 0) && (!dataASN[X509CERTASN_IDX_TBS_EXT_SEQ].noOut)) { /* Encode extensions into buffer. */ @@ -30236,6 +30411,7 @@ int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, NULL, NULL, NULL, NULL); } + #ifdef WOLFSSL_CERT_REQ #ifndef WOLFSSL_ASN_TEMPLATE @@ -31022,7 +31198,8 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, if (ret >= 0) { /* Determine encode public key size. */ ret = EncodePublicKey(cert->keyType, NULL, 0, rsaKey, - eccKey, ed25519Key, ed448Key, dsaKey); + eccKey, ed25519Key, ed448Key, dsaKey, falconKey, + dilithiumKey, sphincsKey); publicKeySz = (word32)ret; } if (ret >= 0) { @@ -31136,7 +31313,8 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, ret = EncodePublicKey(cert->keyType, (byte*)dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.data, (int)dataASN[CERTREQBODYASN_IDX_SPUBKEYINFO_SEQ].data.buffer.length, - rsaKey, eccKey, ed25519Key, ed448Key, dsaKey); + rsaKey, eccKey, ed25519Key, ed448Key, dsaKey, falconKey, + dilithiumKey, sphincsKey); } if ((ret >= 0 && derBuffer != NULL) && (!dataASN[CERTREQBODYASN_IDX_EXT_BODY].noOut)) { @@ -31460,6 +31638,7 @@ int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz, NULL, NULL, NULL, rng); } + WOLFSSL_ABI int wc_MakeSelfCert(Cert* cert, byte* buf, word32 buffSz, RsaKey* key, WC_RNG* rng) diff --git a/wolfcrypt/src/dilithium.c b/wolfcrypt/src/dilithium.c index f8968c5614..f2e241b54a 100644 --- a/wolfcrypt/src/dilithium.c +++ b/wolfcrypt/src/dilithium.c @@ -290,7 +290,7 @@ int wc_dilithium_init_id(dilithium_key* key, const unsigned char* id, int len, key->idLen = len; } - /* Set the maxiumum level here */ + /* Set the maximum level here */ wc_dilithium_set_level(key, 5); return ret; @@ -317,7 +317,7 @@ int wc_dilithium_init_label(dilithium_key* key, const char* label, void* heap, key->labelLen = labelLen; } - /* Set the maxiumum level here */ + /* Set the maximum level here */ wc_dilithium_set_level(key, 5); return ret; @@ -395,7 +395,7 @@ int wc_dilithium_export_public(dilithium_key* key, return BAD_FUNC_ARG; } - if ((key->level != 1) && (key->level != 5)) { + if ((key->level != 2) && (key->level != 3) && (key->level != 5)) { return BAD_FUNC_ARG; } @@ -914,11 +914,11 @@ int wc_Dilithium_PrivateKeyDecode(const byte* input, word32* inOutIdx, pubKey, &pubKeyLen, keytype); if (ret == 0) { if (pubKeyLen == 0) { - ret = wc_dilithium_import_private_only(input, inSz, key); + ret = wc_dilithium_import_private_key(input, inSz, NULL, 0, key); } else { - ret = wc_dilithium_import_private_key(privKey, privKeyLen, - pubKey, pubKeyLen, key); + ret = wc_dilithium_import_private_key(input, inSz, pubKey, + pubKeyLen, key); } } return ret; @@ -983,7 +983,7 @@ int wc_Dilithium_PublicKeyToDer(dilithium_key* key, byte* output, word32 inLen, word32 pubKeyLen = (word32)sizeof(pubKey); int keytype = 0; - if (key == NULL || output == NULL) { + if (key == NULL) { return BAD_FUNC_ARG; } diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 78101ed2cb..524210421d 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -2617,6 +2617,7 @@ int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a, */ int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct) { + int err = MP_OKAY; #if !defined(WOLFSSL_SP_MATH) DECL_MP_INT_SIZE_DYN(t1, mp_bitsused(modulus), MAX_ECC_BITS_USE); DECL_MP_INT_SIZE_DYN(t2, mp_bitsused(modulus), MAX_ECC_BITS_USE); @@ -2626,7 +2627,6 @@ int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct) DECL_MP_INT_SIZE_DYN(rz, mp_bitsused(modulus), MAX_ECC_BITS_USE); #endif mp_int *x, *y, *z; - int err; (void)ct; @@ -2844,7 +2844,7 @@ int ecc_map_ex(ecc_point* P, mp_int* modulus, mp_digit mp, int ct) err = ECC_BAD_ARG_E; #endif - WOLFSSL_LEAVE("ecc_map_ex (SP Math)"); + WOLFSSL_LEAVE("ecc_map_ex (SP Math)", err); return err; #endif /* WOLFSSL_SP_MATH */ } @@ -4279,8 +4279,11 @@ static int wc_ecc_cmp_param(const char* curveParam, if (param == NULL || curveParam == NULL) return BAD_FUNC_ARG; - if (encType == WC_TYPE_HEX_STR) - return XSTRNCMP(curveParam, (char*) param, paramSz); + if (encType == WC_TYPE_HEX_STR) { + if ((word32)XSTRLEN(curveParam) != paramSz) + return -1; + return (XSTRNCMP(curveParam, (char*) param, paramSz) == 0) ? 0 : -1; + } #ifdef WOLFSSL_SMALL_STACK a = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_ECC); diff --git a/wolfcrypt/src/falcon.c b/wolfcrypt/src/falcon.c index 2645db6393..eef982cad7 100644 --- a/wolfcrypt/src/falcon.c +++ b/wolfcrypt/src/falcon.c @@ -282,7 +282,7 @@ int wc_falcon_init_id(falcon_key* key, const unsigned char* id, int len, key->idLen = len; } - /* Set the maxiumum level here */ + /* Set the maximum level here */ wc_falcon_set_level(key, 5); return ret; @@ -309,7 +309,7 @@ int wc_falcon_init_label(falcon_key* key, const char* label, void* heap, key->labelLen = labelLen; } - /* Set the maxiumum level here */ + /* Set the maximum level here */ wc_falcon_set_level(key, 5); return ret; @@ -846,11 +846,11 @@ int wc_Falcon_PrivateKeyDecode(const byte* input, word32* inOutIdx, pubKey, &pubKeyLen, keytype); if (ret == 0) { if (pubKeyLen == 0) { - ret = wc_falcon_import_private_only(input, inSz, key); + ret = wc_falcon_import_private_key(input, inSz, NULL, 0, key); } else { - ret = wc_falcon_import_private_key(privKey, privKeyLen, - pubKey, pubKeyLen, key); + ret = wc_falcon_import_private_key(input, inSz, pubKey, + pubKeyLen, key); } } return ret; @@ -912,7 +912,7 @@ int wc_Falcon_PublicKeyToDer(falcon_key* key, byte* output, word32 inLen, word32 pubKeyLen = (word32)sizeof(pubKey); int keytype = 0; - if (key == NULL || output == NULL) { + if (key == NULL) { return BAD_FUNC_ARG; } diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index 123b2e9db4..e76f1b1a8e 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -1120,7 +1120,7 @@ static WARN_UNUSED_RESULT int freeDecCertList(WC_DerCertList** list, InitDecodedCert(DeCert, current->buffer, current->bufferSz, heap); if (ParseCertRelative(DeCert, CERT_TYPE, NO_VERIFY, NULL) == 0) { - if (wc_CheckPrivateKeyCert(*pkey, *pkeySz, DeCert) == 1) { + if (wc_CheckPrivateKeyCert(*pkey, *pkeySz, DeCert, 0) == 1) { WOLFSSL_MSG("Key Pair found"); *cert = current->buffer; *certSz = current->bufferSz; diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 997fd4f067..96a39f3a52 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -2517,7 +2517,7 @@ static int wc_PKCS7_EncodeContentStreamHelper(PKCS7* pkcs7, int cipherType, } -/* Used for encoding the content, potentially one octet chunck at a time if +/* Used for encoding the content, potentially one octet chunk at a time if * in streaming mode with IO callbacks set. * Can handle the cipher types: * - WC_CIPHER_NONE, used for encoding signed bundle where no encryption is @@ -9746,7 +9746,7 @@ int wc_PKCS7_EncodeEnvelopedData(PKCS7* pkcs7, byte* output, word32 outputSz) StreamOctetString(NULL, encryptedOutSz, NULL, &streamSz, &tmpIdx); totalSz += (streamSz - encryptedOutSz); - /* resize encrytped content buffer */ + /* resize encrypted content buffer */ if (encryptedContent != NULL) { XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); encryptedContent = (byte*)XMALLOC(streamSz, pkcs7->heap, diff --git a/wolfcrypt/src/port/Espressif/esp32_mp.c b/wolfcrypt/src/port/Espressif/esp32_mp.c index 1afda2b832..58925626bc 100644 --- a/wolfcrypt/src/port/Espressif/esp32_mp.c +++ b/wolfcrypt/src/port/Espressif/esp32_mp.c @@ -413,7 +413,7 @@ static int esp_mp_hw_lock(void) { /* Note these names are different from those in the documentation! * - * Documenation lists the same names as the ESP32-C3: + * Documentation lists the same names as the ESP32-C3: * * DPORT_REG_SET_BIT((volatile void *)(SYSTEM_PERIP_CLK_EN1_REG), * SYSTEM_CRYPTO_RSA_CLK_EN ); diff --git a/wolfcrypt/src/port/Espressif/esp32_sha.c b/wolfcrypt/src/port/Espressif/esp32_sha.c index 332c532a6c..a2244af173 100644 --- a/wolfcrypt/src/port/Espressif/esp32_sha.c +++ b/wolfcrypt/src/port/Espressif/esp32_sha.c @@ -128,7 +128,7 @@ static const char* TAG = "wolf_hw_sha"; #ifdef WOLFSSL_DEBUG_MUTEX static portMUX_TYPE sha_crit_sect = portMUX_INITIALIZER_UNLOCKED; WC_ESP32SHA* stray_ctx; - /* each ctx keeps track of the intializer for HW. when debugging + /* each ctx keeps track of the initializer for HW. when debugging * we'll have a global variable to indicate which has the lock. */ static int _sha_lock_count = 0; static int _sha_call_count = 0; @@ -1130,7 +1130,7 @@ int esp_sha_release_unfinished_lock(WC_ESP32SHA* ctx) #ifdef WOLFSSL_DEBUG_MUTEX ESP_LOGE(TAG, "\n>>>> esp_sha_release_unfinished_lock %x\n", ret); #endif - /* unlock only if this ctx is the intializer of the lock */ + /* unlock only if this ctx is the initializer of the lock */ #ifdef SINGLE_THREADED { ret = esp_sha_hw_unlock(ctx); diff --git a/wolfcrypt/src/port/Espressif/esp32_util.c b/wolfcrypt/src/port/Espressif/esp32_util.c index 829afa4a60..03e973ee34 100644 --- a/wolfcrypt/src/port/Espressif/esp32_util.c +++ b/wolfcrypt/src/port/Espressif/esp32_util.c @@ -76,7 +76,7 @@ static int esp_ShowMacroStatus_need_header = 0; #include #include -/* big nums can be very long, perhaps unitialized, so limit displayed words */ +/* big nums can be very long, perhaps uninitialized, so limit displayed words */ #define MAX_WORDS_ESP_SHOW_MP 32 /* diff --git a/wolfcrypt/src/port/autosar/crypto.c b/wolfcrypt/src/port/autosar/crypto.c index e124b3ca5b..f7812f190c 100644 --- a/wolfcrypt/src/port/autosar/crypto.c +++ b/wolfcrypt/src/port/autosar/crypto.c @@ -431,7 +431,7 @@ Std_ReturnType Crypto_ProcessJob(uint32 objectId, Crypto_JobType* job) break; default: - WOLFSSL_MSG("Unsuported Crypto service"); + WOLFSSL_MSG("Unsupported Crypto service"); ret = E_NOT_OK; break; } diff --git a/wolfcrypt/src/port/liboqs/liboqs.c b/wolfcrypt/src/port/liboqs/liboqs.c index f04cab02c7..46733cbbf3 100644 --- a/wolfcrypt/src/port/liboqs/liboqs.c +++ b/wolfcrypt/src/port/liboqs/liboqs.c @@ -60,7 +60,7 @@ static void wolfSSL_liboqsGetRandomData(uint8_t* buffer, size_t numOfBytes) ret = wc_RNG_GenerateBlock(liboqsCurrentRNG, buffer, numOfBytes_word32); if (ret != 0) { - /* ToDo: liboqs exits programm if RNG fails, + /* ToDo: liboqs exits program if RNG fails, * not sure what to do here */ WOLFSSL_MSG_EX( diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index d44f2e2d2f..5e97e91048 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -128,6 +128,8 @@ This library contains implementation for the random number generator. #elif defined(WOLFSSL_TELIT_M2MB) #elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_TRNG) #elif defined(WOLFSSL_IMXRT1170_CAAM) +#elif defined(CY_USING_HAL) && defined(COMPONENT_WOLFSSL) + #include "cyhal_trng.h" /* Infineon/Cypress HAL RNG implementation */ #elif defined(WOLFSSL_GETRANDOM) #include #include @@ -3832,6 +3834,40 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) return ret; } +#elif defined(CY_USING_HAL) && defined(COMPONENT_WOLFSSL) + + /* Infineon/Cypress HAL RNG implementation */ + int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) + { + cyhal_trng_t obj; + cy_rslt_t result; + uint32_t val; + word32 i = 0; + + (void)os; + + result = cyhal_trng_init(&obj); + if (result == CY_RSLT_SUCCESS) { + while (i < sz) { + /* If not aligned or there is odd/remainder add single byte */ + if( (i + sizeof(word32)) > sz || + ((wc_ptr_t)&output[i] % sizeof(word32)) != 0 + ) { + val = cyhal_trng_generate(&obj); + output[i++] = (byte)val; + } + else { + /* Use native 32 instruction */ + val = cyhal_trng_generate(&obj); + *((uint32_t*)&output[i]) = val; + i += sizeof(word32); + } + } + cyhal_trng_free(&obj); + } + return 0; + } + #elif defined(WOLFSSL_SAFERTOS) || defined(WOLFSSL_LEANPSK) || \ defined(WOLFSSL_IAR_ARM) || defined(WOLFSSL_MDK_ARM) || \ defined(WOLFSSL_uITRON4) || defined(WOLFSSL_uTKERNEL2) || \ diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 4299fd2f86..cca20c0d3b 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -4721,7 +4721,12 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) #endif /* WOLFSSL_SMALL_STACK */ int i, failCount, isPrime = 0; word32 primeSz; +#ifndef WOLFSSL_NO_MALLOC byte* buf = NULL; +#else + /* RSA_MAX_SIZE is the size of n in bits. */ + byte buf[RSA_MAX_SIZE/16]; +#endif #endif /* !WOLFSSL_CRYPTOCELL && !WOLFSSL_SE050 */ int err; @@ -4827,12 +4832,14 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) primeSz = (word32)size / 16; /* size is the size of n in bits. primeSz is in bytes. */ +#ifndef WOLFSSL_NO_MALLOC /* allocate buffer to work with */ if (err == MP_OKAY) { buf = (byte*)XMALLOC(primeSz, key->heap, DYNAMIC_TYPE_RSA); if (buf == NULL) err = MEMORY_E; } +#endif SAVE_VECTOR_REGISTERS(err = _svr_ret;); @@ -4935,10 +4942,14 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) if (err == MP_OKAY && !isPrime) err = PRIME_GEN_E; +#ifndef WOLFSSL_NO_MALLOC if (buf) { ForceZero(buf, primeSz); XFREE(buf, key->heap, DYNAMIC_TYPE_RSA); } +#else + ForceZero(buf, primeSz); +#endif if (err == MP_OKAY && mp_cmp(p, q) < 0) { err = mp_copy(p, tmp1); diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 0025e85727..8c9b10ea6e 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -168,8 +168,7 @@ on the specific device platform. #define HAVE_INTEL_RORX #endif - -#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) +#if defined(LITTLE_ENDIAN_ORDER) #if ( defined(CONFIG_IDF_TARGET_ESP32C2) || \ defined(CONFIG_IDF_TARGET_ESP8684) || \ defined(CONFIG_IDF_TARGET_ESP32C3) || \ @@ -182,20 +181,24 @@ on the specific device platform. * depending on if HW is active or not. */ #define SHA256_REV_BYTES(ctx) \ (esp_sha_need_byte_reversal(ctx)) + #elif defined(FREESCALE_MMCAU_SHA) + #define SHA256_REV_BYTES(ctx) 1 /* reverse needed on final */ #endif #endif #ifndef SHA256_REV_BYTES - #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) + #if defined(LITTLE_ENDIAN_ORDER) #define SHA256_REV_BYTES(ctx) 1 #else #define SHA256_REV_BYTES(ctx) 0 #endif #endif -#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) && \ +#if defined(LITTLE_ENDIAN_ORDER) && \ defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \ (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) #define SHA256_UPDATE_REV_BYTES(ctx) \ (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags)) +#elif defined(FREESCALE_MMCAU_SHA) + #define SHA256_UPDATE_REV_BYTES(ctx) 0 /* reverse not needed on update */ #else #define SHA256_UPDATE_REV_BYTES(ctx) SHA256_REV_BYTES(ctx) #endif diff --git a/wolfcrypt/src/sphincs.c b/wolfcrypt/src/sphincs.c index a0196ce395..6556fdb5dc 100644 --- a/wolfcrypt/src/sphincs.c +++ b/wolfcrypt/src/sphincs.c @@ -952,7 +952,7 @@ int wc_Sphincs_PublicKeyToDer(sphincs_key* key, byte* output, word32 inLen, word32 pubKeyLen = (word32)sizeof(pubKey); int keytype = 0; - if (key == NULL || output == NULL) { + if (key == NULL) { return BAD_FUNC_ARG; } diff --git a/wolfcrypt/src/wc_kyber.c b/wolfcrypt/src/wc_kyber.c index b0b358f07a..5493c9e617 100644 --- a/wolfcrypt/src/wc_kyber.c +++ b/wolfcrypt/src/wc_kyber.c @@ -203,7 +203,7 @@ int wc_KyberKey_MakeKeyWithRandom(KyberKey* key, const unsigned char* rand, byte* pubSeed = buf; byte* noiseSeed = buf + KYBER_SYM_SZ; sword16* a = NULL; - sword16* e; + sword16* e = NULL; int ret = 0; int kp = 0; @@ -364,12 +364,12 @@ static int kyberkey_encapsulate(KyberKey* key, const byte* msg, byte* coins, unsigned char* ct) { int ret = 0; - sword16* sp; - sword16* ep; - sword16* k; - sword16* epp; - unsigned int kp; - unsigned int compVecSz; + sword16* sp = NULL; + sword16* ep = NULL; + sword16* k = NULL; + sword16* epp = NULL; + unsigned int kp = 0; + unsigned int compVecSz = 0; #ifndef USE_INTEL_SPEEDUP sword16* at = NULL; #else @@ -528,7 +528,7 @@ int wc_KyberKey_EncapsulateWithRandom(KyberKey* key, unsigned char* ct, byte msg[2 * KYBER_SYM_SZ]; byte kr[2 * KYBER_SYM_SZ + 1]; int ret = 0; - unsigned int ctSz; + unsigned int ctSz = 0; /* Validate parameters. */ if ((key == NULL) || (ct == NULL) || (ss == NULL) || (rand == NULL)) { @@ -636,7 +636,7 @@ static KYBER_NOINLINE int kyberkey_decapsulate(KyberKey* key, int ret = 0; sword16* v; sword16* mp; - unsigned int kp; + unsigned int kp = 0; unsigned int compVecSz; #ifndef USE_INTEL_SPEEDUP sword16* bp = NULL; @@ -741,9 +741,9 @@ int wc_KyberKey_Decapsulate(KyberKey* key, unsigned char* ss, byte msg[2 * KYBER_SYM_SZ]; byte kr[2 * KYBER_SYM_SZ + 1]; int ret = 0; - unsigned int ctSz; - unsigned int i; - int fail; + unsigned int ctSz = 0; + unsigned int i = 0; + int fail = 0; #ifndef USE_INTEL_SPEEDUP byte* cmp = NULL; #else diff --git a/wolfcrypt/src/wc_kyber_poly.c b/wolfcrypt/src/wc_kyber_poly.c index fe140f402f..a95d812db8 100644 --- a/wolfcrypt/src/wc_kyber_poly.c +++ b/wolfcrypt/src/wc_kyber_poly.c @@ -50,7 +50,7 @@ static word32 cpuid_flags = 0; /* Used in Barrett Reduction: * r = a mod q * => r = a - ((V * a) >> 26) * q), as V based on 2^26 - * V is the mulitplier that gets the quotient after shifting. + * V is the multiplier that gets the quotient after shifting. */ #define KYBER_V (((1U << 26) + (KYBER_Q / 2)) / KYBER_Q) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index feab257fb6..80e4e49fe8 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -1,6 +1,6 @@ /* test.c * - * Copyright (C) 2006-2023 wolfSSL Inc. + * Copyright (C) 2006-2024 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -1871,9 +1871,9 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\ #if !defined(NO_ASN) && !defined(NO_ASN_TIME) if ( (ret = time_test()) != 0) - TEST_FAIL("time test failed!\n", ret); + TEST_FAIL("time test failed!\n", ret); else - TEST_PASS("time test passed!\n"); + TEST_PASS("time test passed!\n"); #endif #if defined(__INCLUDE_NUTTX_CONFIG_H) @@ -2125,7 +2125,11 @@ static wc_test_ret_t _SaveDerAndPem(const byte* der, int derSz, #if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) XFILE pemFile; #endif + #ifndef WOLFSSL_NO_MALLOC byte* pem; + #else + byte pem[1024]; + #endif int pemSz; /* calculate PEM size */ @@ -2133,10 +2137,15 @@ static wc_test_ret_t _SaveDerAndPem(const byte* der, int derSz, if (pemSz < 0) { return WC_TEST_RET_ENC(calling_line, 2, WC_TEST_RET_TAG_I); } + #ifndef WOLFSSL_NO_MALLOC pem = (byte*)XMALLOC(pemSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { return WC_TEST_RET_ENC(calling_line, 3, WC_TEST_RET_TAG_I); } + #else + if (pemSz > (int)sizeof(pem)) + return BAD_FUNC_ARG; + #endif /* Convert to PEM */ pemSz = wc_DerToPem(der, derSz, pem, pemSz, pemType); if (pemSz < 0) { @@ -2438,8 +2447,10 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t asn_test(void) { wc_test_ret_t ret; /* ASN1 encoded date buffer */ - WOLFSSL_SMALL_STACK_STATIC const byte dateBuf[] = {0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x31, 0x31, - 0x32, 0x30, 0x30, 0x37, 0x33, 0x37, 0x5a}; + WOLFSSL_SMALL_STACK_STATIC const byte dateBuf[] = { + 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x31, 0x31, + 0x32, 0x30, 0x30, 0x37, 0x33, 0x37, 0x5a + }; byte format; int length; const byte* datePart; @@ -16220,6 +16231,16 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t memory_test(void) CERT_ROOT "test" CERT_PATH_SEP "cert-ext-ia.der"; static const char* certExtNct = CERT_ROOT "test" CERT_PATH_SEP "cert-ext-nct.der"; +#ifndef WOLFSSL_ASN_INT_LEAD_0_ANY + static const char* certBadNegInt = + CERT_ROOT "test" CERT_PATH_SEP "cert-bad-neg-int.der"; +#endif + static const char* certBadOid = + CERT_ROOT "test" CERT_PATH_SEP "cert-bad-oid.der"; +#ifndef WOLFSSL_NO_ASN_STRICT + static const char* certBadUtf8 = + CERT_ROOT "test" CERT_PATH_SEP "cert-bad-utf8.der"; +#endif #endif #ifndef NO_WRITE_TEMP_FILES @@ -16469,6 +16490,71 @@ static wc_test_ret_t cert_asn1_test(void) return ret; } +static wc_test_ret_t cert_load_bad(const char* fname, byte* tmp, int err) +{ + wc_test_ret_t ret; + DecodedCert cert; + XFILE file; + size_t bytes; + + if ((fname == NULL) || (tmp == NULL)) { + ERROR_OUT(WC_TEST_RET_ENC_NC, done); + } + file = XFOPEN(fname, "rb"); + if (!file) { + ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done); + } + bytes = XFREAD(tmp, 1, FOURK_BUF, file); + XFCLOSE(file); + if (bytes == 0) { + ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done); + } + InitDecodedCert(&cert, tmp, (word32)bytes, 0); + ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL); + FreeDecodedCert(&cert); + if (ret != err) { + ERROR_OUT(WC_TEST_RET_ENC_EC(ret), done); + } + ret = 0; + +done: + return ret; +} + +static wc_test_ret_t cert_bad_asn1_test(void) +{ + wc_test_ret_t ret = 0; + byte* tmp; + + tmp = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (tmp == NULL) { + ret = WC_TEST_RET_ENC_ERRNO; + } + +#ifndef WOLFSSL_ASN_INT_LEAD_0_ANY + if (ret == 0) { + /* Serial number: 0xff 0xa8. 0xff and top bit set on next byte invalid. + */ + ret = cert_load_bad(certBadNegInt, tmp, ASN_EXPECT_0_E); + } +#endif + if (ret == 0) { + /* Subject name OID: 55 04 f4. Last byte with top bit set invalid. */ + ret = cert_load_bad(certBadOid, tmp, ASN_PARSE_E); + } +#ifndef WOLFSSL_NO_ASN_STRICT + if (ret == 0) { + /* Issuer name UTF8STRING: df 52 4e 44. Top bit of second byte not set. + */ + ret = cert_load_bad(certBadUtf8, tmp, ASN_PARSE_E); + } +#endif + + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + + return ret; +} + WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cert_test(void) { #if !defined(NO_FILESYSTEM) @@ -16542,6 +16628,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cert_test(void) if (ret == 0) ret = cert_asn1_test(); + if (ret == 0) + ret = cert_bad_asn1_test(); return ret; } @@ -18697,7 +18785,9 @@ static wc_test_ret_t rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) word32 idx3 = 0; #if (!defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048)) \ || !defined(USE_CERT_BUFFERS_256) - XFILE file3; + #ifndef NO_FILESYSTEM + XFILE file3; + #endif #endif wc_test_ret_t ret; @@ -18750,20 +18840,29 @@ static wc_test_ret_t rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); /* Get Cert Key */ -#ifdef USE_CERT_BUFFERS_256 - XMEMCPY(tmp, ecc_key_pub_der_256, sizeof_ecc_key_pub_der_256); - bytes3 = sizeof_ecc_key_pub_der_256; -#else - file3 = XFOPEN(eccKeyPubFileDer, "rb"); - if (!file3) { - ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit_rsa); + #if defined(USE_CERT_BUFFERS_256) + { + XMEMCPY(tmp, ecc_key_pub_der_256, sizeof_ecc_key_pub_der_256); + bytes3 = sizeof_ecc_key_pub_der_256; } + #elif !defined(NO_FILESYSTEM) + { + file3 = XFOPEN(eccKeyPubFileDer, "rb"); + if (!file3) { + ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit_rsa); + } - bytes3 = XFREAD(tmp, 1, FOURK_BUF, file3); - XFCLOSE(file3); - if (bytes3 == 0) - ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit_rsa); -#endif + bytes3 = XFREAD(tmp, 1, FOURK_BUF, file3); + XFCLOSE(file3); + if (bytes3 == 0) + ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit_rsa); + } + #else + { + WOLFSSL_MSG("No file system and USE_CERT_BUFFERS_256 not defined.(1)"); + ERROR_OUT(ASN_PARSE_E, exit_rsa); + } + #endif ret = wc_ecc_init_ex(caEccKeyPub, HEAP_HINT, devId); if (ret != 0) @@ -18911,7 +19010,11 @@ static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) RsaKey genKey[1]; #endif wc_test_ret_t ret; +#ifndef WOLFSSL_NO_MALLOC byte* der = NULL; +#else + byte der[1024]; +#endif #ifndef WOLFSSL_CRYPTOCELL word32 idx = 0; #endif @@ -18956,11 +19059,12 @@ static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) if (ret != 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit_rsa); #endif +#ifndef WOLFSSL_NO_MALLOC der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit_rsa); } - +#endif derSz = wc_RsaKeyToDer(genKey, der, FOURK_BUF); if (derSz < 0) { ERROR_OUT(WC_TEST_RET_ENC_EC(derSz), exit_rsa); @@ -18996,10 +19100,12 @@ static wc_test_ret_t rsa_keygen_test(WC_RNG* rng) wc_FreeRsaKey(genKey); #endif +#ifndef WOLFSSL_NO_MALLOC if (der != NULL) { XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); der = NULL; } +#endif return ret; } @@ -27343,10 +27449,12 @@ static wc_test_ret_t ecc_test_make_pub(WC_RNG* rng) wc_ecc_init_ex(key, HEAP_HINT, devId); #ifndef NO_ECC256 -#ifdef USE_CERT_BUFFERS_256 - XMEMCPY(tmp, ecc_key_der_256, (size_t)sizeof_ecc_key_der_256); - tmpSz = (size_t)sizeof_ecc_key_der_256; -#else +#if defined(USE_CERT_BUFFERS_256) + { + XMEMCPY(tmp, ecc_key_der_256, (size_t)sizeof_ecc_key_der_256); + tmpSz = (size_t)sizeof_ecc_key_der_256; + } +#elif !defined(NO_FILESYSTEM) { XFILE file = XFOPEN(eccKeyDerFile, "rb"); if (!file) { @@ -27358,6 +27466,11 @@ static wc_test_ret_t ecc_test_make_pub(WC_RNG* rng) if (tmpSz == 0) ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done); } +#else + { + WOLFSSL_MSG("No file system and USE_CERT_BUFFERS_256 not defined.(2)"); + ERROR_OUT(ASN_PARSE_E, done); + } #endif /* USE_CERT_BUFFERS_256 */ /* import private only then test with */ @@ -28889,10 +29002,12 @@ static wc_test_ret_t ecc_def_curve_test(WC_RNG *rng) ((defined(HAVE_ECC_KEY_IMPORT) && defined(HAVE_ECC_KEY_EXPORT)) || \ (defined(HAVE_ECC_KEY_IMPORT) && !defined(WOLFSSL_VALIDATE_ECC_IMPORT))) /* Use test ECC key - ensure real private "d" exists */ - #ifdef USE_CERT_BUFFERS_256 - ret = wc_EccPrivateKeyDecode(ecc_key_der_256, &idx, key, - sizeof_ecc_key_der_256); - #else + #if defined(USE_CERT_BUFFERS_256) + { + ret = wc_EccPrivateKeyDecode(ecc_key_der_256, &idx, key, + sizeof_ecc_key_der_256); + } + #elif !defined(NO_FILESYSTEM) { XFILE file = XFOPEN(eccKeyDerFile, "rb"); byte der[128]; @@ -28906,6 +29021,12 @@ static wc_test_ret_t ecc_def_curve_test(WC_RNG *rng) ERROR_OUT(WC_TEST_RET_ENC_ERRNO, done); ret = wc_EccPrivateKeyDecode(der, &idx, key, derSz); } + #else + { + (void)idx; + WOLFSSL_MSG("No file system and USE_CERT_BUFFERS_256 not defined.(3)"); + ERROR_OUT(ASN_PARSE_E, done); + } #endif if (ret != 0) { goto done; @@ -29834,9 +29955,9 @@ static wc_test_ret_t ecc_test_cert_gen(WC_RNG* rng) ecc_key certPubKey[1]; #endif int certSz; - size_t bytes; + size_t bytes = 0; word32 idx = 0; -#ifndef USE_CERT_BUFFERS_256 +#if !defined(USE_CERT_BUFFERS_256) && !defined(NO_FILESYSTEM) XFILE file; #endif #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC) @@ -29867,38 +29988,46 @@ static wc_test_ret_t ecc_test_cert_gen(WC_RNG* rng) /* Get cert private key */ #ifdef ENABLE_ECC384_CERT_GEN_TEST /* Get Cert Key 384 */ -#ifdef USE_CERT_BUFFERS_256 - XMEMCPY(der, ca_ecc_key_der_384, sizeof_ca_ecc_key_der_384); - bytes = sizeof_ca_ecc_key_der_384; -#else - file = XFOPEN(eccCaKey384File, "rb"); - if (!file) { - ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit); - } + #ifdef USE_CERT_BUFFERS_256 + XMEMCPY(der, ca_ecc_key_der_384, sizeof_ca_ecc_key_der_384); + bytes = sizeof_ca_ecc_key_der_384; + #elif !defined(NO_FILESYSTEM) + file = XFOPEN(eccCaKey384File, "rb"); + if (!file) { + ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit); + } - bytes = XFREAD(der, 1, FOURK_BUF, file); - XFCLOSE(file); - if (bytes == 0) - ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit); - (void)eccCaKeyFile; -#endif /* USE_CERT_BUFFERS_256 */ -#else -#ifdef USE_CERT_BUFFERS_256 - XMEMCPY(der, ca_ecc_key_der_256, sizeof_ca_ecc_key_der_256); - bytes = sizeof_ca_ecc_key_der_256; + bytes = XFREAD(der, 1, FOURK_BUF, file); + XFCLOSE(file); + if (bytes == 0) + ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit); + (void)eccCaKeyFile; + #else + WOLFSSL_MSG("No file system and USE_CERT_BUFFERS_256 not defined.(4)"); + ERROR_OUT(ASN_PARSE_E, exit); + #endif /* USE_CERT_BUFFERS_256 */ + + /* end if ENABLE_ECC384_CERT_GEN_TEST */ #else - file = XFOPEN(eccCaKeyFile, "rb"); - if (!file) { - ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit); - } - bytes = XFREAD(der, 1, FOURK_BUF, file); - XFCLOSE(file); - if (bytes == 0) - ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit); -#ifdef ENABLE_ECC384_CERT_GEN_TEST - (void)eccCaKey384File; -#endif -#endif /* USE_CERT_BUFFERS_256 */ + /* !ENABLE_ECC384_CERT_GEN_TEST */ + + #ifdef USE_CERT_BUFFERS_256 + XMEMCPY(der, ca_ecc_key_der_256, sizeof_ca_ecc_key_der_256); + bytes = sizeof_ca_ecc_key_der_256; + #else + file = XFOPEN(eccCaKeyFile, "rb"); + if (!file) { + ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit); + } + bytes = XFREAD(der, 1, FOURK_BUF, file); + XFCLOSE(file); + if (bytes == 0) + ERROR_OUT(WC_TEST_RET_ENC_ERRNO, exit); + + #ifdef ENABLE_ECC384_CERT_GEN_TEST + (void)eccCaKey384File; + #endif + #endif /* USE_CERT_BUFFERS_256 */ #endif /* ENABLE_ECC384_CERT_GEN_TEST */ /* Get CA Key */ @@ -29959,23 +30088,28 @@ static wc_test_ret_t ecc_test_cert_gen(WC_RNG* rng) #endif /* WOLFSSL_CERT_EXT */ #ifdef ENABLE_ECC384_CERT_GEN_TEST -#if defined(USE_CERT_BUFFERS_256) - ret = wc_SetIssuerBuffer(myCert, ca_ecc_cert_der_384, - sizeof_ca_ecc_cert_der_384); -#else - ret = wc_SetIssuer(myCert, eccCaCert384File); - (void)eccCaCertFile; -#endif -#else -#if defined(USE_CERT_BUFFERS_256) - ret = wc_SetIssuerBuffer(myCert, ca_ecc_cert_der_256, - sizeof_ca_ecc_cert_der_256); + #if defined(USE_CERT_BUFFERS_256) + ret = wc_SetIssuerBuffer(myCert, ca_ecc_cert_der_384, + sizeof_ca_ecc_cert_der_384); + #elif !defined(NO_FILESYSTEM) + ret = wc_SetIssuer(myCert, eccCaCert384File); + (void)eccCaCertFile; + #else + /* not testing with embedded, no file system target */ + ERROR_OUT(ASN_PARSE_E, exit); + #endif /* USE_CERT_BUFFERS_256 */ + #else - ret = wc_SetIssuer(myCert, eccCaCertFile); - #ifdef ENABLE_ECC384_CERT_GEN_TEST - (void)eccCaCert384File; + /* not ENABLE_ECC384_CERT_GEN_TEST */ + #if defined(USE_CERT_BUFFERS_256) + ret = wc_SetIssuerBuffer(myCert, ca_ecc_cert_der_256, + sizeof_ca_ecc_cert_der_256); + #else + ret = wc_SetIssuer(myCert, eccCaCertFile); + #ifdef ENABLE_ECC384_CERT_GEN_TEST + (void)eccCaCert384File; + #endif #endif -#endif #endif /* ENABLE_ECC384_CERT_GEN_TEST */ if (ret < 0) ERROR_OUT(WC_TEST_RET_ENC_EC(ret), exit); @@ -41672,7 +41806,9 @@ static int myOriEncryptCb(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* oriType, int i; /* make sure buffers are large enough */ - if ((*oriValueSz < (2 + cekSz)) || (*oriTypeSz < sizeof(oriType))) + if (*oriValueSz < (2 + cekSz)) + return WC_TEST_RET_ENC_NC; + if (*oriTypeSz < sizeof(asnDataOid)) return WC_TEST_RET_ENC_NC; /* our simple encryption algorithm will be take the bitwise complement */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 258cb034e2..89a300e927 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -343,7 +343,7 @@ #endif #endif - #if !defined(NO_RSA) && !defined(NO_DES3) + #if !defined(NO_RSA) && !defined(NO_DES3) && !defined(NO_DES3_TLS_SUITES) #if !defined(NO_SHA) #if defined(WOLFSSL_STATIC_RSA) #define BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA @@ -500,7 +500,7 @@ #if defined(WOLFSSL_AES_256) && defined(HAVE_AES_CBC) #define BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA #endif - #if !defined(NO_DES3) + #if !defined(NO_DES3) && !defined(NO_DES3_TLS_SUITES) #define BUILD_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA #endif #endif @@ -686,7 +686,8 @@ #endif #endif #if !defined(NO_DES3) && !(defined(WSSL_HARDEN_TLS) && \ - WSSL_HARDEN_TLS > 112) + WSSL_HARDEN_TLS > 112) && \ + !defined(NO_DES3_TLS_SUITES) /* 3DES offers only 112 bits of security. * Using guidance from section 5.6.1 * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r5.pdf */ @@ -1560,7 +1561,6 @@ enum Misc { #endif SIZEOF_SENDER = 4, /* clnt or srvr */ FINISHED_SZ = 36, /* WC_MD5_DIGEST_SIZE + WC_SHA_DIGEST_SIZE */ - MAX_RECORD_SIZE = 16384, /* 2^14, max size by standard */ MAX_PLAINTEXT_SZ = (1 << 14), /* Max plaintext sz */ MAX_TLS_CIPHER_SZ = (1 << 14) + 2048, /* Max TLS encrypted data sz */ #ifdef WOLFSSL_TLS13 @@ -1915,10 +1915,10 @@ enum Misc { #ifdef HAVE_PQC #ifndef MIN_FALCONKEY_SZ - #define MIN_FALCONKEY_SZ 897 + #define MIN_FALCONKEY_SZ 1281 #endif #ifndef MIN_DILITHIUMKEY_SZ - #define MIN_DILITHIUMKEY_SZ 1312 + #define MIN_DILITHIUMKEY_SZ 2528 #endif #endif @@ -2175,9 +2175,9 @@ WOLFSSL_LOCAL int CreateDevPrivateKey(void** pkey, byte* data, word32 length, int hsType, int label, int id, void* heap, int devId); #endif -WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word16* length); +WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word32* length); #ifdef WOLFSSL_DUAL_ALG_CERTS -WOLFSSL_LOCAL int DecodeAltPrivateKey(WOLFSSL *ssl, word16* length); +WOLFSSL_LOCAL int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length); #endif #ifdef WOLF_PRIVATE_KEY_ID WOLFSSL_LOCAL int GetPrivateKeySigSize(WOLFSSL* ssl); @@ -2273,6 +2273,8 @@ enum { /* determine maximum record size */ +#define MAX_RECORD_SIZE 16384 /* 2^14, max size by standard */ + #ifdef RECORD_SIZE /* user supplied value */ #if RECORD_SIZE < 128 || RECORD_SIZE > MAX_RECORD_SIZE @@ -2864,7 +2866,7 @@ typedef enum { TLSX_KEY_QUIC_TP_PARAMS = 0x0039, /* RFC 9001, ch. 8.2 */ #endif #ifdef WOLFSSL_DUAL_ALG_CERTS - TLSX_CKS = 0xff92, /* X9.146; ff indcates personal + TLSX_CKS = 0xff92, /* X9.146; ff indicates personal * use and 92 is hex for 146. */ #endif #endif @@ -2986,9 +2988,9 @@ WOLFSSL_LOCAL int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isRequest); #if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_CLIENT) WOLFSSL_LOCAL int TLSX_GetRequestSize(WOLFSSL* ssl, byte msgType, - word16* pLength); + word32* pLength); WOLFSSL_LOCAL int TLSX_WriteRequest(WOLFSSL* ssl, byte* output, - byte msgType, word16* pOffset); + byte msgType, word32* pOffset); #endif #if defined(WOLFSSL_TLS13) || !defined(NO_WOLFSSL_SERVER) @@ -3583,8 +3585,11 @@ struct WOLFSSL_CTX { #ifdef WOLFSSL_DUAL_ALG_CERTS DerBuffer* altPrivateKey; - byte altPrivateKeyType; + byte altPrivateKeyType:6; + byte altPrivateKeyId:1; + byte altPrivateKeyLabel:1; int altPrivateKeySz; + int altPrivateKeyDevId; #endif /* WOLFSSL_DUAL_ALG_CERTS */ #ifdef OPENSSL_ALL WOLFSSL_EVP_PKEY* privateKeyPKey; @@ -4548,15 +4553,18 @@ typedef struct Buffers { #ifndef NO_CERTS DerBuffer* certificate; /* WOLFSSL_CTX owns, unless we own */ DerBuffer* key; /* WOLFSSL_CTX owns, unless we own */ - byte keyType:6; /* Type of key: RSA, ECC, Ed25519 */ + byte keyType:6; /* Type of key */ byte keyId:1; /* Key data is an id not data */ byte keyLabel:1; /* Key data is a label not data */ int keySz; /* Size of RSA key */ int keyDevId; /* Device Id for key */ #ifdef WOLFSSL_DUAL_ALG_CERTS DerBuffer* altKey; /* WOLFSSL_CTX owns, unless we own */ - byte altKeyType; /* Type of key: dilithium, falcon */ - int altKeySz; /* Size of key */ + byte altKeyType:6; /* Type of alt key */ + byte altKeyId:1; /* Key data is an id not data */ + byte altKeyLabel:1; /* Key data is a label not data */ + int altKeySz; /* Size of alt key */ + int altKeyDevId; /* Device Id for alt key */ #endif DerBuffer* certChain; /* WOLFSSL_CTX owns, unless we own */ /* chain after self, in DER, with leading size for each cert */ diff --git a/wolfssl/openssl/sha.h b/wolfssl/openssl/sha.h index c36441498f..ab38c5c096 100644 --- a/wolfssl/openssl/sha.h +++ b/wolfssl/openssl/sha.h @@ -27,7 +27,7 @@ #include #include - +#include #ifdef WOLFSSL_PREFIX #include "prefix_sha.h" #endif @@ -151,7 +151,7 @@ typedef WOLFSSL_SHA224_CTX SHA224_CTX; * to Sha256, is expected to also be 16 byte aligned addresses. */ typedef struct WOLFSSL_SHA256_CTX { /* big enough to hold wolfcrypt Sha256, but check on init */ - ALIGN16 void* holder[(274 + CTX_SHA_HW_ADDER + WC_ASYNC_DEV_SIZE) / + ALIGN16 void* holder[sizeof(wc_Sha256) / sizeof(void*)]; #if defined(WOLFSSL_DEVCRYPTO_HASH) || defined(WOLFSSL_HASH_KEEP) ALIGN16 void* keephash_holder[sizeof(void*) + (2 * sizeof(unsigned int))]; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 804ec44bbb..cb36864cd2 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3096,6 +3096,17 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* key, unsigned int len, const unsigned char* in, long sz, int format); WOLFSSL_API int wolfSSL_CTX_use_certificate_chain_buffer(WOLFSSL_CTX* ctx, const unsigned char* in, long sz); +#ifdef WOLFSSL_DUAL_ALG_CERTS + WOLFSSL_API int wolfSSL_CTX_use_AltPrivateKey_buffer(WOLFSSL_CTX* ctx, + const unsigned char* in, long sz, int format); + WOLFSSL_API int wolfSSL_CTX_use_AltPrivateKey_id(WOLFSSL_CTX* ctx, + const unsigned char* id, long sz, + int devId, long keySz); + WOLFSSL_API int wolfSSL_CTX_use_AltPrivateKey_Id(WOLFSSL_CTX* ctx, + const unsigned char* id, long sz, int devId); + WOLFSSL_API int wolfSSL_CTX_use_AltPrivateKey_Label(WOLFSSL_CTX* ctx, + const char* label, int devId); +#endif /* SSL versions */ WOLFSSL_API int wolfSSL_use_certificate_buffer(WOLFSSL* ssl, const unsigned char* in, @@ -3114,6 +3125,17 @@ WOLFSSL_API int wolfSSL_make_eap_keys(WOLFSSL* ssl, void* key, unsigned int len, WOLFSSL_API int wolfSSL_use_certificate_chain_buffer(WOLFSSL* ssl, const unsigned char* in, long sz); WOLFSSL_API int wolfSSL_UnloadCertsKeys(WOLFSSL* ssl); +#ifdef WOLFSSL_DUAL_ALG_CERTS + WOLFSSL_API int wolfSSL_use_AltPrivateKey_buffer(WOLFSSL* ssl, + const unsigned char* in, long sz, int format); + WOLFSSL_API int wolfSSL_use_AltPrivateKey_id(WOLFSSL* ssl, + const unsigned char* id, long sz, + int devId, long keySz); + WOLFSSL_API int wolfSSL_use_AltPrivateKey_Id(WOLFSSL* ssl, + const unsigned char* id, long sz, int devId); + WOLFSSL_API int wolfSSL_use_AltPrivateKey_Label(WOLFSSL* ssl, + const char* label, int devId); +#endif #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) && \ defined(KEEP_OUR_CERT) diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 01eb03c206..e8a6f99dd8 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -969,6 +969,9 @@ enum Misc_ASN { MAX_DSA_PRIVKEY_SZ = (DSA_INTS * MAX_DSA_INT_SZ) + MAX_SEQ_SZ + MAX_VERSION_SZ, /* Maximum size of a DSA Private key taken from DsaKeyIntsToDer. */ +#if defined(HAVE_PQC) + MAX_PQC_PUBLIC_KEY_SZ = 2592, /* Maximum size of a Dilithium public key. */ +#endif MAX_RSA_E_SZ = 16, /* Max RSA public e size */ MAX_CA_SZ = 32, /* Max encoded CA basic constraint length */ MAX_SN_SZ = 35, /* Max encoded serial number (INT) length */ @@ -1015,7 +1018,11 @@ enum Misc_ASN { OCSP_NONCE_EXT_SZ = 35, /* OCSP Nonce Extension size */ MAX_OCSP_EXT_SZ = 58, /* Max OCSP Extension length */ MAX_OCSP_NONCE_SZ = 16, /* OCSP Nonce size */ +#if defined(HAVE_PQC) + MAX_PUBLIC_KEY_SZ = MAX_PQC_PUBLIC_KEY_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2, +#else MAX_PUBLIC_KEY_SZ = MAX_DSA_PUBKEY_SZ + MAX_ALGO_SZ + MAX_SEQ_SZ * 2, +#endif #ifdef WOLFSSL_ENCRYPTED_KEYS HEADER_ENCRYPTED_KEY_SIZE = 88,/* Extra header size for encrypted key */ #else @@ -2017,10 +2024,9 @@ struct Signer { word32 cm_idx; #endif #ifdef WOLFSSL_DUAL_ALG_CERTS - /* The Subject Alternative Public Key Info (SAPKI) will NOT be cached. - * Caching of it is NOT SUPPORTED yet. */ - byte *sapkiDer; - int sapkiLen; + word32 sapkiOID; /* key type */ + byte* sapkiDer; + int sapkiLen; #endif /* WOLFSSL_DUAL_ALG_CERTS */ byte type; @@ -2308,7 +2314,8 @@ WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash, int maxIdx); WOLFSSL_LOCAL int GetNameHash_ex(const byte* source, word32* idx, byte* hash, int maxIdx, word32 sigOID); -WOLFSSL_LOCAL int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der); +WOLFSSL_LOCAL int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, + DecodedCert* der, int checkAlt); WOLFSSL_LOCAL int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz, const byte* pubKey, word32 pubKeySz, enum Key_Sum ks); WOLFSSL_LOCAL int StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g); diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 0f58152dfe..d3df2a0765 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -516,7 +516,7 @@ typedef struct Cert { #endif #ifdef WOLFSSL_DUAL_ALG_CERTS /* These will not point to managed buffers. They will point to buffers that - * are managed by others. No cleanup neccessary. */ + * are managed by others. No cleanup necessary. */ /* Subject Alternative Public Key Info */ byte *sapkiDer; int sapkiLen; diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index d4ab8e338b..53c4ce0b73 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -242,8 +242,8 @@ WOLFSSL_API int wc_FreeRng(WC_RNG* rng); #endif #ifdef HAVE_HASHDRBG - WOLFSSL_LOCAL int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy, - word32 entropySz); + WOLFSSL_API int wc_RNG_DRBG_Reseed(WC_RNG* rng, const byte* entropy, + word32 entropySz); WOLFSSL_API int wc_RNG_TestSeed(const byte* seed, word32 seedSz); WOLFSSL_API int wc_RNG_HealthTest(int reseed, const byte* entropyA, word32 entropyASz, diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index bc544c70bd..d4e30aad97 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -306,22 +306,61 @@ #include -#define WOLFSSL_MAKE_FIPS_VERSION(major, minor) (((major) * 256) + (minor)) +/*------------------------------------------------------------*/ +#define WOLFSSL_MAKE_FIPS_VERSION3(major, minor, patch) \ + (((major) * 65536) + ((minor) * 256) + (patch)) +#define WOLFSSL_MAKE_FIPS_VERSION(major, minor) \ + WOLFSSL_MAKE_FIPS_VERSION3(major, minor, 0) + #if !defined(HAVE_FIPS) - #define WOLFSSL_FIPS_VERSION_CODE WOLFSSL_MAKE_FIPS_VERSION(0,0) + #define WOLFSSL_FIPS_VERSION_CODE WOLFSSL_MAKE_FIPS_VERSION3(0,0,0) + #define WOLFSSL_FIPS_VERSION2_CODE WOLFSSL_FIPS_VERSION_CODE #elif !defined(HAVE_FIPS_VERSION) - #define WOLFSSL_FIPS_VERSION_CODE WOLFSSL_MAKE_FIPS_VERSION(1,0) + #define WOLFSSL_FIPS_VERSION_CODE WOLFSSL_MAKE_FIPS_VERSION3(1,0,0) + #define WOLFSSL_FIPS_VERSION2_CODE WOLFSSL_FIPS_VERSION_CODE #elif !defined(HAVE_FIPS_VERSION_MINOR) - #define WOLFSSL_FIPS_VERSION_CODE WOLFSSL_MAKE_FIPS_VERSION(HAVE_FIPS_VERSION,0) + #define WOLFSSL_FIPS_VERSION_CODE \ + WOLFSSL_MAKE_FIPS_VERSION3(HAVE_FIPS_VERSION,0,0) + #define WOLFSSL_FIPS_VERSION2_CODE WOLFSSL_FIPS_VERSION_CODE +#elif !defined(HAVE_FIPS_VERSION_PATCH) + #define WOLFSSL_FIPS_VERSION_CODE \ + WOLFSSL_MAKE_FIPS_VERSION3(HAVE_FIPS_VERSION, \ + HAVE_FIPS_VERSION_MINOR, 0) + #define WOLFSSL_FIPS_VERSION2_CODE WOLFSSL_FIPS_VERSION_CODE #else - #define WOLFSSL_FIPS_VERSION_CODE WOLFSSL_MAKE_FIPS_VERSION(HAVE_FIPS_VERSION,HAVE_FIPS_VERSION_MINOR) -#endif + #define WOLFSSL_FIPS_VERSION_CODE \ + WOLFSSL_MAKE_FIPS_VERSION3(HAVE_FIPS_VERSION,\ + HAVE_FIPS_VERSION_MINOR, \ + HAVE_FIPS_VERSION_PATCH) + #define WOLFSSL_FIPS_VERSION2_CODE \ + WOLFSSL_MAKE_FIPS_VERSION3(HAVE_FIPS_VERSION,\ + HAVE_FIPS_VERSION_MINOR, \ + 0) +#endif + +#define FIPS_VERSION_LT(major,minor) \ + (WOLFSSL_FIPS_VERSION2_CODE < WOLFSSL_MAKE_FIPS_VERSION(major,minor)) +#define FIPS_VERSION_LE(major,minor) \ + (WOLFSSL_FIPS_VERSION2_CODE <= WOLFSSL_MAKE_FIPS_VERSION(major,minor)) +#define FIPS_VERSION_EQ(major,minor) \ + (WOLFSSL_FIPS_VERSION2_CODE == WOLFSSL_MAKE_FIPS_VERSION(major,minor)) +#define FIPS_VERSION_GE(major,minor) \ + (WOLFSSL_FIPS_VERSION2_CODE >= WOLFSSL_MAKE_FIPS_VERSION(major,minor)) +#define FIPS_VERSION_GT(major,minor) \ + (WOLFSSL_FIPS_VERSION2_CODE > WOLFSSL_MAKE_FIPS_VERSION(major,minor)) + +#define FIPS_VERSION3_LT(major,minor,patch) \ + (WOLFSSL_FIPS_VERSION_CODE < WOLFSSL_MAKE_FIPS_VERSION3(major,minor,patch)) +#define FIPS_VERSION3_LE(major,minor,patch) \ + (WOLFSSL_FIPS_VERSION_CODE <= WOLFSSL_MAKE_FIPS_VERSION3(major,minor,patch)) +#define FIPS_VERSION3_EQ(major,minor,patch) \ + (WOLFSSL_FIPS_VERSION_CODE == WOLFSSL_MAKE_FIPS_VERSION3(major,minor,patch)) +#define FIPS_VERSION3_GE(major,minor,patch) \ + (WOLFSSL_FIPS_VERSION_CODE >= WOLFSSL_MAKE_FIPS_VERSION3(major,minor,patch)) +#define FIPS_VERSION3_GT(major,minor,patch) \ + (WOLFSSL_FIPS_VERSION_CODE > WOLFSSL_MAKE_FIPS_VERSION3(major,minor,patch)) +/*------------------------------------------------------------*/ -#define FIPS_VERSION_LT(major,minor) (WOLFSSL_FIPS_VERSION_CODE < WOLFSSL_MAKE_FIPS_VERSION(major,minor)) -#define FIPS_VERSION_LE(major,minor) (WOLFSSL_FIPS_VERSION_CODE <= WOLFSSL_MAKE_FIPS_VERSION(major,minor)) -#define FIPS_VERSION_EQ(major,minor) (WOLFSSL_FIPS_VERSION_CODE == WOLFSSL_MAKE_FIPS_VERSION(major,minor)) -#define FIPS_VERSION_GE(major,minor) (WOLFSSL_FIPS_VERSION_CODE >= WOLFSSL_MAKE_FIPS_VERSION(major,minor)) -#define FIPS_VERSION_GT(major,minor) (WOLFSSL_FIPS_VERSION_CODE > WOLFSSL_MAKE_FIPS_VERSION(major,minor)) /* make sure old RNG name is used with CTaoCrypt FIPS */ #ifdef HAVE_FIPS @@ -2008,6 +2047,7 @@ extern void uITRON4_free(void *p) ; #define WOLFSSL_DH_CONST #define WOLFSSL_HAVE_MAX #define NO_WRITEV + #define NO_STDLIB_ISASCII #define USE_FLAT_BENCHMARK_H #define USE_FLAT_TEST_H diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 01ed929f49..f5a279febb 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -430,6 +430,9 @@ typedef struct w64wrapper { #define XELEM_CNT(x) (sizeof((x))/sizeof(*(x))) + #define WC_SAFE_SUM_WORD32(in1, in2, out) ((in2) <= 0xffffffffU - (in1) ? \ + ((out) = (in1) + (in2), 1) : ((out) = 0xffffffffU, 0)) + /* idea to add global alloc override by Moises Guimaraes */ /* default to libc stuff */ /* XREALLOC is used once in normal math lib, not in fast math lib */ diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt index ec6dcba2c4..0b26805576 100644 --- a/zephyr/CMakeLists.txt +++ b/zephyr/CMakeLists.txt @@ -1,20 +1,26 @@ if(CONFIG_WOLFSSL) zephyr_interface_library_named(wolfSSL) - + if(CONFIG_WOLFSSL_BUILTIN) - target_compile_definitions(wolfSSL INTERFACE - WOLFSSL_SETTINGS_FILE="${CONFIG_WOLFSSL_SETTINGS_FILE}" - ) - + if(CONFIG_WOLFSSL_SETTINGS_FILE) + target_compile_definitions(wolfSSL INTERFACE + WOLFSSL_SETTINGS_FILE="${CONFIG_WOLFSSL_SETTINGS_FILE}" + ) + zephyr_include_directories( + ${APPLICATION_CONFIG_DIR} + ${APPLICATION_CONFIG_DIR}/src + ) + endif() + zephyr_include_directories( ${ZEPHYR_CURRENT_MODULE_DIR} ${ZEPHYR_CURRENT_MODULE_DIR}/wolfssl ${ZEPHYR_CURRENT_MODULE_DIR}/zephyr ) - + zephyr_library() zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/zephyr/zephyr_init.c) - + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/src/crl.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/src/dtls13.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/src/internal.c) @@ -25,8 +31,29 @@ if(CONFIG_WOLFSSL) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/src/tls.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/src/tls13.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/src/wolfio.c) - + + # FIPS Boundary + if(CONFIG_WOLFCRYPT_FIPS) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wolfcrypt_first.c) + endif() + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/hmac.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/random.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/kdf.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/rsa.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/ecc.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/aes.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sha.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sha256.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sha512.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sha3.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/dh.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/cmac.c) + if(CONFIG_WOLFCRYPT_FIPS) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/fips.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/fips_test.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wolfcrypt_last.c) + endif() + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/arc4.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/asm.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/asn.c) @@ -36,7 +63,6 @@ if(CONFIG_WOLFSSL) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/camellia.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/chacha.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/chacha20_poly1305.c) - zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/cmac.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/coding.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/compress.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/cpuid.c) @@ -44,10 +70,8 @@ if(CONFIG_WOLFSSL) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/curve25519.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/curve448.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/des3.c) - zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/dh.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/dilithium.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/dsa.c) - zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/ecc.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/ecc_fp.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/eccsi.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/ed25519.c) @@ -58,15 +82,11 @@ if(CONFIG_WOLFSSL) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/fe_448.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/fe_low_mem.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/fe_operations.c) - #zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/fips.c) - #zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/fips_test.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/ge_448.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/ge_low_mem.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/ge_operations.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/hash.c) - zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/hmac.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/integer.c) - zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/kdf.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/logging.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/md2.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/md4.c) @@ -77,15 +97,9 @@ if(CONFIG_WOLFSSL) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/pkcs7.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/poly1305.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/pwdbased.c) - zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/random.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/ripemd.c) - zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/rsa.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sakke.c) #zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/selftest.c) - zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sha.c) - zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sha256.c) - zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sha3.c) - zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sha512.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/signature.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/siphash.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sp_arm32.c) @@ -104,8 +118,6 @@ if(CONFIG_WOLFSSL) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wc_encrypt.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wc_pkcs11.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wc_port.c) - #zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wolfcrypt_first.c) - #zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wolfcrypt_last.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wolfevent.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/wolfmath.c) @@ -115,7 +127,38 @@ if(CONFIG_WOLFSSL) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/psa/psa_hash.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/psa/psa_pkcbs.c) zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/st/stm32.c) - + + if(CONFIG_WOLFCRYPT_ARMASM) + # tested with board: "qemu_kvm_arm64" + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/arm/armv8-aes.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/arm/armv8-32-aes-asm_c.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/arm/armv8-sha256.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/arm/armv8-32-sha256-asm_c.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/arm/armv8-sha512.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/arm/armv8-sha512-asm_c.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/arm/armv8-sha3-asm_c.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/arm/armv8-poly1305.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/arm/armv8-chacha.c) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/port/arm/armv8-curve25519_c.c) + + # Note: The cmake/gcc-m-cpu.cmake make need updated to add "+crypto -mstrict-align" + set(TOOLCHAIN_C_FLAGS "-mcpu=cortex-a53+crypto -mstrict-align") + endif() + + if(CONFIG_WOLFCRYPT_INTELASM) + # tested with board: "qemu_x86_64" + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sha256_asm.S) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sha512_asm.S) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/sha3_asm.S) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/chacha_asm.S) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/poly1305_asm.S) + + # AESNI + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/aes_asm.S) + zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/wolfcrypt/src/aes_gcm_x86_asm.S) + set(TOOLCHAIN_C_FLAGS "-march=native -maes -msse4 -mpclmul ") + endif() + zephyr_library_link_libraries(wolfSSL) target_compile_definitions(wolfSSL INTERFACE WOLFSSL_ZEPHYR) @@ -125,14 +168,14 @@ if(CONFIG_WOLFSSL) endif() else() assert(CONFIG_WOLFSSL_LIBRARY "wolfSSL was enabled, but neither BUILTIN or LIBRARY was selected.") - + # NB: CONFIG_WOLFSSL_LIBRARY is not regression tested and is # therefore susceptible to bit rot - + target_include_directories(wolfSSL INTERFACE ${CONFIG_WOLFSSL_INSTALL_PATH} ) - + zephyr_link_libraries( wolfssl_external -L${CONFIG_WOLFSSL_INSTALL_PATH} @@ -142,7 +185,7 @@ if(CONFIG_WOLFSSL) # wolfssl to link with gcc we need to ensure it is placed # after wolfssl_external on the linkers command line. endif() - + target_link_libraries(wolfSSL INTERFACE zephyr_interface) endif() diff --git a/zephyr/Kconfig b/zephyr/Kconfig index 6d58cc02e4..5c6fa73ef1 100644 --- a/zephyr/Kconfig +++ b/zephyr/Kconfig @@ -53,7 +53,6 @@ endchoice config WOLFSSL_SETTINGS_FILE string "wolfSSL settings file" depends on WOLFSSL_BUILTIN - default "user_settings-tls-generic.h" help Use a specific wolfSSL settings file. The default config file file can be tweaked with Kconfig. The default settings is @@ -64,6 +63,26 @@ config WOLFSSL_SETTINGS_FILE rsource "Kconfig.tls-generic" +config WOLFCRYPT_FIPS + bool "wolfCrypt FIPS support" + depends on WOLFSSL_BUILTIN + help + Enables FIPS support in wolfCrypt. Requires the wolfSSL FIPS ready + download that includes fips.c/fips_test.c. + +config WOLFCRYPT_ARMASM + bool "wolfCrypt ARM Assembly support" + depends on WOLFSSL_BUILTIN + help + wolfCrypt ARM (ARMv8/ARMv7) assembly support for AES, SHA-2, SHA-3, + ChaCha20/Poly1305 and Curve25519 + +config WOLFCRYPT_INTELASM + bool "wolfCrypt Intel Assembly support" + depends on WOLFSSL_BUILTIN + help + wolfCrypt Intel Aassembly support (AVX/AVX2/AESNI) + config WOLFSSL_DEBUG bool "wolfSSL debug activation" depends on WOLFSSL_BUILTIN diff --git a/zephyr/include.am b/zephyr/include.am index 83b69368dd..ef67bcc108 100644 --- a/zephyr/include.am +++ b/zephyr/include.am @@ -8,9 +8,7 @@ EXTRA_DIST+= zephyr/Kconfig.tls-generic EXTRA_DIST+= zephyr/zephyr_init.c EXTRA_DIST+= zephyr/module.yml EXTRA_DIST+= zephyr/wolfssl/options.h -EXTRA_DIST+= zephyr/nrf5340dk_nrf5340_user_settings.h EXTRA_DIST+= zephyr/user_settings.h -EXTRA_DIST+= zephyr/user_settings-tls-generic.h EXTRA_DIST+= zephyr/README.md EXTRA_DIST+= zephyr/samples/wolfssl_benchmark/ EXTRA_DIST+= zephyr/samples/wolfssl_benchmark/CMakeLists.txt diff --git a/zephyr/nrf5340dk_nrf5340_user_settings.h b/zephyr/nrf5340dk_nrf5340_user_settings.h deleted file mode 100644 index a10b54bd23..0000000000 --- a/zephyr/nrf5340dk_nrf5340_user_settings.h +++ /dev/null @@ -1,133 +0,0 @@ -/* nrf5340dk_nrf5340_user_settings.h - * - * Copyright (C) 2006-2023 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_OPTIONS_H -#define WOLFSSL_OPTIONS_H - - -#ifdef __cplusplus -extern "C" { -#endif - -/* Platform */ -#undef WOLFSSL_ZEPHYR -#define WOLFSSL_ZEPHYR - -#define WOLFSSL_GENERAL_ALIGNMENT 4 -#define SIZEOF_LONG_LONG 8 - -/* Enable PSA Crypto API for CryptoCell 312 crypto use */ -#define WOLFSSL_HAVE_PSA -#define WOLFSSL_PSA_GLOBAL_LOCK - -/* Enable SP Math */ -#define WOLFSSL_SP_MATH -#define WOLFSSL_SP_MATH_ALL -#define WOLFSSL_HAVE_SP_RSA -#define WOLFSSL_HAVE_SP_DH -#define WOLFSSL_HAVE_SP_ECC - -/* Enable SP Math assembly support for ARM32 */ -#define SP_WORD_SIZE 32 -#define WOLFSSL_SP_ASM -#define WOLFSSL_SP_ARM32 -#define WOLFSSL_SP_ARM32_ASM - -/* Crypto */ -#define WC_RSA_BLINDING -#define WC_RSA_PSS -#define WOLFSSL_DH_CONST -#define HAVE_FFDHE_2048 - -#define HAVE_ECC -#define ECC_USER_CURVES -/* #define HAVE_ECC192 */ -/* #define HAVE_ECC224 */ -#undef NO_ECC256 -/* #define HAVE_ECC384 */ -/* #define HAVE_ECC521 */ -#define ECC_SHAMIR -#define ECC_TIMING_RESISTANT - -#define WOLFSSL_AES_DIRECT -#define HAVE_AES_ECB -#define HAVE_AES_CBC -#define HAVE_AESCCM -#define HAVE_AESGCM -#define GCM_TABLE_4BIT - -/* AES-CTR is not working correctly with Nordic PSA Crypto API */ -/* #define WOLFSSL_AES_COUNTER */ - -#define HAVE_CHACHA -#define HAVE_POLY1305 -#define HAVE_ONE_TIME_AUTH - -/* Nordic Security PSA Crypto CryptoCell integration does not support SHA-1 */ -#define NO_SHA -#define WOLFSSL_SHA224 -#define WOLFSSL_SHA384 -#define WOLFSSL_SHA512 -#define WOLFSSL_SHA3 - -#define HAVE_HKDF -#define WOLFSSL_CMAC - -/* Benchmark / Test */ -#define BENCH_EMBEDDED -#define USE_CERT_BUFFERS_256 -#define USE_CERT_BUFFERS_2048 -#define NO_FILESYSTEM - -/* RNG */ -#define HAVE_HASHDRBG - -/* Features */ -#define WOLFSSL_TLS13 -#define WOLFSSL_OLD_PRIME_CHECK -#define HAVE_TLS_EXTENSIONS -#define HAVE_SUPPORTED_CURVES -#define HAVE_EXTENDED_MASTER -#define WOLFSSL_BASE64_ENCODE -#define WC_NO_ASYNC_THREADING - -/* Disable features that require SHA-1 (see note above) */ -#define NO_OLD_TLS -#define NO_DSA - -/* Disable other features (re-enable if needed) */ -#define NO_RC4 -#define NO_PSK -#define NO_MD4 -#define NO_PWDBASED -#define NO_DES3 - -#if defined(CONFIG_WOLFSSL_DEBUG) -#undef DEBUG_WOLFSSL -#define DEBUG_WOLFSSL -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* WOLFSSL_OPTIONS_H */ - diff --git a/zephyr/samples/wolfssl_benchmark/boards/nrf5340dk_nrf5340_cpuapp.conf b/zephyr/samples/wolfssl_benchmark/boards/nrf5340dk_nrf5340_cpuapp.conf index b651b7b889..98d8bc4963 100644 --- a/zephyr/samples/wolfssl_benchmark/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/zephyr/samples/wolfssl_benchmark/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -1,5 +1,5 @@ # Set user_settings.h file to be used for native wolfSSL build settings -CONFIG_WOLFSSL_SETTINGS_FILE="nrf5340dk_nrf5340_user_settings.h" +#CONFIG_WOLFSSL_SETTINGS_FILE="user_settings_custom.h" ##### PSA and CC3XX ##### # Enable Nordic Security Module diff --git a/zephyr/samples/wolfssl_benchmark/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/zephyr/samples/wolfssl_benchmark/boards/nrf5340dk_nrf5340_cpuapp_ns.conf index a0e2052157..aa3bbe18ad 100644 --- a/zephyr/samples/wolfssl_benchmark/boards/nrf5340dk_nrf5340_cpuapp_ns.conf +++ b/zephyr/samples/wolfssl_benchmark/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -2,7 +2,7 @@ CONFIG_BUILD_WITH_TFM=y CONFIG_TFM_PROFILE_TYPE_NOT_SET=y # Set user_settings.h file to be used for native wolfSSL build settings -CONFIG_WOLFSSL_SETTINGS_FILE="nrf5340dk_nrf5340_user_settings.h" +#CONFIG_WOLFSSL_SETTINGS_FILE="user_settings_custom.h" ##### PSA and CC3XX ##### # Enable Nordic Security Module diff --git a/zephyr/samples/wolfssl_benchmark/prj.conf b/zephyr/samples/wolfssl_benchmark/prj.conf index b7e4eee439..41ccf7f948 100644 --- a/zephyr/samples/wolfssl_benchmark/prj.conf +++ b/zephyr/samples/wolfssl_benchmark/prj.conf @@ -26,6 +26,10 @@ CONFIG_LOG_BUFFER_SIZE=15360 #CONFIG_WOLFSSL_DEBUG=y # Entropy +CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ENTROPY_GENERATOR=y CONFIG_ENTROPY_DEVICE_RANDOM_GENERATOR=y +# Optional ARM or Intel Assembly +#CONFIG_WOLFCRYPT_ARMASM=y +#CONFIG_WOLFCRYPT_INTELASM=y diff --git a/zephyr/samples/wolfssl_test/boards/nrf5340dk_nrf5340_cpuapp.conf b/zephyr/samples/wolfssl_test/boards/nrf5340dk_nrf5340_cpuapp.conf index b651b7b889..98d8bc4963 100644 --- a/zephyr/samples/wolfssl_test/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/zephyr/samples/wolfssl_test/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -1,5 +1,5 @@ # Set user_settings.h file to be used for native wolfSSL build settings -CONFIG_WOLFSSL_SETTINGS_FILE="nrf5340dk_nrf5340_user_settings.h" +#CONFIG_WOLFSSL_SETTINGS_FILE="user_settings_custom.h" ##### PSA and CC3XX ##### # Enable Nordic Security Module diff --git a/zephyr/samples/wolfssl_test/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/zephyr/samples/wolfssl_test/boards/nrf5340dk_nrf5340_cpuapp_ns.conf index a0e2052157..aa3bbe18ad 100644 --- a/zephyr/samples/wolfssl_test/boards/nrf5340dk_nrf5340_cpuapp_ns.conf +++ b/zephyr/samples/wolfssl_test/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -2,7 +2,7 @@ CONFIG_BUILD_WITH_TFM=y CONFIG_TFM_PROFILE_TYPE_NOT_SET=y # Set user_settings.h file to be used for native wolfSSL build settings -CONFIG_WOLFSSL_SETTINGS_FILE="nrf5340dk_nrf5340_user_settings.h" +#CONFIG_WOLFSSL_SETTINGS_FILE="user_settings_custom.h" ##### PSA and CC3XX ##### # Enable Nordic Security Module diff --git a/zephyr/samples/wolfssl_test/prj.conf b/zephyr/samples/wolfssl_test/prj.conf index a989213b4c..6c8a5ca437 100644 --- a/zephyr/samples/wolfssl_test/prj.conf +++ b/zephyr/samples/wolfssl_test/prj.conf @@ -24,6 +24,6 @@ CONFIG_LOG_BUFFER_SIZE=15360 #CONFIG_WOLFSSL_DEBUG=y # Entropy +CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_ENTROPY_GENERATOR=y CONFIG_ENTROPY_DEVICE_RANDOM_GENERATOR=y - diff --git a/zephyr/samples/wolfssl_tls_sock/src/tls_sock.c b/zephyr/samples/wolfssl_tls_sock/src/tls_sock.c index 7be365321f..b930554435 100644 --- a/zephyr/samples/wolfssl_tls_sock/src/tls_sock.c +++ b/zephyr/samples/wolfssl_tls_sock/src/tls_sock.c @@ -62,6 +62,20 @@ static const char msgHTTPIndex[] = "\n" "\n"; +#ifdef HAVE_FIPS +static void myFipsCb(int ok, int err, const char* hash) +{ + printf("in my Fips callback, ok = %d, err = %d\n", ok, err); + printf("message = %s\n", wc_GetErrorString(err)); + printf("hash = %s\n", hash); + + if (err == IN_CORE_FIPS_E) { + printf("In core integrity hash check failure, copy above hash\n"); + printf("into verifyCore[] in fips_test.c and rebuild\n"); + } +} +#endif + /* DO NOT use this in production. You should implement a way * to get the current date. */ static int verifyIgnoreDateError(int preverify, WOLFSSL_X509_STORE_CTX* store) @@ -485,6 +499,9 @@ int main() { THREAD_TYPE serverThread; +#ifdef HAVE_FIPS + wolfCrypt_SetCb_fips(myFipsCb); +#endif wolfSSL_Init(); #ifdef DEBUG_WOLFSSL wolfSSL_Debugging_ON(); diff --git a/zephyr/samples/wolfssl_tls_thread/boards/nrf5340dk_nrf5340_cpuapp.conf b/zephyr/samples/wolfssl_tls_thread/boards/nrf5340dk_nrf5340_cpuapp.conf index b651b7b889..98d8bc4963 100644 --- a/zephyr/samples/wolfssl_tls_thread/boards/nrf5340dk_nrf5340_cpuapp.conf +++ b/zephyr/samples/wolfssl_tls_thread/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -1,5 +1,5 @@ # Set user_settings.h file to be used for native wolfSSL build settings -CONFIG_WOLFSSL_SETTINGS_FILE="nrf5340dk_nrf5340_user_settings.h" +#CONFIG_WOLFSSL_SETTINGS_FILE="user_settings_custom.h" ##### PSA and CC3XX ##### # Enable Nordic Security Module diff --git a/zephyr/samples/wolfssl_tls_thread/boards/nrf5340dk_nrf5340_cpuapp_ns.conf b/zephyr/samples/wolfssl_tls_thread/boards/nrf5340dk_nrf5340_cpuapp_ns.conf index a0e2052157..aa3bbe18ad 100644 --- a/zephyr/samples/wolfssl_tls_thread/boards/nrf5340dk_nrf5340_cpuapp_ns.conf +++ b/zephyr/samples/wolfssl_tls_thread/boards/nrf5340dk_nrf5340_cpuapp_ns.conf @@ -2,7 +2,7 @@ CONFIG_BUILD_WITH_TFM=y CONFIG_TFM_PROFILE_TYPE_NOT_SET=y # Set user_settings.h file to be used for native wolfSSL build settings -CONFIG_WOLFSSL_SETTINGS_FILE="nrf5340dk_nrf5340_user_settings.h" +#CONFIG_WOLFSSL_SETTINGS_FILE="user_settings_custom.h" ##### PSA and CC3XX ##### # Enable Nordic Security Module diff --git a/zephyr/samples/wolfssl_tls_thread/prj.conf b/zephyr/samples/wolfssl_tls_thread/prj.conf index 4a1e290a6b..95ebedcbb6 100644 --- a/zephyr/samples/wolfssl_tls_thread/prj.conf +++ b/zephyr/samples/wolfssl_tls_thread/prj.conf @@ -1,6 +1,7 @@ # Kernel options CONFIG_MAIN_STACK_SIZE=16384 CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y CONFIG_INIT_STACKS=y CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=65536 @@ -35,7 +36,7 @@ CONFIG_LOG_MODE_IMMEDIATE=y CONFIG_WOLFSSL=y CONFIG_WOLFSSL_BUILTIN=y -CONFIG_WOLFSSL_TLS_VERSION_1_2=y +CONFIG_WOLFSSL_TLS_VERSION_1_3=y CONFIG_WOLFSSL_KEY_EXCHANGE_ALL_ENABLED=y CONFIG_WOLFSSL_CIPHER_ALL_ENABLED=y CONFIG_WOLFSSL_MAC_ALL_ENABLED=y diff --git a/zephyr/samples/wolfssl_tls_thread/src/tls_threaded.c b/zephyr/samples/wolfssl_tls_thread/src/tls_threaded.c index 490e3362e2..cd7aad9016 100644 --- a/zephyr/samples/wolfssl_tls_thread/src/tls_threaded.c +++ b/zephyr/samples/wolfssl_tls_thread/src/tls_threaded.c @@ -89,6 +89,20 @@ static const char msgHTTPIndex[] = "\n" "\n"; +#ifdef HAVE_FIPS +static void myFipsCb(int ok, int err, const char* hash) +{ + printf("in my Fips callback, ok = %d, err = %d\n", ok, err); + printf("message = %s\n", wc_GetErrorString(err)); + printf("hash = %s\n", hash); + + if (err == IN_CORE_FIPS_E) { + printf("In core integrity hash check failure, copy above hash\n"); + printf("into verifyCore[] in fips_test.c and rebuild\n"); + } +} +#endif + /* wolfSSL client wants to read data from the server. */ static int recv_client(WOLFSSL* ssl, char* buff, int sz, void* ctx) { @@ -575,6 +589,9 @@ int main() utctime.tv_nsec = 0; clock_settime(CLOCK_REALTIME, &utctime); +#ifdef HAVE_FIPS + wolfCrypt_SetCb_fips(myFipsCb); +#endif wolfSSL_Init(); #ifdef DEBUG_WOLFSSL wolfSSL_Debugging_ON(); diff --git a/zephyr/user_settings-tls-generic.h b/zephyr/user_settings-tls-generic.h deleted file mode 100644 index 32a28bbc2c..0000000000 --- a/zephyr/user_settings-tls-generic.h +++ /dev/null @@ -1,153 +0,0 @@ -/* user_settings-tls-generic.h - * generated from configure options - * - * Copyright (C) 2006-2023 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_OPTIONS_H -#define WOLFSSL_OPTIONS_H - - -#ifdef __cplusplus -extern "C" { -#endif - -#if 0 -#undef SINGLE_THREADED -#define SINGLE_THREADED -#endif - -#undef TFM_TIMING_RESISTANT -#define TFM_TIMING_RESISTANT - -#undef ECC_TIMING_RESISTANT -#define ECC_TIMING_RESISTANT - -#undef WC_RSA_BLINDING -#define WC_RSA_BLINDING - -#undef HAVE_AESGCM -#define HAVE_AESGCM - -#undef WOLFSSL_SHA512 -#define WOLFSSL_SHA512 - -#undef WOLFSSL_SHA384 -#define WOLFSSL_SHA384 - -#undef NO_DSA -#define NO_DSA - -#undef HAVE_ECC -#define HAVE_ECC - -#undef TFM_ECC256 -#define TFM_ECC256 - -#undef WOLFSSL_BASE64_ENCODE -#define WOLFSSL_BASE64_ENCODE - -#undef NO_RC4 -#define NO_RC4 - -#undef WOLFSSL_SHA224 -#define WOLFSSL_SHA224 - -#undef WOLFSSL_SHA3 -#define WOLFSSL_SHA3 - -#undef HAVE_POLY1305 -#define HAVE_POLY1305 - -#undef HAVE_ONE_TIME_AUTH -#define HAVE_ONE_TIME_AUTH - -#undef HAVE_CHACHA -#define HAVE_CHACHA - -#undef HAVE_HASHDRBG -#define HAVE_HASHDRBG - -#undef NO_FILESYSTEM -#define NO_FILESYSTEM - -#undef HAVE_TLS_EXTENSIONS -#define HAVE_TLS_EXTENSIONS - -#undef HAVE_SUPPORTED_CURVES -#define HAVE_SUPPORTED_CURVES - -#undef HAVE_EXTENDED_MASTER -#define HAVE_EXTENDED_MASTER - -#undef NO_PSK -#define NO_PSK - -#undef NO_MD4 -#define NO_MD4 - -#undef NO_PWDBASED -#define NO_PWDBASED - -#undef USE_FAST_MATH -#define USE_FAST_MATH - -#undef WOLFSSL_NO_ASM -#define WOLFSSL_NO_ASM - -#undef WOLFSSL_X86_BUILD -#define WOLFSSL_X86_BUILD - -#undef WC_NO_ASYNC_THREADING -#define WC_NO_ASYNC_THREADING - -#undef NO_DES3 -#define NO_DES3 - -#undef WOLFSSL_STATIC_MEMORY -#define WOLFSSL_STATIC_MEMORY - -#undef WOLFSSL_TLS13 -#define WOLFSSL_TLS13 - -#undef HAVE_HKDF -#define HAVE_HKDF - -#undef WC_RSA_PSS -#define WC_RSA_PSS - -#undef HAVE_FFDHE_2048 -#define HAVE_FFDHE_2048 - -#if 0 -#undef WOLFSSL_HAVE_SP_RSA -#define WOLFSSL_HAVE_SP_RSA -#undef WOLFSSL_HAVE_SP_DH -#define WOLFSSL_HAVE_SP_DH -#undef WOLFSSL_HAVE_SP_ECC -#define WOLFSSL_HAVE_SP_ECC -#endif - -#ifdef __cplusplus -} -#endif - - -#endif /* WOLFSSL_OPTIONS_H */ - diff --git a/zephyr/user_settings.h b/zephyr/user_settings.h index ba0ba9b2e7..8c8f2e3032 100644 --- a/zephyr/user_settings.h +++ b/zephyr/user_settings.h @@ -1,6 +1,6 @@ /* user_settings.h * - * Copyright (C) 2006-2023 wolfSSL Inc. + * Copyright (C) 2006-2024 wolfSSL Inc. * * This file is part of wolfSSL. * @@ -23,120 +23,405 @@ #define USER_SETTINGS_H #ifdef CONFIG_WOLFSSL -#ifdef CONFIG_WOLFSSL_SETTINGS_FILE - -#include CONFIG_WOLFSSL_SETTINGS_FILE +/* If a custom user_settings file is provided use it instead */ +#ifdef WOLFSSL_SETTINGS_FILE +#include WOLFSSL_SETTINGS_FILE #else #ifdef __cplusplus extern "C" { #endif + +/* ------------------------------------------------------------------------- */ +/* Platform */ +/* ------------------------------------------------------------------------- */ +#define WOLFSSL_GENERAL_ALIGNMENT 4 /* platform requires 32-bit alignment on uint32_t */ +#define SIZEOF_LONG_LONG 8 /* long long is 8 bytes / 64-bit */ +//#define WOLFSSL_NO_ASM /* optionally disable inline assembly support */ +#define WOLFSSL_IGNORE_FILE_WARN /* ignore file includes not required */ +//#define WOLFSSL_SMALL_STACK /* option to reduce stack size, offload to heap */ +#define BENCH_EMBEDDED /* use smaller buffers in benchmark / tests */ + +/* Network stack */ +/* Default is POSIX sockets */ +//#define WOLFSSL_USER_IO /* Use the SetIO callbacks, not the internal wolfio.c socket code */ +//#define WOLFSSL_LWIP +//#define WOLFSSL_LWIP_NATIVE +//#define FREERTOS_TCP + +/* RTOS */ +/* Default is POSIX mutex and pthreads*/ +//#define SINGLE_THREADED +//#define FREERTOS +#define NO_FILESYSTEM +#define NO_WRITEV + +/* ------------------------------------------------------------------------- */ +/* Hardware */ +/* ------------------------------------------------------------------------- */ +/* CryptoCell support */ #if 0 -#undef SINGLE_THREADED -#define SINGLE_THREADED + //#define WOLFSSL_CRYPTOCELL + //#define WOLFSSL_CRYPTOCELL_AES +#endif +/* PSA support */ +#ifdef CONFIG_MBEDTLS_PSA_CRYPTO_C + #define WOLFSSL_HAVE_PSA + #ifndef SINGLE_THREADED + #define WOLFSSL_PSA_GLOBAL_LOCK + #endif + #define WC_NO_HASHDRBG /* use PSA RNG directly via wc_psa_get_random */ #endif -#undef TFM_TIMING_RESISTANT -#define TFM_TIMING_RESISTANT +/* ------------------------------------------------------------------------- */ +/* FIPS */ +/* ------------------------------------------------------------------------- */ +#ifdef CONFIG_WOLFCRYPT_FIPS + /* FIPS Ready */ + #define HAVE_FIPS_VERSION 5 + #define HAVE_FIPS_VERSION_MINOR 3 +#endif -#undef ECC_TIMING_RESISTANT -#define ECC_TIMING_RESISTANT -#undef WC_RSA_BLINDING -#define WC_RSA_BLINDING +/* ------------------------------------------------------------------------- */ +/* TLS */ +/* ------------------------------------------------------------------------- */ +/* TLS v1.2 (on by default) */ +#ifdef CONFIG_WOLFSSL_TLS_VERSION_1_2 + #undef WOLFSSL_NO_TLS12 +#else + #define WOLFSSL_NO_TLS12 +#endif +//#define NO_WOLFSSL_SERVER /* Optionally disable TLS server code */ +//#define NO_WOLFSSL_CLIENT /* Optionally disable TLS client code */ -#undef HAVE_AESGCM -#define HAVE_AESGCM +/* TLS v1.3 */ +#if defined(CONFIG_WOLFSSL_TLS_VERSION_1_3) || defined(CONFIG_WOLFSSL_TLS13_ENABLED) + #define WOLFSSL_TLS13 +#endif -#undef WOLFSSL_SHA512 -#define WOLFSSL_SHA512 +/* Disable older TLS version prior to 1.2 */ +#define NO_OLD_TLS -#undef WOLFSSL_SHA384 -#define WOLFSSL_SHA384 +/* Enable default TLS extensions */ +#define HAVE_TLS_EXTENSIONS +#define HAVE_SUPPORTED_CURVES +#define HAVE_EXTENDED_MASTER +#define HAVE_ENCRYPT_THEN_MAC +#define HAVE_SERVER_RENEGOTIATION_INFO +#define HAVE_SNI /* optional Server Name Indicator (SNI) */ + +/* ASN */ +#define WOLFSSL_ASN_TEMPLATE /* use newer ASN template asn.c code (default) */ +#if 0 /* optional space reductions */ + #define WOLFSSL_NO_ASN_STRICT + #define IGNORE_NAME_CONSTRAINTS +#endif -#undef NO_DSA -#define NO_DSA +/* Session Cache */ +#if 1 + #define SMALL_SESSION_CACHE + #ifdef WOLFSSL_TLS13 + #define HAVE_SESSION_TICKET /* session tickets required for resumption in TLS v1.3 */ + #endif +#else + #define NO_SESSION_CACHE /* disable session resumption */ +#endif -#undef HAVE_ECC -#define HAVE_ECC +/* PSK */ +#define NO_PSK /* disable pre-shared-key support */ -#undef TFM_ECC256 -#define TFM_ECC256 -#undef WOLFSSL_BASE64_ENCODE -#define WOLFSSL_BASE64_ENCODE +/* ------------------------------------------------------------------------- */ +/* Algorithms */ +/* ------------------------------------------------------------------------- */ +/* RNG */ +#ifndef WC_NO_HASHDRBG + #define HAVE_HASHDRBG /* Use DRBG SHA2-256 and seed */ +#endif -#undef NO_RC4 -#define NO_RC4 +/* ECC */ +#if 1 + #define HAVE_ECC + #define ECC_USER_CURVES /* Enable only ECC curves specific */ + #undef NO_ECC256 /* Enable SECP256R1 only (on by default) */ + #define ECC_TIMING_RESISTANT /* Enable Timing Resistance */ + + //#define ECC_SHAMIR /* Optional ECC calculation speed improvement if not using SP implementation */ + //#define WOLFSSL_CUSTOM_CURVES /* enable other curves (not just prime) */ + //#define HAVE_ECC_SECPR2 + //#define HAVE_ECC_SECPR3 + //#define HAVE_ECC_BRAINPOOL + //#define HAVE_ECC_KOBLITZ + //#define HAVE_ECC_CDH /* Co-factor */ + //#define HAVE_COMP_KEY /* Compressed key support */ + //#define FP_ECC /* Fixed point caching - speed repeated operations against same key */ + //#define HAVE_ECC_ENCRYPT + //#define WOLFCRYPT_HAVE_ECCSI + //#define WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT +#endif -#undef WOLFSSL_SHA224 -#define WOLFSSL_SHA224 +#define WOLFSSL_OLD_PRIME_CHECK /* Use faster DH prime checking */ + +/* RSA */ +#if 1 + #undef NO_RSA + #define WC_RSA_BLINDING + //#define WC_RSA_NO_PADDING + //#define RSA_LOW_MEM + + #if 0 + #define WOLFSSL_KEY_GEN /* For RSA Key gen only */ + #endif + #if defined(WOLFSSL_TLS13) || defined(CONFIG_WOLFSSL_RSA_PSS) + /* TLS v1.3 requires RSA PSS padding */ + #define WC_RSA_PSS + //#define WOLFSSL_PSS_LONG_SALT + #endif +#else + #define NO_RSA +#endif -#undef WOLFSSL_SHA3 -#define WOLFSSL_SHA3 +/* DH */ +#if 0 + #undef NO_DH /* on by default */ + #define WOLFSSL_DH_CONST /* don't rely on pow/log */ + #define HAVE_FFDHE_2048 + #define HAVE_FFDHE_3072 + #define HAVE_DH_DEFAULT_PARAMS + //#define WOLFSSL_DH_EXTRA /* Enable additional DH key import/export */ +#else + #define NO_DH +#endif -#undef HAVE_POLY1305 -#define HAVE_POLY1305 +/* ChaCha20 / Poly1305 */ +#if 1 + #define HAVE_CHACHA + #define HAVE_POLY1305 -#undef HAVE_ONE_TIME_AUTH -#define HAVE_ONE_TIME_AUTH + /* Needed for Poly1305 */ + #define HAVE_ONE_TIME_AUTH +#endif -#undef HAVE_CHACHA -#define HAVE_CHACHA +/* Ed25519 / Curve25519 */ +#if 0 + #define HAVE_CURVE25519 + #define HAVE_ED25519 /* ED25519 Requires SHA512 */ -#undef HAVE_HASHDRBG -#define HAVE_HASHDRBG + /* Optionally use small math (less flash usage, but much slower) */ + //#define CURVED25519_SMALL +#endif -#undef NO_FILESYSTEM -#define NO_FILESYSTEM +/* SHA-1 */ +#if 0 + #undef NO_SHA /* on by default */ + //#define USE_SLOW_SHA /* 1k smaller, but 25% slower */ +#else + #define NO_SHA +#endif -#undef HAVE_TLS_EXTENSIONS -#define HAVE_TLS_EXTENSIONS +/* SHA2-256 */ +#if 1 + #undef NO_SHA256 /* on by default */ + //#define USE_SLOW_SHA256 /* ~2k smaller and about 25% slower */ + #define WOLFSSL_SHA224 +#else + #define NO_SHA256 +#endif -#undef HAVE_SUPPORTED_CURVES -#define HAVE_SUPPORTED_CURVES +/* SHA2-384/512 */ +#if 1 + #define WOLFSSL_SHA384 + #define WOLFSSL_SHA512 + //#define USE_SLOW_SHA512 /* Over twice as small, but 50% slower */ +#endif -#undef HAVE_EXTENDED_MASTER -#define HAVE_EXTENDED_MASTER +/* SHA-3 */ +#if 1 + #define WOLFSSL_SHA3 +#endif + +/* AES */ +#define HAVE_AES_ECB +/* AES-CBC */ +#if 1 + #define HAVE_AES_CBC +#else + #define NO_AES_CBC +#endif +/* AES-GCM */ +#if 1 + #define HAVE_AESGCM + #define GCM_SMALL /* GCM Method: GCM_TABLE_4BIT, GCM_SMALL, GCM_WORD32 or GCM_TABLE */ + //#define WOLFSSL_AESGCM_STREAM +#endif +//#define HAVE_AES_DECRYPT +//#define WOLFSSL_AES_COUNTER +//#define WOLFSSL_AES_CFB +//#define WOLFSSL_AES_OFB +//#define HAVE_AESCCM +//#define WOLFSSL_AES_XTS + +//#define NO_AES_128 +//#define NO_AES_192 +//#define NO_AES_256 +//#define WOLFSSL_AES_SMALL_TABLES +//#define WOLFSSL_AES_NO_UNROLL + + +/* HKDF */ +#if defined(WOLFSSL_TLS13) || defined(CONFIG_WOLFSSL_HKDF) + #define HAVE_HKDF +#endif + +/* CMAC - Zephyr nRF BTLE needs CMAC */ +#if 1 + #define WOLFSSL_AES_DIRECT + #define WOLFSSL_CMAC +#endif -#undef NO_PSK -#define NO_PSK -#undef NO_MD4 +/* Optional Features */ +#define WOLFSSL_BASE64_ENCODE /* Enable Base64 encoding */ +//#define WC_NO_CACHE_RESISTANT /* systems with cache should enable this for AES, ECC, RSA and DH */ +//#define WOLFSSL_CERT_GEN +//#define WOLFSSL_CERT_REQ +//#define WOLFSSL_CERT_EXT +//#define NO_PWDBASED + + +/* Disable Algorithms */ +#define NO_DSA +#define NO_RC4 #define NO_MD4 +#define NO_MD5 +#define NO_DES3 +#define WOLFSSL_NO_SHAKE128 +#define WOLFSSL_NO_SHAKE256 + + + +/* ------------------------------------------------------------------------- */ +/* Math */ +/* ------------------------------------------------------------------------- */ +/* Math Options */ +/* Multi-precision - generic math for all keys sizes and curves */ +#if 1 + #define WOLFSSL_SP_MATH /* no multi-precision math, only single */ +#elif 1 + /* wolf mp math (sp_int.c) */ + #define WOLFSSL_SP_MATH_ALL /* use SP math for all key sizes and curves */ + //#define WOLFSSL_SP_NO_MALLOC + + /* use smaller version of code */ + #define WOLFSSL_SP_SMALL + + /* Define the maximum math bits used */ + #if !defined(NO_RSA) || !defined(NO_DH) + #define SP_INT_BITS 2048 + #elif defined(HAVE_ECC) + #define SP_INT_BITS 256 + #endif + +#elif 1 + /* Fast Math (tfm.c) (stack based and timing resistant) */ + #define USE_FAST_MATH + #define TFM_TIMING_RESISTANT + + /* Define the maximum math bits used (2 * max) */ + #if !defined(NO_RSA) || !defined(NO_DH) + #define FP_MAX_BITS (2*2048) + #ifdef HAVE_ECC + #define ALT_ECC_SIZE /* use heap allocation for ECC point */ + #endif + #elif defined(HAVE_ECC) + #define FP_MAX_BITS (2*256) + #endif + #ifdef HAVE_ECC + //#define TFM_ECC256 /* optional speedup for ECC-256 bit */ + #endif +#else + /* Normal (integer.c) (heap based, not timing resistant) - not recommended */ + #define USE_INTEGER_HEAP_MATH +#endif -#undef NO_PWDBASED -#define NO_PWDBASED +/* Single Precision (optional) */ +/* Math written for specific curves and key sizes */ +#if 1 + #ifdef HAVE_ECC + #define WOLFSSL_HAVE_SP_ECC + //#define WOLFSSL_SP_NO_256 + //#define WOLFSSL_SP_384 + //#define WOLFSSL_SP_521 + #endif + #ifndef NO_RSA + #define WOLFSSL_HAVE_SP_RSA + //#define WOLFSSL_SP_NO_2048 + //#define WOLFSSL_SP_NO_3072 + //#define WOLFSSL_SP_4096 + #endif + #ifndef NO_DH + #define WOLFSSL_HAVE_SP_DH + #endif + + #define WOLFSSL_SP_SMALL /* use smaller version of code */ + //#define WOLFSSL_SP_NO_MALLOC /* disable heap in wolf/SP math */ + //#define SP_DIV_WORD_USE_DIV /* no div64 */ + + #if 0 + /* optional speedup with inline assembly */ + //#define WOLFSSL_SP_ARM_CORTEX_M_ASM /* Cortex-M3+ */ + //#define WOLFSSL_SP_ARM_THUMB_ASM /* Cortex-M0+ thumb */ + //#define WOLFSSL_SP_ARM32_ASM /* Cortex-R */ + //#define WOLFSSL_SP_ARM64_ASM /* Cortex-A */ + //#define WOLFSSL_SP_USE_UDIV + #endif +#endif -#undef USE_FAST_MATH -#define USE_FAST_MATH +/* ------------------------------------------------------------------------- */ +/* Assembly Speedups for Symmetric Algorithms */ +/* ------------------------------------------------------------------------- */ -#undef WOLFSSL_NO_ASM -#define WOLFSSL_NO_ASM +#ifdef CONFIG_WOLFCRYPT_ARMASM + #define WOLFSSL_ARMASM + #define WOLFSSL_NO_HASH_RAW + #define WOLFSSL_ARMASM_INLINE /* use inline .c versions */ + #define WOLFSSL_ARMASM_NO_NEON -#undef WOLFSSL_X86_BUILD -#define WOLFSSL_X86_BUILD + /* Default is ARMv8 */ -#undef WC_NO_ASYNC_THREADING -#define WC_NO_ASYNC_THREADING + #if 0 /* ARMv7 */ + #define WOLFSSL_ARM_ARCH 7 + #define WOLFSSL_ARMASM_NO_HW_CRYPTO /* enable if processor does not support aes/sha instructions */ + #endif +#endif -#undef NO_DES3 -#define NO_DES3 +#ifdef CONFIG_WOLFCRYPT_INTELASM + #define USE_INTEL_SPEEDUP + #define WOLFSSL_X86_64_BUILD /* 64-bit */ + //#define WOLFSSL_X86_BUILD /* 32-bit */ -#undef WOLFSSL_STATIC_MEMORY -#define WOLFSSL_STATIC_MEMORY + /* Issues with building AESNI "_mm_aesimc_si128" always_inline */ + //#define WOLFSSL_AESNI +#endif -#if 0 -#undef WOLFSSL_HAVE_SP_RSA -#define WOLFSSL_HAVE_SP_RSA -#undef WOLFSSL_HAVE_SP_DH -#define WOLFSSL_HAVE_SP_DH -#undef WOLFSSL_HAVE_SP_ECC -#define WOLFSSL_HAVE_SP_ECC + +/* ------------------------------------------------------------------------- */ +/* Debugging */ +/* ------------------------------------------------------------------------- */ +#undef DEBUG_WOLFSSL +#undef NO_ERROR_STRINGS +#ifdef CONFIG_WOLFSSL_DEBUG + #define DEBUG_WOLFSSL +#else + #if 1 + #define NO_ERROR_STRINGS + #endif #endif + #ifdef __cplusplus } #endif diff --git a/zephyr/wolfssl/options.h b/zephyr/wolfssl/options.h index e69de29bb2..5c637481bb 100644 --- a/zephyr/wolfssl/options.h +++ b/zephyr/wolfssl/options.h @@ -0,0 +1 @@ +/* default blank options to appease code that may require it */