diff --git a/.github/workflows/build-config-matrix.yml b/.github/workflows/build-config-matrix.yml new file mode 100644 index 0000000..17dd2e8 --- /dev/null +++ b/.github/workflows/build-config-matrix.yml @@ -0,0 +1,82 @@ +name: Build Config Matrix + +on: + push: + pull_request: + +jobs: + build-config-matrix: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - name: baseline + modifiers: "" + - name: md5 + modifiers: "-WOLFSSL_MD5 +NO_MD5" + - name: ripemd + modifiers: "-WOLFSSL_RIPEMD" + - name: sha1 + modifiers: "+NO_SHA" + - name: sha224 + modifiers: "-WOLFSSL_SHA224" + - name: sha384 + modifiers: "-WOLFSSL_SHA384" + - name: sha512-family + modifiers: "-WOLFSSL_SHA512 -WOLFSSL_SHA384 -HAVE_ED25519 -WOLFSSL_ED25519_STREAMING_VERIFY -HAVE_ED448 -WOLFSSL_ED448_STREAMING_VERIFY +NO_SHA512" + - name: sha3-ed448 + modifiers: "-WOLFSSL_SHA3 -HAVE_ED448 -WOLFSSL_ED448_STREAMING_VERIFY" + - name: des3 + modifiers: "-WOLFSSL_DES3 -WOLFSSL_DES_ECB +NO_DES3" + - name: aes-gcm + modifiers: "-HAVE_AESGCM" + - name: aes-ccm + modifiers: "-HAVE_AESCCM" + - name: aes-ctr + modifiers: "-WOLFSSL_AES_COUNTER" + - name: aes-cfb + modifiers: "-WOLFSSL_AES_CFB" + - name: aes-ofb + modifiers: "-WOLFSSL_AES_OFB" + - name: aes-ecb + modifiers: "-HAVE_AES_ECB" + - name: des-ecb + modifiers: "-WOLFSSL_DES_ECB" + - name: cmac + modifiers: "-WOLFSSL_CMAC" + - name: chacha20-poly1305 + modifiers: "-HAVE_CHACHA -HAVE_POLY1305" + - name: curve25519 + modifiers: "-HAVE_CURVE25519" + - name: ed25519 + modifiers: "-HAVE_ED25519 -WOLFSSL_ED25519_STREAMING_VERIFY" + - name: curve448 + modifiers: "-HAVE_CURVE448" + - name: ed448 + modifiers: "-HAVE_ED448 -WOLFSSL_ED448_STREAMING_VERIFY" + - name: hkdf + modifiers: "-HAVE_HKDF -HAVE_ECC_ENCRYPT" + - name: tls-prf + modifiers: "-WOLFSSL_HAVE_PRF" + - name: pbkdf2 + modifiers: "-HAVE_PBKDF2 +NO_PBKDF2" + - name: ecc384 + modifiers: "-WOLFSSL_SP_384 -HAVE_ECC384" + - name: rsa-1024 + modifiers: "-WOLFSSL_SP_1024 -RSA_MIN_SIZE +RSA_MIN_SIZE=2048" + + steps: + - name: Check out wolfPSA + uses: actions/checkout@v4 + + - name: Install build dependencies + run: | + sudo apt-get update + sudo apt-get install -y build-essential + + - name: Clone sibling wolfSSL + run: git clone --depth 1 https://github.com/wolfSSL/wolfssl ../wolfssl + + - name: Build ${{ matrix.name }} + run: ./build-test/build-variant.sh "${{ matrix.name }}" ${{ matrix.modifiers }} diff --git a/.gitignore b/.gitignore index 7d49aca..36efc97 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ wolfcrypt-benchmark/wolfcrypt-psa-benchmark wolfcrypt-psa-benchmark .store/ *.log +.codex diff --git a/build-test/build-variant.sh b/build-test/build-variant.sh new file mode 100755 index 0000000..e692e85 --- /dev/null +++ b/build-test/build-variant.sh @@ -0,0 +1,106 @@ +#!/bin/sh +# +# Build a wolfPSA variant with a baseline set of wolfcrypt-native defines, +# optionally modified by lane-specific +/- tokens. +# +# Usage: build-variant.sh [modifier ...] +# +# A modifier is one of: +# +FLAG add -DFLAG to the compile flags +# +FLAG=VALUE add -DFLAG=VALUE +# -FLAG remove -DFLAG (or -DFLAG=...) from the baseline +# +# The baseline below must list every wolfcrypt-native knob wolfPSA needs for +# a full build. Keep the names in sync with wolfssl/wolfcrypt/settings.h. + +set -eu + +script_dir=$(CDPATH= cd -- "$(dirname "$0")" && pwd) +repo_root=$(CDPATH= cd -- "${script_dir}/.." && pwd) +variant_name=${1:?usage: build-variant.sh [modifier ...]} +shift + +# Baseline — every feature enabled. Listed one per line for easy grep/edit. +BASELINE=" +WOLFSSL_SP_MATH_ALL +WOLFSSL_HAVE_SP_RSA +WOLFSSL_HAVE_SP_ECC +HAVE_SP_ECC +WOLFSSL_KEY_GEN +WC_NO_HARDEN +HAVE_ECC +HAVE_ECC_KEY_EXPORT +HAVE_ECC_KEY_IMPORT +WOLFSSL_ECDSA_DETERMINISTIC_K +WC_RSA_PSS +WOLFSSL_PSS_SALT_LEN_DISCOVER +WOLFSSL_RSA_OAEP +WOLFSSL_SP_1024 +RSA_MIN_SIZE=1024 +WOLFSSL_SP_384 +HAVE_ECC384 +WOLFSSL_HAVE_PRF +HAVE_HKDF +HAVE_ECC_ENCRYPT +HAVE_PBKDF2 +WOLFSSL_MD5 +WOLFSSL_RIPEMD +WOLFSSL_SHA224 +WOLFSSL_SHA384 +WOLFSSL_SHA512 +WOLFSSL_SHA3 +WOLFSSL_DES3 +WOLFSSL_DES_ECB +HAVE_AESGCM +HAVE_AESCCM +HAVE_AES_ECB +WOLFSSL_AES_COUNTER +WOLFSSL_AES_CFB +WOLFSSL_AES_OFB +WOLFSSL_CMAC +HAVE_CHACHA +HAVE_POLY1305 +HAVE_CURVE25519 +HAVE_ED25519 +WOLFSSL_ED25519_STREAMING_VERIFY +HAVE_CURVE448 +HAVE_ED448 +WOLFSSL_ED448_STREAMING_VERIFY +" + +flags="${BASELINE}" + +for mod in "$@"; do + case "${mod}" in + +*) + token=${mod#+} + flags="${flags} +${token}" + ;; + -*) + name=${mod#-} + # Drop any line that is either exactly "name" or "name=...". + flags=$(printf '%s\n' "${flags}" | awk -v n="${name}" ' + $0 == n { next } + index($0, n "=") == 1 { next } + { print }') + ;; + *) + printf 'build-variant.sh: unknown modifier %s\n' "${mod}" >&2 + exit 2 + ;; + esac +done + +cppflags="-DWOLFSSL_USER_SETTINGS" +for tok in ${flags}; do + [ -z "${tok}" ] && continue + cppflags="${cppflags} -D${tok}" +done + +make -C "${repo_root}" clean BUILD_DIR="${repo_root}/build-test/out/${variant_name}" >/dev/null +make -C "${repo_root}" \ + BUILD_DIR="${repo_root}/build-test/out/${variant_name}" \ + USER_SETTINGS_PATH="${repo_root}/build-test" \ + WOLFSSL_CPPFLAGS="${cppflags}" \ + libwolfpsa.a diff --git a/build-test/user_settings.h b/build-test/user_settings.h new file mode 100644 index 0000000..1df443c --- /dev/null +++ b/build-test/user_settings.h @@ -0,0 +1,35 @@ +/* user_settings.h + * + * Copyright (C) 2026 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_USER_SETTINGS_H +#define WOLFSSL_USER_SETTINGS_H + +/* The build-config-matrix harness drives every algorithm feature via + * wolfcrypt-native defines passed on the compiler command line by + * build-test/build-variant.sh. This file only sets up invariants that are + * always required (or always forbidden) regardless of the lane. */ + +#define WOLFCRYPT_ONLY +#define SINGLE_THREADED +#define WOLFSSL_PSA_ENGINE +#define NO_DSA + +#endif /* WOLFSSL_USER_SETTINGS_H */ diff --git a/src/psa_aead.c b/src/psa_aead.c index 60e0221..cb74f5c 100644 --- a/src/psa_aead.c +++ b/src/psa_aead.c @@ -213,6 +213,21 @@ static psa_status_t wolfpsa_aead_setup(psa_aead_operation_t *operation, if (!PSA_ALG_IS_AEAD(alg) || PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_CCM_STAR_NO_TAG)) { return PSA_ERROR_NOT_SUPPORTED; } +#ifndef HAVE_AESGCM + if (PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_GCM)) { + return PSA_ERROR_NOT_SUPPORTED; + } +#endif +#ifndef HAVE_AESCCM + if (PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_CCM)) { + return PSA_ERROR_NOT_SUPPORTED; + } +#endif +#if !defined(HAVE_CHACHA) || !defined(HAVE_POLY1305) + if (PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_CHACHA20_POLY1305)) { + return PSA_ERROR_NOT_SUPPORTED; + } +#endif status = wolfpsa_aead_check_key(key, usage, alg, &attributes, &key_data, &key_data_length); @@ -238,12 +253,14 @@ static psa_status_t wolfpsa_aead_setup(psa_aead_operation_t *operation, return PSA_ERROR_INVALID_ARGUMENT; } ctx->direction = (usage == PSA_KEY_USAGE_ENCRYPT) ? 1 : 0; +#ifdef HAVE_AESCCM if (PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_CCM) && wc_AesCcmCheckTagSize((int)ctx->tag_length) != 0) { wolfpsa_forcezero_free_key_data(key_data, key_data_length); XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER); return PSA_ERROR_INVALID_ARGUMENT; } +#endif ctx->key = (uint8_t *)XMALLOC(key_data_length, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -471,7 +488,9 @@ static psa_status_t wolfpsa_aead_encrypt_final(wolfpsa_aead_ctx_t *ctx, size_t *tag_length) { int ret; +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) size_t chacha_ciphertext_size = 0; +#endif const uint8_t *input; const uint8_t *aad; @@ -490,12 +509,14 @@ static psa_status_t wolfpsa_aead_encrypt_final(wolfpsa_aead_ctx_t *ctx, return PSA_ERROR_INVALID_ARGUMENT; } +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) if (PSA_ALG_AEAD_EQUAL(ctx->alg, PSA_ALG_CHACHA20_POLY1305)) { if (ctx->input_length > SIZE_MAX - ctx->tag_length) { return PSA_ERROR_BUFFER_TOO_SMALL; } chacha_ciphertext_size = ctx->input_length + ctx->tag_length; } +#endif if (ciphertext_size < ctx->input_length) { return PSA_ERROR_BUFFER_TOO_SMALL; @@ -514,6 +535,7 @@ static psa_status_t wolfpsa_aead_encrypt_final(wolfpsa_aead_ctx_t *ctx, aad = wolfpsa_aead_nonnull_data(ctx->aad, ctx->aad_length); if (PSA_ALG_AEAD_EQUAL(ctx->alg, PSA_ALG_GCM)) { +#ifdef HAVE_AESGCM Aes aes; ret = wc_AesInit(&aes, NULL, INVALID_DEVID); if (ret == 0) { @@ -531,8 +553,12 @@ static psa_status_t wolfpsa_aead_encrypt_final(wolfpsa_aead_ctx_t *ctx, if (ret != 0) { return wc_error_to_psa_status(ret); } +#else + return PSA_ERROR_NOT_SUPPORTED; +#endif } else if (PSA_ALG_AEAD_EQUAL(ctx->alg, PSA_ALG_CCM)) { +#ifdef HAVE_AESCCM Aes aes; if (wc_AesCcmCheckTagSize((int)ctx->tag_length) != 0) { return PSA_ERROR_NOT_SUPPORTED; @@ -553,8 +579,12 @@ static psa_status_t wolfpsa_aead_encrypt_final(wolfpsa_aead_ctx_t *ctx, if (ret != 0) { return wc_error_to_psa_status(ret); } +#else + return PSA_ERROR_NOT_SUPPORTED; +#endif } else if (PSA_ALG_AEAD_EQUAL(ctx->alg, PSA_ALG_CHACHA20_POLY1305)) { +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) size_t out_len = 0; uint8_t *tmp = (uint8_t *)XMALLOC(chacha_ciphertext_size, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -581,6 +611,9 @@ static psa_status_t wolfpsa_aead_encrypt_final(wolfpsa_aead_ctx_t *ctx, XMEMCPY(tag, tmp + ctx->input_length, ctx->tag_length); wc_ForceZero(tmp, chacha_ciphertext_size); XFREE(tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#else + return PSA_ERROR_NOT_SUPPORTED; +#endif } else { return PSA_ERROR_NOT_SUPPORTED; @@ -639,6 +672,7 @@ static psa_status_t wolfpsa_aead_decrypt_final(wolfpsa_aead_ctx_t *ctx, aad = wolfpsa_aead_nonnull_data(ctx->aad, ctx->aad_length); if (PSA_ALG_AEAD_EQUAL(ctx->alg, PSA_ALG_GCM)) { +#ifdef HAVE_AESGCM Aes aes; ret = wc_AesInit(&aes, NULL, INVALID_DEVID); if (ret == 0) { @@ -659,8 +693,12 @@ static psa_status_t wolfpsa_aead_decrypt_final(wolfpsa_aead_ctx_t *ctx, if (ret != 0) { return wc_error_to_psa_status(ret); } +#else + return PSA_ERROR_NOT_SUPPORTED; +#endif } else if (PSA_ALG_AEAD_EQUAL(ctx->alg, PSA_ALG_CCM)) { +#ifdef HAVE_AESCCM Aes aes; if (wc_AesCcmCheckTagSize((int)tag_length) != 0) { return PSA_ERROR_INVALID_SIGNATURE; @@ -684,8 +722,12 @@ static psa_status_t wolfpsa_aead_decrypt_final(wolfpsa_aead_ctx_t *ctx, if (ret != 0) { return wc_error_to_psa_status(ret); } +#else + return PSA_ERROR_NOT_SUPPORTED; +#endif } else if (PSA_ALG_AEAD_EQUAL(ctx->alg, PSA_ALG_CHACHA20_POLY1305)) { +#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) size_t out_len = 0; uint8_t *ciphertext = ctx->input; size_t ciphertext_len; @@ -713,6 +755,9 @@ static psa_status_t wolfpsa_aead_decrypt_final(wolfpsa_aead_ctx_t *ctx, } *plaintext_length = out_len; return PSA_SUCCESS; +#else + return PSA_ERROR_NOT_SUPPORTED; +#endif } else { return PSA_ERROR_NOT_SUPPORTED; diff --git a/src/psa_cipher.c b/src/psa_cipher.c index 31342e1..ad6dae4 100644 --- a/src/psa_cipher.c +++ b/src/psa_cipher.c @@ -63,7 +63,9 @@ typedef struct wolfpsa_cipher_ctx { #ifndef NO_DES3 Des3 des3; #endif +#ifdef HAVE_CHACHA ChaCha chacha; +#endif } wolfpsa_cipher_ctx_t; static wolfpsa_cipher_ctx_t *wolfpsa_cipher_get_ctx( @@ -93,13 +95,28 @@ static psa_status_t wolfpsa_cipher_check_alg(psa_algorithm_t alg) switch (alg) { case PSA_ALG_CBC_NO_PADDING: case PSA_ALG_CBC_PKCS7: + return PSA_SUCCESS; +#if defined(HAVE_AES_ECB) || defined(WOLFSSL_DES_ECB) + case PSA_ALG_ECB_NO_PADDING: + return PSA_SUCCESS; +#endif +#ifdef WOLFSSL_AES_COUNTER case PSA_ALG_CTR: + case PSA_ALG_CCM_STAR_NO_TAG: + return PSA_SUCCESS; +#endif +#ifdef WOLFSSL_AES_CFB case PSA_ALG_CFB: + return PSA_SUCCESS; +#endif +#ifdef WOLFSSL_AES_OFB case PSA_ALG_OFB: - case PSA_ALG_ECB_NO_PADDING: + return PSA_SUCCESS; +#endif +#ifdef HAVE_CHACHA case PSA_ALG_STREAM_CIPHER: - case PSA_ALG_CCM_STAR_NO_TAG: return PSA_SUCCESS; +#endif default: return PSA_ERROR_NOT_SUPPORTED; } @@ -151,6 +168,14 @@ static psa_status_t wolfpsa_cipher_check_key( return status; } +#ifndef HAVE_CHACHA + if (alg == PSA_ALG_STREAM_CIPHER) { + wolfpsa_forcezero_free_key_data(*key_data, *key_data_length); + *key_data = NULL; + *key_data_length = 0; + return PSA_ERROR_NOT_SUPPORTED; + } +#endif if (alg == PSA_ALG_STREAM_CIPHER) { if (attributes->type != PSA_KEY_TYPE_CHACHA20) { wolfpsa_forcezero_free_key_data(*key_data, *key_data_length); @@ -166,6 +191,14 @@ static psa_status_t wolfpsa_cipher_check_key( *key_data_length = 0; return PSA_ERROR_NOT_SUPPORTED; } + if (alg == PSA_ALG_ECB_NO_PADDING) { +#if defined(NO_DES3) || !defined(WOLFSSL_DES_ECB) + wolfpsa_forcezero_free_key_data(*key_data, *key_data_length); + *key_data = NULL; + *key_data_length = 0; + return PSA_ERROR_NOT_SUPPORTED; +#endif + } } else { if (attributes->type != PSA_KEY_TYPE_AES) { @@ -174,6 +207,14 @@ static psa_status_t wolfpsa_cipher_check_key( *key_data_length = 0; return PSA_ERROR_NOT_SUPPORTED; } + if (alg == PSA_ALG_ECB_NO_PADDING) { +#ifndef HAVE_AES_ECB + wolfpsa_forcezero_free_key_data(*key_data, *key_data_length); + *key_data = NULL; + *key_data_length = 0; + return PSA_ERROR_NOT_SUPPORTED; +#endif + } } key_usage = psa_get_key_usage_flags(attributes); @@ -192,6 +233,7 @@ static psa_status_t wolfpsa_cipher_check_key( return PSA_ERROR_NOT_PERMITTED; } +#ifdef HAVE_CHACHA if (attributes->type == PSA_KEY_TYPE_CHACHA20) { if (*key_data_length != CHACHA_MAX_KEY_SZ) { wolfpsa_forcezero_free_key_data(*key_data, *key_data_length); @@ -207,6 +249,7 @@ static psa_status_t wolfpsa_cipher_check_key( } return PSA_SUCCESS; } +#endif if (attributes->type == PSA_KEY_TYPE_DES) { if (*key_data_length != 16 && *key_data_length != 24) { @@ -312,11 +355,14 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, return PSA_ERROR_INVALID_ARGUMENT; } +#ifdef HAVE_CHACHA if (ctx->is_chacha) { ret = wc_Chacha_SetKey(&ctx->chacha, key_data, (word32)key_data_length); } - else if (ctx->is_des3) { + else +#endif + if (ctx->is_des3) { #ifndef NO_DES3 byte des_key[DES3_KEY_SIZE]; @@ -352,15 +398,19 @@ psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation, return wc_error_to_psa_status(ret); } +#ifdef WOLFSSL_AES_COUNTER if (alg == PSA_ALG_CTR || alg == PSA_ALG_CFB) { ret = wc_AesCtrSetKey(&ctx->aes, key_data, (word32)key_data_length, ctx->iv, AES_ENCRYPTION); } - else if (alg == PSA_ALG_CCM_STAR_NO_TAG) { + else +#endif + if (alg == PSA_ALG_CCM_STAR_NO_TAG) { ret = wc_AesSetKey(&ctx->aes, key_data, (word32)key_data_length, ctx->iv, AES_ENCRYPTION); } - else { + else + { ret = wc_AesSetKey(&ctx->aes, key_data, (word32)key_data_length, ctx->iv, AES_ENCRYPTION); } @@ -454,11 +504,14 @@ psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, return PSA_ERROR_INVALID_ARGUMENT; } +#ifdef HAVE_CHACHA if (ctx->is_chacha) { ret = wc_Chacha_SetKey(&ctx->chacha, key_data, (word32)key_data_length); } - else if (ctx->is_des3) { + else +#endif + if (ctx->is_des3) { #ifndef NO_DES3 byte des_key[DES3_KEY_SIZE]; @@ -494,11 +547,14 @@ psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation, return wc_error_to_psa_status(ret); } +#ifdef WOLFSSL_AES_COUNTER if (alg == PSA_ALG_CTR || alg == PSA_ALG_CFB) { ret = wc_AesCtrSetKey(&ctx->aes, key_data, (word32)key_data_length, ctx->iv, AES_ENCRYPTION); } - else if (alg == PSA_ALG_CCM_STAR_NO_TAG) { + else +#endif + if (alg == PSA_ALG_CCM_STAR_NO_TAG) { ret = wc_AesSetKey(&ctx->aes, key_data, (word32)key_data_length, ctx->iv, AES_ENCRYPTION); } @@ -558,6 +614,7 @@ psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, } if (ctx->alg == PSA_ALG_STREAM_CIPHER) { +#ifdef HAVE_CHACHA if (iv_length != WOLFPSA_CHACHA20_IV_BYTES) { return PSA_ERROR_INVALID_ARGUMENT; } @@ -565,6 +622,9 @@ psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation, if (ret != 0) { return wc_error_to_psa_status(ret); } +#else + return PSA_ERROR_NOT_SUPPORTED; +#endif } else if (ctx->alg == PSA_ALG_CCM_STAR_NO_TAG) { uint8_t counter[AES_BLOCK_SIZE]; @@ -1001,6 +1061,7 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, } } else if (ctx->alg == PSA_ALG_CCM_STAR_NO_TAG) { +#ifdef WOLFSSL_AES_COUNTER if (!ctx->iv_set) { return wolfpsa_cipher_fail(operation, PSA_ERROR_BAD_STATE); } @@ -1017,8 +1078,12 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, } *output_length = input_length; return PSA_SUCCESS; +#else + return wolfpsa_cipher_fail(operation, PSA_ERROR_NOT_SUPPORTED); +#endif } else if (ctx->alg == PSA_ALG_ECB_NO_PADDING) { +#if defined(HAVE_AES_ECB) || defined(WOLFSSL_DES_ECB) { size_t block_size = ctx->block_size; size_t total = ctx->partial_len + input_length; @@ -1048,7 +1113,7 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, XMEMCPY(block + ctx->partial_len, input, needed); if (ctx->is_des3) { -#ifndef NO_DES3 +#if !defined(NO_DES3) && defined(WOLFSSL_DES_ECB) if (ctx->direction == AES_ENCRYPTION) { ret = wc_Des3_EcbEncrypt(&ctx->des3, output, block, (word32)block_size); @@ -1062,6 +1127,7 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, #endif } else { +#ifdef HAVE_AES_ECB if (ctx->direction == AES_ENCRYPTION) { ret = wc_AesEcbEncrypt(&ctx->aes, output, block, (word32)block_size); @@ -1070,6 +1136,9 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, ret = wc_AesEcbDecrypt(&ctx->aes, output, block, (word32)block_size); } +#else + return wolfpsa_cipher_fail(operation, PSA_ERROR_NOT_SUPPORTED); +#endif } if (ret != 0) { return wolfpsa_cipher_fail(operation, @@ -1086,7 +1155,7 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, if (full_blocks > 0) { if (ctx->is_des3) { -#ifndef NO_DES3 +#if !defined(NO_DES3) && defined(WOLFSSL_DES_ECB) if (ctx->direction == AES_ENCRYPTION) { ret = wc_Des3_EcbEncrypt(&ctx->des3, output + output_offset, @@ -1105,6 +1174,7 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, #endif } else { +#ifdef HAVE_AES_ECB if (ctx->direction == AES_ENCRYPTION) { ret = wc_AesEcbEncrypt(&ctx->aes, output + output_offset, @@ -1117,6 +1187,10 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, input + input_offset, (word32)full_blocks); } +#else + return wolfpsa_cipher_fail(operation, + PSA_ERROR_NOT_SUPPORTED); +#endif } if (ret != 0) { return wolfpsa_cipher_fail(operation, @@ -1135,8 +1209,12 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, *output_length = output_offset; return PSA_SUCCESS; } +#else + return wolfpsa_cipher_fail(operation, PSA_ERROR_NOT_SUPPORTED); +#endif } else if (ctx->alg == PSA_ALG_CTR) { +#ifdef WOLFSSL_AES_COUNTER if (!ctx->iv_set) { return wolfpsa_cipher_fail(operation, PSA_ERROR_BAD_STATE); } @@ -1148,8 +1226,12 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, if (ret != 0) { return wolfpsa_cipher_fail(operation, wc_error_to_psa_status(ret)); } +#else + return wolfpsa_cipher_fail(operation, PSA_ERROR_NOT_SUPPORTED); +#endif } else if (ctx->alg == PSA_ALG_CFB) { +#ifdef WOLFSSL_AES_CFB if (!ctx->iv_set) { return wolfpsa_cipher_fail(operation, PSA_ERROR_BAD_STATE); } @@ -1167,8 +1249,12 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, if (ret != 0) { return wolfpsa_cipher_fail(operation, wc_error_to_psa_status(ret)); } +#else + return wolfpsa_cipher_fail(operation, PSA_ERROR_NOT_SUPPORTED); +#endif } else if (ctx->alg == PSA_ALG_OFB) { +#ifdef WOLFSSL_AES_OFB if (!ctx->iv_set) { return wolfpsa_cipher_fail(operation, PSA_ERROR_BAD_STATE); } @@ -1186,8 +1272,12 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, if (ret != 0) { return wolfpsa_cipher_fail(operation, wc_error_to_psa_status(ret)); } +#else + return wolfpsa_cipher_fail(operation, PSA_ERROR_NOT_SUPPORTED); +#endif } else if (ctx->alg == PSA_ALG_STREAM_CIPHER) { +#ifdef HAVE_CHACHA if (!ctx->iv_set) { return wolfpsa_cipher_fail(operation, PSA_ERROR_BAD_STATE); } @@ -1199,6 +1289,9 @@ psa_status_t psa_cipher_update(psa_cipher_operation_t *operation, if (ret != 0) { return wolfpsa_cipher_fail(operation, wc_error_to_psa_status(ret)); } +#else + return wolfpsa_cipher_fail(operation, PSA_ERROR_NOT_SUPPORTED); +#endif } else { return wolfpsa_cipher_fail(operation, PSA_ERROR_NOT_SUPPORTED); diff --git a/src/psa_key_derivation.c b/src/psa_key_derivation.c index 3dbbbcf..0409bdc 100644 --- a/src/psa_key_derivation.c +++ b/src/psa_key_derivation.c @@ -385,6 +385,22 @@ psa_status_t psa_key_derivation_setup(psa_key_derivation_operation_t *operation, return PSA_ERROR_NOT_SUPPORTED; } +#if !defined(HAVE_HKDF) || defined(NO_HMAC) + if (PSA_ALG_IS_ANY_HKDF(kdf_alg)) { + return PSA_ERROR_NOT_SUPPORTED; + } +#endif +#if !defined(WOLFSSL_HAVE_PRF) || defined(NO_HMAC) + if (PSA_ALG_IS_TLS12_PRF(kdf_alg) || PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg)) { + return PSA_ERROR_NOT_SUPPORTED; + } +#endif +#if !defined(HAVE_PBKDF2) || defined(NO_HMAC) + if (PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) { + return PSA_ERROR_NOT_SUPPORTED; + } +#endif + if (PSA_ALG_IS_ANY_HKDF(kdf_alg) || PSA_ALG_IS_TLS12_PRF(kdf_alg) || PSA_ALG_IS_TLS12_PSK_TO_MS(kdf_alg) || PSA_ALG_IS_PBKDF2_HMAC(kdf_alg)) { hash_type = wolfpsa_hash_type_from_alg(kdf_alg); @@ -733,6 +749,12 @@ static psa_status_t wolfpsa_kdf_hkdf(wolfpsa_kdf_ctx_t *ctx, uint8_t *output, size_t output_length) { +#if !defined(HAVE_HKDF) || defined(NO_HMAC) + (void)ctx; + (void)output; + (void)output_length; + return PSA_ERROR_NOT_SUPPORTED; +#else int hash_type = wolfpsa_hash_type_from_alg(ctx->alg); int ret; @@ -821,12 +843,19 @@ static psa_status_t wolfpsa_kdf_hkdf(wolfpsa_kdf_ctx_t *ctx, } return PSA_ERROR_NOT_SUPPORTED; +#endif } static psa_status_t wolfpsa_kdf_tls12_prf(wolfpsa_kdf_ctx_t *ctx, uint8_t *output, size_t output_length) { +#if !defined(WOLFSSL_HAVE_PRF) || defined(NO_HMAC) + (void)ctx; + (void)output; + (void)output_length; + return PSA_ERROR_NOT_SUPPORTED; +#else int hash_type = wolfpsa_hash_type_from_alg(ctx->alg); int ret; @@ -848,12 +877,19 @@ static psa_status_t wolfpsa_kdf_tls12_prf(wolfpsa_kdf_ctx_t *ctx, return wc_error_to_psa_status(ret); } return PSA_SUCCESS; +#endif } static psa_status_t wolfpsa_kdf_tls12_psk_to_ms(wolfpsa_kdf_ctx_t *ctx, uint8_t *output, size_t output_length) { +#if !defined(WOLFSSL_HAVE_PRF) || defined(NO_HMAC) + (void)ctx; + (void)output; + (void)output_length; + return PSA_ERROR_NOT_SUPPORTED; +#else int hash_type = wolfpsa_hash_type_from_alg(ctx->alg); size_t other_secret_length; const uint8_t *other_secret; @@ -913,6 +949,7 @@ static psa_status_t wolfpsa_kdf_tls12_psk_to_ms(wolfpsa_kdf_ctx_t *ctx, wc_ForceZero(premaster, premaster_len); XFREE(premaster, NULL, DYNAMIC_TYPE_TMP_BUFFER); return status; +#endif } static psa_status_t wolfpsa_kdf_pbkdf2(wolfpsa_kdf_ctx_t *ctx, @@ -924,6 +961,11 @@ static psa_status_t wolfpsa_kdf_pbkdf2(wolfpsa_kdf_ctx_t *ctx, const uint8_t *salt = wolfpsa_kdf_input_ptr(ctx->salt, ctx->salt_length); if (PSA_ALG_IS_PBKDF2_HMAC(ctx->alg)) { +#if !defined(HAVE_PBKDF2) || defined(NO_HMAC) + (void)output; + (void)output_length; + return PSA_ERROR_NOT_SUPPORTED; +#else int hash_type = wolfpsa_hash_type_from_alg(ctx->alg); int ret; @@ -937,6 +979,7 @@ static psa_status_t wolfpsa_kdf_pbkdf2(wolfpsa_kdf_ctx_t *ctx, return wc_error_to_psa_status(ret); } return PSA_SUCCESS; +#endif } if (ctx->alg == PSA_ALG_PBKDF2_AES_CMAC_PRF_128) { diff --git a/src/psa_mac.c b/src/psa_mac.c index f1f5f29..01864f7 100644 --- a/src/psa_mac.c +++ b/src/psa_mac.c @@ -32,7 +32,9 @@ #include #include #include +#ifdef WOLFSSL_CMAC #include +#endif #include #include #ifndef NO_INLINE @@ -55,7 +57,9 @@ typedef struct wolfpsa_mac_ctx { wolfpsa_mac_type_t type; union { Hmac hmac; +#ifdef WOLFSSL_CMAC Cmac cmac; +#endif } ctx; } wolfpsa_mac_ctx_t; @@ -139,6 +143,12 @@ static psa_status_t wolfpsa_mac_check_key(psa_key_id_t key, } } else if (PSA_ALG_IS_BLOCK_CIPHER_MAC(alg)) { +#ifndef WOLFSSL_CMAC + wolfpsa_forcezero_free_key_data(*key_data, *key_data_length); + *key_data = NULL; + *key_data_length = 0; + return PSA_ERROR_NOT_SUPPORTED; +#endif if (attributes->type != PSA_KEY_TYPE_AES) { wolfpsa_forcezero_free_key_data(*key_data, *key_data_length); *key_data = NULL; @@ -273,12 +283,14 @@ static psa_status_t wolfpsa_mac_setup(psa_mac_operation_t *operation, (word32)key_data_length); ctx->type = WOLFPSA_MAC_HMAC; } +#ifdef WOLFSSL_CMAC else if (PSA_ALG_IS_BLOCK_CIPHER_MAC(alg) && PSA_ALG_FULL_LENGTH_MAC(alg) == PSA_ALG_CMAC) { ret = wc_InitCmac(&ctx->ctx.cmac, key_data, (word32)key_data_length, WC_CMAC_AES, NULL); ctx->type = WOLFPSA_MAC_CMAC; } +#endif else { ret = NOT_COMPILED_IN; } @@ -357,9 +369,11 @@ psa_status_t psa_mac_update(psa_mac_operation_t *operation, if (ctx->type == WOLFPSA_MAC_HMAC) { ret = wc_HmacUpdate(&ctx->ctx.hmac, input, (word32)input_length); } +#ifdef WOLFSSL_CMAC else if (ctx->type == WOLFPSA_MAC_CMAC) { ret = wc_CmacUpdate(&ctx->ctx.cmac, input, (word32)input_length); } +#endif else { return wolfpsa_mac_fail(operation, PSA_ERROR_BAD_STATE); } @@ -402,6 +416,7 @@ static psa_status_t wolfpsa_mac_final(wolfpsa_mac_ctx_t *ctx, } full_len = (word32)ctx->full_length; } +#ifdef WOLFSSL_CMAC else if (ctx->type == WOLFPSA_MAC_CMAC) { full_len = (word32)ctx->full_length; ret = wc_CmacFinal(&ctx->ctx.cmac, full_mac, &full_len); @@ -410,6 +425,7 @@ static psa_status_t wolfpsa_mac_final(wolfpsa_mac_ctx_t *ctx, goto cleanup; } } +#endif else { status = PSA_ERROR_BAD_STATE; goto cleanup; @@ -517,9 +533,11 @@ psa_status_t psa_mac_abort(psa_mac_operation_t *operation) if (ctx->type == WOLFPSA_MAC_HMAC) { wc_HmacFree(&ctx->ctx.hmac); } +#ifdef WOLFSSL_CMAC if (ctx->type == WOLFPSA_MAC_CMAC) { wc_CmacFree(&ctx->ctx.cmac); } +#endif wc_ForceZero(ctx, sizeof(*ctx)); XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER); operation->opaque = (uintptr_t)NULL; diff --git a/src/psa_tls_prf.c b/src/psa_tls_prf.c index 57589c2..6d5fb90 100644 --- a/src/psa_tls_prf.c +++ b/src/psa_tls_prf.c @@ -25,7 +25,8 @@ #include -#if defined(WOLFSSL_PSA_ENGINE) && defined(WOLFSSL_TLS13) +#if defined(WOLFSSL_PSA_ENGINE) && defined(WOLFSSL_TLS13) && \ + defined(HAVE_HKDF) && !defined(NO_HMAC) #include #include "psa_size.h" @@ -317,4 +318,91 @@ psa_status_t psa_tls13_hkdf_expand_label( return PSA_SUCCESS; } +#elif defined(WOLFSSL_PSA_ENGINE) && defined(WOLFSSL_TLS13) + +#include +#include + +psa_status_t psa_tls_prf_check_alg_supported(psa_algorithm_t alg) +{ + (void)alg; + + return PSA_ERROR_NOT_SUPPORTED; +} + +psa_status_t psa_tls13_prf( + psa_algorithm_t alg, + const uint8_t *secret, size_t secret_length, + const uint8_t *label, size_t label_length, + const uint8_t *context, size_t context_length, + uint8_t *output, size_t output_length) +{ + (void)alg; + (void)secret; + (void)secret_length; + (void)label; + (void)label_length; + (void)context; + (void)context_length; + (void)output; + (void)output_length; + + return PSA_ERROR_NOT_SUPPORTED; +} + +psa_status_t psa_tls13_hkdf_extract( + psa_algorithm_t alg, + const uint8_t *salt, size_t salt_length, + const uint8_t *ikm, size_t ikm_length, + uint8_t *output, size_t output_size, size_t *output_length) +{ + (void)alg; + (void)salt; + (void)salt_length; + (void)ikm; + (void)ikm_length; + (void)output; + (void)output_size; + (void)output_length; + + return PSA_ERROR_NOT_SUPPORTED; +} + +psa_status_t psa_tls13_hkdf_expand( + psa_algorithm_t alg, + const uint8_t *prk, size_t prk_length, + const uint8_t *info, size_t info_length, + uint8_t *output, size_t output_length) +{ + (void)alg; + (void)prk; + (void)prk_length; + (void)info; + (void)info_length; + (void)output; + (void)output_length; + + return PSA_ERROR_NOT_SUPPORTED; +} + +psa_status_t psa_tls13_hkdf_expand_label( + psa_algorithm_t alg, + const uint8_t *secret, size_t secret_length, + const uint8_t *label, size_t label_length, + const uint8_t *context, size_t context_length, + uint8_t *output, size_t output_length) +{ + (void)alg; + (void)secret; + (void)secret_length; + (void)label; + (void)label_length; + (void)context; + (void)context_length; + (void)output; + (void)output_length; + + return PSA_ERROR_NOT_SUPPORTED; +} + #endif /* WOLFSSL_PSA_ENGINE && WOLFSSL_TLS13 */