Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/scripts/check-headers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ else
| grep -vE '^wolfssl/wolfcrypt/port/caam/(caam_driver|caam_qnx|wolfcaam_hash)\.h$' \
| grep -vE '^wolfssl/wolfcrypt/port/kcapi/' \
| grep -vE '^wolfssl/wolfcrypt/port/nxp/(dcp_port|se050_port)\.h$' \
| grep -vE '^wolfssl/wolfcrypt/port/Renesas/(renesas_fspsm_internal|renesas-rx64-hw-crypt|renesas-tsip-crypt|renesas_tsip_internal)\.h$' \
| grep -vE '^wolfssl/wolfcrypt/port/silabs/silabs_aes\.h$'
| grep -vE '^wolfssl/wolfcrypt/port/Renesas/(renesas_fspsm_internal|renesas-rx64-hw-crypt|renesas-tsip-crypt|renesas_tsip_internal)\.h$'
)
fi

Expand Down
105 changes: 105 additions & 0 deletions .github/workflows/silabs-cryptocb.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Silicon Labs EFR32 Secure Element port Tests

# START OF COMMON SECTION
on:
push:
branches: [ 'release/**' ]
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches: [ '*' ]
# Weekday-morning cron seeds the master-scoped ccache that PR runs restore
# read-only (see ccache-setup).
schedule:
- cron: '41 10 * * 1-5'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read
# END OF COMMON SECTION

jobs:
# Build gate for the EFR32 Secure Element crypto-callback port.
# --enable-silabs-cryptocb defaults to the host-test profile, which sets
# WOLFSSL_SILABS_HOST_TEST and swaps the SE Manager headers for
# silabs_shim.h. Every shim operation returns SL_STATUS_NOT_SUPPORTED, so
# this does no crypto; what it covers is that the port compiles, that the
# cryptocb dispatch and info-struct field access are right across engine
# combinations, and that every engine's decline path falls back to software
# rather than failing.
#
# That last part is why testwolfcrypt runs below: with a device registered
# whose every operation declines, a green run means the fall-back is wired
# correctly on each engine. Crypto correctness on the Secure Element is
# validated on EFR32xG25 silicon, not here (see the port README).
build:
name: build + software fall-back (--enable-silabs-cryptocb)
if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }}
runs-on: ubuntu-24.04
timeout-minutes: 20
steps:
- uses: actions/checkout@v5
name: Checkout wolfSSL

- name: Install dependencies
uses: ./.github/actions/install-apt-deps
with:
packages: autoconf automake libtool build-essential
ghcr-debs-tag: ubuntu-24.04-minimal

- name: Set up ccache
uses: ./.github/actions/ccache-setup
with:
workflow-id: silabs-cryptocb
read-only: ${{ github.event_name == 'pull_request' }}
max-size: 100M

- name: Build all configs (compile-only, out-of-tree)
run: |
cat > "$RUNNER_TEMP/silabs-configs.json" <<'EOF'
[
{"name": "full", "minutes": 3,
"comment": "Every engine the port dispatches: hash, AES (GCM/CCM/CTR/ECB), CMAC, ChaCha20-Poly1305, ECC, HKDF and PBKDF2.",
"configure": ["--enable-silabs-cryptocb", "--enable-cryptocb", "--enable-ecc",
"--enable-aesgcm", "--enable-aesccm", "--enable-aesctr", "--enable-aesecb",
"--enable-cmac", "--enable-pwdbased", "--enable-hkdf", "--enable-chacha",
"--enable-poly1305"]},
{"name": "full-smallstack", "minutes": 3,
"comment": "Same coverage with WOLFSSL_SMALL_STACK, which moves the port's working buffers to the heap.",
"configure": ["--enable-silabs-cryptocb", "--enable-cryptocb", "--enable-ecc",
"--enable-aesgcm", "--enable-aesccm", "--enable-aesctr", "--enable-aesecb",
"--enable-cmac", "--enable-pwdbased", "--enable-hkdf", "--enable-chacha",
"--enable-poly1305", "CPPFLAGS=-DWOLFSSL_SMALL_STACK"]},
{"name": "min", "minutes": 2,
"comment": "Defaults only: no CMAC, no CCM, no PBKDF2 -> exercises the compile guards that take those engines out.",
"configure": ["--enable-silabs-cryptocb", "--enable-cryptocb"]}
]
EOF
.github/scripts/parallel-make-check.py --build-only \
"$RUNNER_TEMP/silabs-configs.json"

- name: Run testwolfcrypt against a device that declines everything
run: |
./autogen.sh
./configure --enable-silabs-cryptocb --enable-cryptocb --enable-ecc \
--enable-aesgcm --enable-aesccm --enable-aesctr --enable-aesecb \
--enable-cmac --enable-pwdbased --enable-hkdf --enable-chacha \
--enable-poly1305
make -j"$(nproc)"
./wolfcrypt/test/testwolfcrypt

- name: ccache stats
if: always()
run: ccache -s || true

- name: Upload logs on failure
if: failure()
uses: actions/upload-artifact@v6
with:
retention-days: 7
name: silabs-cryptocb-logs
path: |
build-*/config.log
if-no-files-found: ignore
1 change: 1 addition & 0 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,7 @@ WOLFSSL_SHA3_AVX2
WOLFSSL_SHA3_NO_AVX2
WOLFSSL_SHA3_PPC64_BLOCKS_N
WOLFSSL_SHUTDOWNONCE
WOLFSSL_SILABS_NO_VAULT_KEYS
WOLFSSL_SILABS_TRNG
WOLFSSL_SLHDSA_FULL_HASH
WOLFSSL_SLHDSA_NO_VERIFY_ONLY
Expand Down
58 changes: 57 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -3993,6 +3993,61 @@ then
fi


# Silicon Labs EFR32 Secure Element crypto-callback port.
#
# Two profiles, because the port is built two different ways:
#
# host-test (the default for a bare --enable-silabs-cryptocb)
# Swaps the SE Manager headers for a shim (WOLFSSL_SILABS_HOST_TEST) so
# the cryptocb dispatch and wiring build with no vendor SDK present.
# Every shim operation declines, so this compiles the port and exercises
# the fall-back paths; it does no crypto and is not a target build.
#
# target
# The port itself, with no shim. The Simplicity SDK include path comes
# from the application, so pass it in CFLAGS:
# ./configure --enable-silabs-cryptocb=target \
# CFLAGS="-I<simplicity-sdk>/platform/security/sl_component/se_manager/inc ..."
# This is what a cross build for an EFR32 uses. Building it for the host
# will not link, which is the point of the host-test profile.
#
# Either way it forces crypto callbacks on (see the cryptocb block).
# Example: "./configure --enable-silabs-cryptocb"
ENABLED_SILABS_CRYPTOCB="no"
Comment thread
dgarske marked this conversation as resolved.
AC_ARG_ENABLE([silabs-cryptocb],
[AS_HELP_STRING([--enable-silabs-cryptocb@<:@=host-test|target@:>@],
[Enable Silicon Labs EFR32 Secure Element crypto-callback port. Default host-test, which builds the port against a shim and needs no vendor SDK.])],
[ ENABLED_SILABS_CRYPTOCB=$enableval ],
[ ENABLED_SILABS_CRYPTOCB=no ])

if test "x$ENABLED_SILABS_CRYPTOCB" = "xyes"
then
ENABLED_SILABS_CRYPTOCB="host-test"
fi

if test "x$ENABLED_SILABS_CRYPTOCB" != "xno"
then
# The shim models an EFR32xG25 (Series 2 Config 5) with Secure Vault High.
# The port's AES-ECB dispatch is gated on HAVE_AES_ECB and compiles out
# without it, so this option does not turn AES-ECB on. To compile-test that
# path too, add --enable-aesecb, which enables the (public,
# unauthenticated) AES-ECB API through the normal option.
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SILABS_CRYPTOCB"

case "$ENABLED_SILABS_CRYPTOCB" in
host-test)
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SILABS_HOST_TEST"
;;
target)
AC_MSG_NOTICE([silabs-cryptocb=target: the Simplicity SDK include path must be supplied in CFLAGS])
;;
*)
AC_MSG_ERROR([unknown --enable-silabs-cryptocb value '$ENABLED_SILABS_CRYPTOCB'; use host-test or target])
;;
esac
fi


# NXP SE050
# Example: "./configure --with-se050=/home/pi/simw_top"
ENABLED_SE050="no"
Expand Down Expand Up @@ -11940,7 +11995,7 @@ then
fi
fi

if test "x$ENABLED_PKCS11" = "xyes" || test "x$ENABLED_WOLFTPM" = "xyes" || test "$ENABLED_CAAM" != "no" || test "x$ENABLED_RTL8735B" != "xno" || test "x$ENABLED_VAULTIC" = "xyes"
if test "x$ENABLED_PKCS11" = "xyes" || test "x$ENABLED_WOLFTPM" = "xyes" || test "$ENABLED_CAAM" != "no" || test "x$ENABLED_RTL8735B" != "xno" || test "x$ENABLED_SILABS_CRYPTOCB" != "xno" || test "x$ENABLED_VAULTIC" = "xyes"
then
ENABLED_CRYPTOCB=yes
fi
Expand Down Expand Up @@ -14052,6 +14107,7 @@ AM_CONDITIONAL([BUILD_VAULTIC],[test "x$ENABLED_VAULTIC" = "xyes"])
AM_CONDITIONAL([BUILD_SE050],[test "x$ENABLED_SE050" = "xyes"])
AM_CONDITIONAL([BUILD_STSAFE],[test "x$ENABLED_STSAFE" != "xno"])
AM_CONDITIONAL([BUILD_RTL8735B],[test "x$ENABLED_RTL8735B" != "xno"])
AM_CONDITIONAL([BUILD_SILABS_CRYPTOCB],[test "x$ENABLED_SILABS_CRYPTOCB" != "xno"])
AM_CONDITIONAL([BUILD_TROPIC01],[test "x$ENABLED_TROPIC01" = "xyes"])
AM_CONDITIONAL([BUILD_KDF],[test "x$ENABLED_KDF" = "xyes"])
AM_CONDITIONAL([BUILD_HMAC],[test "x$ENABLED_HMAC" = "xyes"])
Expand Down
20 changes: 12 additions & 8 deletions src/keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -2485,31 +2485,35 @@ int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs,
#endif
if (side == WOLFSSL_CLIENT_END) {
if (enc) {
chachaRet = wc_Chacha_SetKey(enc->chacha, keys->client_write_key,
specs->key_size);
chachaRet = wc_Chacha_SetKey_ex(enc->chacha,
keys->client_write_key,
specs->key_size, heap, devId);
XMEMCPY(keys->aead_enc_imp_IV, keys->client_write_IV,
CHACHA20_IMP_IV_SZ);
if (chachaRet != 0) return chachaRet;
}
if (dec) {
chachaRet = wc_Chacha_SetKey(dec->chacha, keys->server_write_key,
specs->key_size);
chachaRet = wc_Chacha_SetKey_ex(dec->chacha,
keys->server_write_key,
specs->key_size, heap, devId);
XMEMCPY(keys->aead_dec_imp_IV, keys->server_write_IV,
CHACHA20_IMP_IV_SZ);
if (chachaRet != 0) return chachaRet;
}
}
else {
if (enc) {
chachaRet = wc_Chacha_SetKey(enc->chacha, keys->server_write_key,
specs->key_size);
chachaRet = wc_Chacha_SetKey_ex(enc->chacha,
keys->server_write_key,
specs->key_size, heap, devId);
XMEMCPY(keys->aead_enc_imp_IV, keys->server_write_IV,
CHACHA20_IMP_IV_SZ);
if (chachaRet != 0) return chachaRet;
}
if (dec) {
chachaRet = wc_Chacha_SetKey(dec->chacha, keys->client_write_key,
specs->key_size);
chachaRet = wc_Chacha_SetKey_ex(dec->chacha,
keys->client_write_key,
specs->key_size, heap, devId);
XMEMCPY(keys->aead_dec_imp_IV, keys->client_write_IV,
CHACHA20_IMP_IV_SZ);
if (chachaRet != 0) return chachaRet;
Expand Down
7 changes: 7 additions & 0 deletions wolfcrypt/src/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -6164,6 +6164,13 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir)
return BAD_FUNC_ARG;
}

#ifdef WOLFSSL_SILABS_SE_TYPES
/* A plaintext key supersedes any resident key bound by
* wc_SilabsSe_AesUse*Key(); without clearing the binding the SE would
* keep using the key it still holds. */
aes->ctx.keySet = 0;
#endif

/* sometimes hardware may not support all keylengths (e.g. ESP32-S3) */
#if defined(WOLFSSL_ESPIDF) && defined(NEED_AES_HW_FALLBACK)
ESP_LOGV(TAG, "wc_AesSetKey fallback check %d", keylen);
Expand Down
21 changes: 20 additions & 1 deletion wolfcrypt/src/chacha.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ static const word32 tau[4] = {0x61707865, 0x3120646e, 0x79622d36, 0x6b206574};
/**
* Key setup. 8 word iv (nonce)
*/
int wc_Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz)
int wc_Chacha_SetKey_ex(ChaCha* ctx, const byte* key, word32 keySz,
void* heap, int devId)
{
#if (!defined(USE_ARM_CHACHA_SPEEDUP) || defined(WOLFSSL_ARM_CHACHA_NEED_C)) && \
!defined(USE_RISCV_CHACHA_SPEEDUP)
Expand Down Expand Up @@ -276,9 +277,27 @@ int wc_Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz)
ctx->left = 0; /* resets state */
ctx->keySet = 1;

#ifdef WOLF_CRYPTO_CB
/* A device takes the plaintext key, not the expanded state above. There
* is no wc_Chacha_Init(), so clear the whole buffer first rather than
* leave the tail of a 16 byte key holding whatever the caller's storage
* held before. */
XMEMSET(ctx->devKey, 0, sizeof(ctx->devKey));
XMEMCPY(ctx->devKey, key, keySz);
ctx->devKeySz = keySz;
ctx->devId = devId;
#endif
(void)heap; /* nothing on this path allocates */
(void)devId;

return 0;
}

int wc_Chacha_SetKey(ChaCha* ctx, const byte* key, word32 keySz)
{
return wc_Chacha_SetKey_ex(ctx, key, keySz, NULL, INVALID_DEVID);
}

#if (!defined(USE_INTEL_CHACHA_SPEEDUP) && !defined(USE_ARM_CHACHA_SPEEDUP) && \
!defined(USE_RISCV_CHACHA_SPEEDUP)) || defined(WOLFSSL_ARM_CHACHA_NEED_C)
/**
Expand Down
51 changes: 47 additions & 4 deletions wolfcrypt/src/chacha20_poly1305.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ or Authenticated Encryption with Additional Data (AEAD) algorithm.
#include <wolfssl/wolfcrypt/chacha20_poly1305.h>
#include <wolfssl/wolfcrypt/cpuid.h>

#ifdef WOLF_CRYPTO_CB
#include <wolfssl/wolfcrypt/cryptocb.h>
#endif

#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
Expand Down Expand Up @@ -442,6 +446,23 @@ WOLFSSL_API int wc_ChaCha20Poly1305_Encrypt_ex(ChaCha* chacha, Poly1305* poly,
return BAD_FUNC_ARG;
}

#ifdef WOLF_CRYPTO_CB
/* devId comes from wc_Chacha_SetKey_ex(). This is the path the TLS
* record layer uses. Software runs if the device declines.
*
* wc_Chacha_SetKey_ex() also accepts a 16 byte key, which this AEAD is
* not defined for and which the callback carries no length for, so a
* device would key itself with 32 bytes and diverge from software. Keep
* those contexts on the software path. */
if (chacha->devId != INVALID_DEVID &&
chacha->devKeySz == CHACHA20_POLY1305_AEAD_KEYSIZE) {
ret = wc_CryptoCb_Chacha20Poly1305Encrypt(chacha->devId, chacha->devKey,
nonce, aad, aadSz, in, sz, out, tag);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
}
#endif

#ifdef WOLFSSL_CHACHA20_POLY1305_SHORT
if (sz <= CHACHA20_POLY1305_SHORT_MAX)
return chacha20_poly1305_encrypt_short(chacha, poly, out, in, sz,
Expand Down Expand Up @@ -532,6 +553,17 @@ WOLFSSL_API int wc_ChaCha20Poly1305_Decrypt_ex(ChaCha* chacha, Poly1305* poly,
return BAD_FUNC_ARG;
}

#ifdef WOLF_CRYPTO_CB
/* See the encrypt counterpart, including the 16 byte key exclusion. */
if (chacha->devId != INVALID_DEVID &&
chacha->devKeySz == CHACHA20_POLY1305_AEAD_KEYSIZE) {
ret = wc_CryptoCb_Chacha20Poly1305Decrypt(chacha->devId, chacha->devKey,
nonce, aad, aadSz, in, sz, tag, out);
if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
return ret;
}
#endif

#ifdef WOLFSSL_CHACHA20_POLY1305_SHORT
if (sz <= CHACHA20_POLY1305_SHORT_MAX)
return chacha20_poly1305_decrypt_short(chacha, poly, out, in, sz,
Expand Down Expand Up @@ -801,10 +833,10 @@ int wc_ChaCha20Poly1305_CheckTag(
return ret;
}

int wc_ChaCha20Poly1305_Init(ChaChaPoly_Aead* aead,
int wc_ChaCha20Poly1305_Init_ex(ChaChaPoly_Aead* aead,
const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE],
const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE],
int isEncrypt)
int isEncrypt, void* heap, int devId)
{
int ret;
byte authKey[CHACHA20_POLY1305_AEAD_KEYSIZE];
Expand Down Expand Up @@ -833,8 +865,10 @@ int wc_ChaCha20Poly1305_Init(ChaChaPoly_Aead* aead,
aead->isEncrypt = isEncrypt ? 1 : 0;

/* Initialize the ChaCha20 context (key and iv) */
ret = wc_Chacha_SetKey(&aead->chacha, inKey,
CHACHA20_POLY1305_AEAD_KEYSIZE);
ret = wc_Chacha_SetKey_ex(&aead->chacha, inKey,
CHACHA20_POLY1305_AEAD_KEYSIZE, heap, devId);
(void)heap;
(void)devId;
if (ret == 0) {
ret = wc_Chacha_SetIV(&aead->chacha, inIV,
CHACHA20_POLY1305_AEAD_INITIAL_COUNTER);
Expand Down Expand Up @@ -870,6 +904,15 @@ int wc_ChaCha20Poly1305_Init(ChaChaPoly_Aead* aead,
return ret;
}

int wc_ChaCha20Poly1305_Init(ChaChaPoly_Aead* aead,
const byte inKey[CHACHA20_POLY1305_AEAD_KEYSIZE],
const byte inIV[CHACHA20_POLY1305_AEAD_IV_SIZE],
int isEncrypt)
{
return wc_ChaCha20Poly1305_Init_ex(aead, inKey, inIV, isEncrypt, NULL,
INVALID_DEVID);
}

/* optional additional authentication data */
int wc_ChaCha20Poly1305_UpdateAad(ChaChaPoly_Aead* aead,
const byte* inAAD, word32 inAADLen)
Expand Down
Loading
Loading