EFR32xG25 Secure Element example for wolfSSL PR 11267: wolfCrypt test, benchmark and TLS 1.3

pull/627/head
David Garske 2026-09-09 10:56:10 -07:00
parent d421168ad8
commit 269816454e
8 changed files with 1246 additions and 0 deletions

3
embedded/efr32xg25/.gitignore vendored 100644
View File

@ -0,0 +1,3 @@
# slc generate output
build/
.wolfcrypt_test.local.slcp

View File

@ -0,0 +1,194 @@
# wolfCrypt test and benchmark on EFR32xG25
Runs the wolfCrypt algorithm self-test and benchmark on an EFR32xG25 with crypto routed to the Secure Element through the wolfSSL crypto callback port. Builds headlessly with `slc-cli` and GNU Arm - no Simplicity Studio GUI needed.
For the port itself, including which algorithms are offloaded and the Secure Vault key management API, see [wolfcrypt/src/port/silabs/README.md](https://github.com/wolfSSL/wolfssl/blob/master/wolfcrypt/src/port/silabs/README.md) in the wolfSSL repository.
## wolfSSL source
This project compiles the wolfSSL sources directly - there is no prebuilt library. `build.sh` expects a wolfSSL checkout beside `wolfssl-examples`:
```
GitHub/
wolfssl/
wolfssl-examples/embedded/efr32xg25/
```
Point `WOLFSSL_ROOT` somewhere else if yours does not sit there:
```sh
WOLFSSL_ROOT=/path/to/wolfssl ./build.sh
```
The Secure Element crypto callback port arrived in wolfSSL [PR 11267](https://github.com/wolfSSL/wolfssl/pull/11267); until that is in a release, use a checkout that contains it.
## Hardware
An xG25 radio board (BRD4270B, BRD4271A or BRD4272A) on a BRD4002A/BRD4001A mainboard. All three radio boards carry `EFR32FG25B222F1920IM56`: Series 2 Config 5, Secure Vault **High**, 1920 KB flash. Set `BOARD` if yours is not the default BRD4270B:
```sh
BOARD=brd4271a ./build.sh
```
The application prints the SE firmware version and the detected Secure Vault level at startup, so a captured log records which silicon produced the numbers under it.
## Toolchain
Install headlessly with Silicon Labs Tool (SLT). As of SLC-CLI v6 the CLI is no longer a direct download; SLT fetches it along with the SDK, GNU Arm and Commander from a recipe:
```sh
mkdir -p ~/silabs && cd ~/silabs
wget -O slt-cli.zip \
"https://www.silabs.com/documents/public/software/slt-cli-1.2.1-linux-x64.zip"
unzip -o slt-cli.zip && chmod +x slt
cat > pkg.slt <<'RECIPE'
[dependency]
simplicity-sdk = "~"
slc-cli = "~"
gcc-arm-none-eabi = "~"
commander = "~"
RECIPE
./slt install
```
Check the current SLT version on the [command line development page](https://www.silabs.com/software-and-tools/simplicity-studio/configurator-command-line-development). `build.sh` and `flash.sh` read `~/.silabs/sdks.json` and `~/.silabs/tools.json` to locate everything, so no paths are hardcoded. Override `SDK`, `SLC`, `GCC_DIR`, `JAVA_DIR` or `COMMANDER` in the environment if your install lives elsewhere; the scripts say so by name if a registry is missing or a tool was never installed.
Developed against Simplicity SDK 2026.6.1 (platform 6.0.0), slc-cli 6.0.23, Commander 1.24.3, GNU Arm 14.2.rel1.
## Build and flash
```sh
./build.sh # slc generate + make, output in ./build
./flash.sh # commander device info, flash, reset
```
Then read the VCOM output at 115200 8N1. On a bench running the `uart-monitor` daemon, tail its log rather than opening the port directly.
## What to expect
`wolfcrypt_test` must report a full PASS. Because `WOLFSSL_SILABS_CRYPTOCB` points `WC_USE_DEVID` at the SE device, every algorithm the port claims runs on the Secure Element, so a PASS is direct evidence the callback is correct against the known-answer vectors.
The benchmark then runs each algorithm twice, labelling rows `HW` and `SW`, which gives a hardware-versus-software comparison in one run.
## Measured results
Captured on an **EFR32FG25B222F1920IM56** (Secure Vault High, SE firmware 2.2.0) with this project, wolfSSL 5.9.2. `wolfcrypt_test` reports a **full PASS** in both builds below; the software/Secure Element pairs are the `HW` and `SW` rows the benchmark prints in one run.
Both builds define the `--enable-harden` options (`ECC_TIMING_RESISTANT`, `WC_RSA_BLINDING`), so these are hardened numbers. They cost nothing measurable here: this configuration routes P-256 through `WOLFSSL_SP_MATH_ALL`/`WOLFSSL_HAVE_SP_ECC`, which is already constant time, and every ECC and RSA row moved by less than 0.3% when the options were added.
The two software columns are two builds of this project. **Software (C)** is what you get out of the box. **Software (Thumb2 asm)** additionally enables the `WOLFSSL_ARMASM` block near the top of `user_settings.h` -- flip its `#if 0` to `#if 1` to reproduce it. Both builds already use `WOLFSSL_SP_ARM_CORTEX_M_ASM` for ECC, so the ECC rows do not move.
| Algorithm | Software (C) | Software (Thumb2 asm) | Secure Element | SE vs C | SE vs asm |
|---|---|---|---|---|---|
| RNG SHA-256 DRBG | 281 KiB/s | 408 KiB/s | **89 KiB/s** | **0.3x** | **0.2x** |
| AES-128-CBC-enc | 856 KiB/s | 986 KiB/s | **2.63 MiB/s** | **3.2x** | **2.7x** |
| AES-128-CBC-dec | 854 KiB/s | 985 KiB/s | **2.65 MiB/s** | **3.2x** | **2.8x** |
| AES-192-CBC-enc | 722 KiB/s | 826 KiB/s | **2.60 MiB/s** | **3.7x** | **3.2x** |
| AES-192-CBC-dec | 722 KiB/s | 820 KiB/s | **2.59 MiB/s** | **3.7x** | **3.2x** |
| AES-256-CBC-enc | 627 KiB/s | 710 KiB/s | **2.58 MiB/s** | **4.2x** | **3.7x** |
| AES-256-CBC-dec | 626 KiB/s | 712 KiB/s | **2.59 MiB/s** | **4.2x** | **3.7x** |
| AES-128-GCM-enc | 293 KiB/s | 629 KiB/s | **2.37 MiB/s** | **8.3x** | **3.9x** |
| AES-128-GCM-dec | 291 KiB/s | 626 KiB/s | **2.26 MiB/s** | **8.0x** | **3.7x** |
| AES-192-GCM-enc | 275 KiB/s | 558 KiB/s | **2.38 MiB/s** | **8.9x** | **4.4x** |
| AES-192-GCM-dec | 274 KiB/s | 556 KiB/s | **2.24 MiB/s** | **8.4x** | **4.1x** |
| AES-256-GCM-enc | 260 KiB/s | 502 KiB/s | **2.38 MiB/s** | **9.4x** | **4.8x** |
| AES-256-GCM-dec | 258 KiB/s | 501 KiB/s | **2.23 MiB/s** | **8.8x** | **4.6x** |
| AES-128-GCM-enc-no_AAD | 296 KiB/s | 632 KiB/s | **2.44 MiB/s** | **8.4x** | **3.9x** |
| AES-128-GCM-dec-no_AAD | 294 KiB/s | 630 KiB/s | **2.28 MiB/s** | **7.9x** | **3.7x** |
| AES-192-GCM-enc-no_AAD | 278 KiB/s | 560 KiB/s | **2.41 MiB/s** | **8.9x** | **4.4x** |
| AES-192-GCM-dec-no_AAD | 276 KiB/s | 559 KiB/s | **2.30 MiB/s** | **8.5x** | **4.2x** |
| AES-256-GCM-enc-no_AAD | 262 KiB/s | 505 KiB/s | **2.35 MiB/s** | **9.2x** | **4.8x** |
| AES-256-GCM-dec-no_AAD | 261 KiB/s | 503 KiB/s | **2.23 MiB/s** | **8.8x** | **4.5x** |
| AES-128-ECB-enc | 876 KiB/s | 992 KiB/s | **2.84 MiB/s** | **3.3x** | **2.9x** |
| AES-128-ECB-dec | 882 KiB/s | 988 KiB/s | **2.77 MiB/s** | **3.2x** | **2.9x** |
| AES-192-ECB-enc | 737 KiB/s | 824 KiB/s | **2.74 MiB/s** | **3.8x** | **3.4x** |
| AES-192-ECB-dec | 741 KiB/s | 833 KiB/s | **2.79 MiB/s** | **3.9x** | **3.4x** |
| AES-256-ECB-enc | 638 KiB/s | 711 KiB/s | **2.70 MiB/s** | **4.3x** | **3.9x** |
| AES-256-ECB-dec | 640 KiB/s | 710 KiB/s | **2.71 MiB/s** | **4.3x** | **3.9x** |
| AES-128-CTR | 852 KiB/s | 977 KiB/s | **2.63 MiB/s** | **3.2x** | n/a |
| AES-192-CTR | 720 KiB/s | 820 KiB/s | **2.62 MiB/s** | **3.7x** | n/a |
| AES-256-CTR | 625 KiB/s | 705 KiB/s | **2.63 MiB/s** | **4.3x** | n/a |
| AES-CCM-enc | 426 KiB/s | 460 KiB/s | **2.20 MiB/s** | **5.3x** | **4.9x** |
| AES-CCM-dec | 425 KiB/s | 459 KiB/s | **2.14 MiB/s** | **5.1x** | **4.8x** |
| AES-CCM-enc-no_AAD | 426 KiB/s | 460 KiB/s | **2.20 MiB/s** | **5.3x** | **4.9x** |
| AES-CCM-dec-no_AAD | 425 KiB/s | 459 KiB/s | **2.11 MiB/s** | **5.1x** | **4.7x** |
| SHA-1 | 3.91 MiB/s | 3.92 MiB/s | **3.63 MiB/s** | **0.9x** | **0.9x** |
| SHA-224 | 1.23 MiB/s | 1.99 MiB/s | **3.67 MiB/s** | **3.0x** | **1.8x** |
| SHA-256 | 1.23 MiB/s | 1.99 MiB/s | **3.67 MiB/s** | **3.0x** | **1.8x** |
| AES-128-CMAC | 793 KiB/s | 856 KiB/s | **2.45 MiB/s** | **3.2x** | **2.9x** |
| AES-256-CMAC | 593 KiB/s | 640 KiB/s | **2.40 MiB/s** | **4.1x** | **3.8x** |
| HMAC-SHA-1 | 3.87 MiB/s | 3.87 MiB/s | **3.01 MiB/s** | **0.8x** | **0.8x** |
| HMAC-SHA-224 | 1.22 MiB/s | 1.97 MiB/s | **3.04 MiB/s** | **2.5x** | **1.5x** |
| HMAC-SHA-256 | 1.22 MiB/s | 1.97 MiB/s | **3.04 MiB/s** | **2.5x** | **1.5x** |
| ECC 256 key gen | 125.4 ops/s | 125.3 ops/s | **180.6 ops/s** | **1.4x** | **1.4x** |
| ECDHE 256 agree | 65.4 ops/s | 65.4 ops/s | **179.8 ops/s** | **2.7x** | **2.7x** |
| ECDSA 256 sign | 67.8 ops/s | 67.8 ops/s | **173.4 ops/s** | **2.6x** | **2.6x** |
| ECDSA 256 verify | 41.9 ops/s | 41.9 ops/s | **163.8 ops/s** | **3.9x** | **3.9x** |
Where the Secure Element is **slower** the numbers are reported as measured. SHA-1 and HMAC-SHA-1 are cheap enough on this Cortex-M33 that the SE round trip costs more than it saves. The **RNG** row compares asking the SE for every byte against a SHA-256 DRBG seeded once from that same SE TRNG - seeding a DRBG is the normal way to use a hardware entropy source, so the `HW` row is raw TRNG throughput rather than the cost of getting random data. **AES-GCM** gains the most, up to **9.4x**.
The RNG row is the only one that moves appreciably between runs: the DRBG reseeds from the SE TRNG at a fixed generate count and one reseed is expensive at 89 KiB/s, so the software figure swings by roughly 15% depending on whether a reseed lands inside the one-second measurement window.
**AES-CTR** reads `n/a` in the last column because the port deliberately declines CTR when `WOLFSSL_ARMASM` is defined -- the Thumb2 keystream remainder and the SE's do not line up -- so that build has no Secure Element CTR number.
**RSA** and **DH** are omitted because Series 2 has no RSA hardware, so both columns run in software. **SHA-384/512** likewise, and they are always left to software (see the port README). **ChaCha20-Poly1305** has no paired row because the benchmark drives it through the one-shot `wc_ChaCha20Poly1305_Encrypt()`, which carries no `devId` and so always runs in software. The pre-keyed API the TLS record layer uses does carry one, and that path is offloaded.
To check the software fallback path, offload a subset by adding one or more engine macros to `user_settings.h` (for example only `WOLFSSL_SILABS_CRYPTOCB_HASH`) and re-run: everything else must still pass, in software.
## TLS 1.3 over the Secure Element
Flip the `WOLFSSL_XG25_TLS13` block at the top of `user_settings.h` to `#if 1`
and rebuild. The application then runs `tls13_test.c` between the wolfCrypt
test and the benchmark: a client and a server, both on the device, wired
together through two in-memory byte queues, with the Secure Element `devId` set
on both. It runs the handshake once per TLS 1.3 cipher suite and then pushes
application data through the record layer.
This covers ground the known answer vectors cannot. Handshake and record
buffers are cursors into a larger buffer, so the engines see arbitrary byte
offsets rather than aligned stack arrays, and one cipher object is reused
across many chained records, so any state the port fails to carry between calls
shows up as a decrypt failure instead of passing on a single shot.
The three suites cover different engines. `TLS13-AES128-GCM-SHA256` drives the
key schedule and transcript hash through the Secure Element, while
`TLS13-AES256-GCM-SHA384` runs those in software, so between them they cover
the offloaded and the fallback hash path. `TLS13-CHACHA20-POLY1305-SHA256`
covers the ChaCha20-Poly1305 record cipher, which the AES suites never reach.
Measured result on the kit:
```
--- TLS 1.3 over the Secure Element ---
[TLS13-AES128-GCM-SHA256]
handshake OK: TLSv1.3 TLS_AES_128_GCM_SHA256
record layer OK: 9 payloads, 1 to 255 bytes
[TLS13-AES256-GCM-SHA384]
handshake OK: TLSv1.3 TLS_AES_256_GCM_SHA384
record layer OK: 9 payloads, 1 to 255 bytes
[TLS13-CHACHA20-POLY1305-SHA256]
handshake OK: TLSv1.3 TLS_CHACHA20_POLY1305_SHA256
record layer OK: 9 payloads, 1 to 255 bytes
tls13_test returned 0 (PASS)
```
The ChaCha suite is the one that needs the `devId` carried on the cipher
object: the record layer keys a `ChaCha` once per epoch and then calls the
pre-keyed API, so without a `devId` on that object there is nothing to route
on. Instrumenting the port's dispatch during this run counts 28
ChaCha20-Poly1305 requests reaching the Secure Element and 28 handled there,
with no software fallback.
The kit has no battery-backed real time clock, so `app.c` supplies a
`_gettimeofday()` seeded from the build date, overriding newlib's weak stub.
Without it `time()` returns -1, every certificate reads as not yet valid and
the CA fails to load with `ASN_BEFORE_DATE_E` (-150). That clock is good enough
for a self-contained demo and nothing more: a device that cannot tell the time
cannot tell a valid certificate from an expired one, so a real design needs an
RTC, a time server, or a provisioned time that an attacker cannot move.
## Notes
* The SE firmware must be recent enough for the SE Manager commands used. xG25 is Series 2 Config 5, so it takes the `s2c5` firmware package - not the `s2c1` package referenced by older wolfSSL SiLabs documentation. Check with `commander device info` and upgrade with `commander flash` if needed.
* `user_settings.h` is shared by the library and the application, as wolfSSL requires. Changing feature macros in one and not the other corrupts struct layouts at runtime.
* RSA has no hardware support on Series 2 and stays in software; the benchmark rows for it are software timings.

View File

@ -0,0 +1,216 @@
/* app.c
*
* Copyright (C) 2006-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 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* wolfCrypt test and benchmark entry point for the EFR32xG25. */
#include <stdio.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/version.h>
#ifdef WOLFSSL_XG25_TLS13
#include <wolfssl/ssl.h>
#endif
#include <sl_se_manager.h>
#include <sl_se_manager_util.h>
#include <sl_sleeptimer.h>
#ifdef WOLFSSL_XG25_TLS13
#include <sys/time.h>
#endif
#ifdef WOLFSSL_XG25_TLS13
/* The kit has no RTC and newlib's _gettimeofday is a weak stub that fails, so
* time() returns -1 and every certificate looks not-yet-valid
* (ASN_BEFORE_DATE_E). Seed a clock from the build date and let the sleep
* timer advance it, so date validation can stay on.
*
* Adequate for a self-contained demo and nothing more: a device that cannot
* tell the time cannot tell a valid certificate from an expired one. A real
* design needs an RTC or a provisioned time, not attacker-controlled. */
/* Days from 1970-01-01 to y-m-d, proleptic Gregorian, for y >= 1970. */
static long xg25_days_from_civil(long y, long m, long d)
{
long era, yoe, doy, doe;
y -= (m <= 2);
era = ((y >= 0) ? y : (y - 399)) / 400;
yoe = y - era * 400;
doy = (153 * (m + ((m > 2) ? -3 : 9)) + 2) / 5 + d - 1;
doe = yoe * 365 + yoe / 4 - yoe / 100 + doy;
return era * 146097 + doe - 719468;
}
/* Seconds since the epoch for __DATE__ ("Mmm dd yyyy"), midnight UTC. Derived
* from the build so it cannot drift out of the test certificates' validity
* window the way a hardcoded constant would. */
static long xg25_build_epoch(void)
{
static const char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
const char* bd = __DATE__;
long mon = 0;
long day, year;
int i;
for (i = 0; i < 12; i++) {
if (bd[0] == months[i * 3] &&
bd[1] == months[i * 3 + 1] &&
bd[2] == months[i * 3 + 2]) {
mon = i + 1;
break;
}
}
if (mon == 0) {
mon = 1;
}
day = (bd[4] == ' ') ? (bd[5] - '0')
: ((bd[4] - '0') * 10 + (bd[5] - '0'));
year = (bd[7] - '0') * 1000 + (bd[8] - '0') * 100 +
(bd[9] - '0') * 10 + (bd[10] - '0');
return xg25_days_from_civil(year, mon, day) * 86400L;
}
/* Strong override of newlib's weak stub. */
int _gettimeofday(struct timeval* tv, void* tzvp)
{
(void)tzvp;
if (tv == NULL) {
return -1;
}
tv->tv_sec = (time_t)(xg25_build_epoch() +
(long)(sl_sleeptimer_get_tick_count64() /
sl_sleeptimer_get_timer_frequency()));
tv->tv_usec = 0;
return 0;
}
#endif /* WOLFSSL_XG25_TLS13 */
extern int wolfcrypt_test(void* args);
extern int benchmark_test(void* args);
#ifdef WOLFSSL_XG25_TLS13
extern int xg25_tls13_test(void);
#endif
/* The benchmark needs a coarse wall clock. Bench iterations are sized in
* BENCH_EMBEDDED mode, so a low resolution tick is adequate. */
double current_time(int reset)
{
(void)reset;
return (double)sl_sleeptimer_get_tick_count64()
/ (double)sl_sleeptimer_get_timer_frequency();
}
/* Report the Secure Element firmware version and the part's security level, so
* a captured log says which silicon produced the numbers below it. */
static void print_se_info(void)
{
sl_se_command_context_t cmd = SL_SE_COMMAND_CONTEXT_INIT;
uint32_t version = 0;
if (sl_se_get_se_version(&cmd, &version) == SL_STATUS_OK) {
printf("SE firmware : %lu.%lu.%lu\n",
(unsigned long)((version >> 16) & 0xFF),
(unsigned long)((version >> 8) & 0xFF),
(unsigned long)(version & 0xFF));
}
else {
printf("SE firmware : unavailable\n");
}
#if defined(_SILICON_LABS_SECURITY_FEATURE) && \
(_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
printf("Secure Vault : High\n");
#else
printf("Secure Vault : Mid (SHA-384/512, P-384/521, ChaCha20-Poly1305,\n"
" the SE KDFs and wrapped keys run in software)\n");
#endif
}
void app_init(void)
{
int ret;
printf("\n\nwolfSSL %s - EFR32xG25 Secure Element crypto callback\n",
LIBWOLFSSL_VERSION_STRING);
/* Name the software backend: it is what the benchmark's SW column
* measures, and what the SE is being compared against. */
#ifdef WOLFSSL_ARMASM
printf("Software path: Thumb2 assembly (WOLFSSL_ARMASM)\n");
#else
printf("Software path: C\n");
#endif
print_se_info();
#ifdef DEBUG_WOLFSSL
wolfSSL_Debugging_ON();
#endif
/* In TLS mode init and cleanup must pair at the library layer: a
* WOLFSSL_CTX takes its own wolfCrypt reference via wolfSSL_Init(), so a
* lone wolfCrypt_Cleanup() would leak the TLS globals and one SE
* registration. */
#ifdef WOLFSSL_XG25_TLS13
ret = wolfSSL_Init();
if (ret != WOLFSSL_SUCCESS) {
printf("wolfSSL_Init failed: %d\n", ret);
return;
}
ret = 0;
#else
ret = wolfCrypt_Init();
#endif
if (ret != 0) {
printf("wolfCrypt_Init failed: %d\n", ret);
return;
}
printf("\n--- wolfCrypt test ---\n");
ret = wolfcrypt_test(NULL);
printf("wolfcrypt_test returned %d (%s)\n", ret,
(ret == 0) ? "PASS" : "FAIL");
#ifdef WOLFSSL_XG25_TLS13
printf("\n--- TLS 1.3 over the Secure Element ---\n");
ret = xg25_tls13_test();
printf("tls13_test returned %d (%s)\n", ret, (ret == 0) ? "PASS" : "FAIL");
#endif
printf("\n--- wolfCrypt benchmark ---\n");
printf("Rows marked HW run on the Secure Element, SW in software.\n");
ret = benchmark_test(NULL);
printf("benchmark_test returned %d\n", ret);
#ifdef WOLFSSL_XG25_TLS13
wolfSSL_Cleanup();
#else
wolfCrypt_Cleanup();
#endif
printf("\n--- done ---\n");
}
void app_process_action(void)
{
}

View File

@ -0,0 +1,120 @@
#!/usr/bin/env bash
# Generate and build the EFR32xG25 wolfCrypt test/benchmark project headlessly.
# Requires the Silicon Labs toolchain installed via SLT (see README.md).
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BOARD="${BOARD:-brd4270b}"
BUILD_DIR="${BUILD_DIR:-$HERE/build}"
# wolfSSL sources are pulled in by relative path from wolfcrypt_test.slcp, which
# assumes a wolfssl checkout sitting beside wolfssl-examples. Point WOLFSSL_ROOT
# somewhere else and the project file is rewritten with absolute paths into the
# build directory, leaving the checked-in one untouched.
WOLFSSL_ROOT="${WOLFSSL_ROOT:-$HERE/../../../wolfssl}"
if [ ! -f "$WOLFSSL_ROOT/wolfcrypt/src/aes.c" ]; then
echo "No wolfSSL checkout at '$WOLFSSL_ROOT'." >&2
echo "Clone wolfSSL beside wolfssl-examples, or set WOLFSSL_ROOT." >&2
exit 1
fi
WOLFSSL_ROOT="$(cd "$WOLFSSL_ROOT" && pwd -P)"
# Resolve the SLT-managed toolchain from its own registries rather than
# hardcoding conan hash directories, which change on reinstall.
SILABS_HOME="${SILABS_HOME:-$HOME/.silabs}"
SLT_HINT="Install the toolchain with 'slt install' (see README.md), or set SDK, SLC, GCC_DIR and JAVA_DIR explicitly."
# A missing registry, a truncated one, or a tool that was never installed all
# have the same fix, so say what it is instead of letting python traceback.
json_path() { # json_path <file> <key>
local out
if [ ! -r "$1" ]; then
echo "Cannot read SLT registry '$1'." >&2
echo "$SLT_HINT" >&2
return 1
fi
out="$(python3 -c "import json,sys
try:
d = json.load(open(sys.argv[1]))
except ValueError as e:
sys.exit('%s: not valid JSON: %s' % (sys.argv[1], e))
try:
print(d[sys.argv[2]][0]['path'] if isinstance(d, dict)
else d[0]['extensions'][0]['path'])
except (KeyError, IndexError, TypeError):
sys.exit('%s: no entry for %s' % (sys.argv[1], sys.argv[2]))" "$1" "$2")" || {
echo "$SLT_HINT" >&2
return 1
}
printf '%s\n' "$out"
}
SDK="${SDK:-$(json_path "$SILABS_HOME/sdks.json" simplicity-sdk)}"
SLC="${SLC:-$(json_path "$SILABS_HOME/tools.json" slc-cli)/slc}"
GCC_DIR="${GCC_DIR:-$(json_path "$SILABS_HOME/tools.json" gcc-arm-none-eabi)/bin}"
JAVA_DIR="${JAVA_DIR:-$(json_path "$SILABS_HOME/tools.json" java21)/bin}"
export PATH="$JAVA_DIR:$GCC_DIR:$PATH"
ARM_GCC_DIR="$(dirname "$GCC_DIR")"
export ARM_GCC_DIR
echo "SDK : $SDK"
echo "slc : $SLC"
echo "gcc : $(arm-none-eabi-gcc -dumpversion)"
echo "board : $BOARD"
# BUILD_DIR is deleted below, so refuse anything that is not clearly ours.
# It must resolve beneath this example directory: that rules out "/", $HOME,
# the repository root and any unrelated project someone points the variable at.
BUILD_PARENT="$(cd "$(dirname "$BUILD_DIR")" 2>/dev/null && pwd -P || true)"
if [ -z "$BUILD_PARENT" ]; then
echo "BUILD_DIR parent does not exist: $BUILD_DIR" >&2
exit 1
fi
BUILD_ABS="$BUILD_PARENT/$(basename "$BUILD_DIR")"
case "$BUILD_ABS" in
"$HERE"/?*) ;;
*)
echo "Refusing to delete '$BUILD_ABS'" >&2
echo "BUILD_DIR must be inside $HERE" >&2
exit 1
;;
esac
rm -rf "$BUILD_ABS"
mkdir -p "$BUILD_ABS"
BUILD_DIR="$BUILD_ABS"
# Point the project file at WOLFSSL_ROOT. slc resolves every path: entry
# relative to the .slcp itself, so a non-default root means rewriting that one
# prefix to a path relative to this directory - and the copy has to stay here,
# because app.c and user_settings.h are relative to it too.
SLCP="$HERE/wolfcrypt_test.slcp"
WOLFSSL_REL="$(realpath --relative-to="$HERE" "$WOLFSSL_ROOT")"
if [ "$WOLFSSL_REL" != "../../../wolfssl" ]; then
SLCP="$HERE/.wolfcrypt_test.local.slcp"
sed "s|\.\./\.\./\.\./wolfssl|$WOLFSSL_REL|g" \
"$HERE/wolfcrypt_test.slcp" > "$SLCP"
echo "wolfSSL: $WOLFSSL_ROOT"
fi
"$SLC" signature trust --sdk "$SDK" >/dev/null 2>&1 || true
"$SLC" generate \
--sdk "$SDK" \
--project-file "$SLCP" \
--output-type makefile \
--with "$BOARD" \
--destination "$BUILD_DIR" \
--new-project --force
# slc only emits include directories that live inside the project, so add the
# wolfSSL root here. Appending to the generated fragment keeps the SDK's own
# INCLUDES intact, which passing INCLUDES= on the make command line would not.
printf '\nINCLUDES += -I%s\n' "$WOLFSSL_ROOT" >> "$BUILD_DIR/wolfcrypt_test.project.mak"
make -C "$BUILD_DIR" -f wolfcrypt_test.Makefile -j"$(nproc)"
echo
echo "Artifacts:"
find "$BUILD_DIR" -name "*.hex" -o -name "*.s37" -o -name "*.bin" | sed 's/^/ /'

View File

@ -0,0 +1,57 @@
#!/usr/bin/env bash
# Flash the built image to an attached EFR32xG25 kit and report the device.
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUILD_DIR="${BUILD_DIR:-$HERE/build}"
SILABS_HOME="${SILABS_HOME:-$HOME/.silabs}"
# Resolve Commander from the SLT registry. The path goes in as an argument
# rather than being pasted into the program text, so a directory holding a
# quote is read as a path and nothing else.
TOOLS_JSON="$SILABS_HOME/tools.json"
if [ -z "${COMMANDER:-}" ]; then
if [ ! -r "$TOOLS_JSON" ]; then
echo "Cannot read SLT registry '$TOOLS_JSON'." >&2
echo "Install the toolchain with 'slt install' (see README.md), or set COMMANDER explicitly." >&2
exit 1
fi
COMMANDER_DIR="$(python3 -c "import json,sys
try:
d = json.load(open(sys.argv[1]))
except ValueError as e:
sys.exit('%s: not valid JSON: %s' % (sys.argv[1], e))
try:
print(d['commander'][0]['path'])
except (KeyError, IndexError, TypeError):
sys.exit('%s: no entry for commander' % (sys.argv[1],))" "$TOOLS_JSON")" || {
echo "Install the toolchain with 'slt install' (see README.md), or set COMMANDER explicitly." >&2
exit 1
}
COMMANDER="$COMMANDER_DIR/commander"
fi
# find would end the script under set -e if the directory is not there, before
# the message below could explain why.
if [ -z "${IMAGE:-}" ]; then
if [ ! -d "$BUILD_DIR" ]; then
echo "No build directory at $BUILD_DIR - run build.sh first." >&2
exit 1
fi
IMAGE="$(find "$BUILD_DIR" -name '*.hex' | head -1)"
fi
if [ -z "$IMAGE" ]; then
echo "No .hex found under $BUILD_DIR - run build.sh first." >&2
exit 1
fi
echo "== device =="
"$COMMANDER" device info
echo
echo "== flashing $IMAGE =="
"$COMMANDER" flash "$IMAGE"
echo
echo "== reset =="
"$COMMANDER" device reset

View File

@ -0,0 +1,305 @@
/* tls13_test.c
*
* Copyright (C) 2006-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 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* TLS 1.3 handshake and record layer over an in-memory transport, run on the
* device with every crypto operation routed to the Secure Element.
*
* The wolfCrypt test proves the callbacks against known answer vectors one call
* at a time; this drives them the way a connection does - ECDHE key share,
* ECDSA certificate and CertificateVerify, the HKDF key schedule and a running
* transcript hash, then application data through the record layer.
*
* That catches what the vector tests cannot. Handshake and record buffers are
* cursors into a larger buffer, so they land on arbitrary offsets rather than
* aligned stack arrays - if an engine needs alignment or a DMA-reachable
* buffer, it shows here. One cipher object is also reused across thousands of
* chained records, so state the port fails to carry between calls fails rather
* than passing by luck on a single shot.
*
* Client and server both run in one thread, wired through two byte queues.
* Modeled on examples/tls13/tls13_memio.c, with the file-based certificates
* replaced by the compiled-in test buffers and the SE devId on both ends.
*/
#include <wolfssl/wolfcrypt/settings.h>
#ifdef WOLFSSL_XG25_TLS13
#include <stdio.h>
#include <wolfssl/ssl.h>
#include <wolfssl/certs_test.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/port/silabs/silabs_settings.h>
/* Holds one handshake flight. The server's is the larger: certificate,
* CertificateVerify and Finished together stay under 2 KB with a P-256
* chain. */
#define XG25_TLS_BUF_SZ 4096
/* Handshake needs a few round trips; the cap only stops a stalled loop. */
#define XG25_TLS_MAX_ITERS 32
typedef struct membuf {
unsigned char data[XG25_TLS_BUF_SZ];
int len;
} membuf;
static int mem_recv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
membuf* mb = (membuf*)ctx;
int n;
(void)ssl;
if (mb->len == 0) {
return WOLFSSL_CBIO_ERR_WANT_READ;
}
n = (sz < mb->len) ? sz : mb->len;
XMEMCPY(buf, mb->data, (size_t)n);
XMEMMOVE(mb->data, mb->data + n, (size_t)(mb->len - n));
mb->len -= n;
return n;
}
static int mem_send(WOLFSSL* ssl, char* buf, int sz, void* ctx)
{
membuf* mb = (membuf*)ctx;
(void)ssl;
/* A write larger than the queue itself never fits, however much the peer
* drains, so fail it outright. Retrying to the iteration cap would report
* it as a stalled handshake instead. */
if (sz < 0 || sz > XG25_TLS_BUF_SZ) {
return WOLFSSL_CBIO_ERR_GENERAL;
}
if (mb->len > XG25_TLS_BUF_SZ - sz) {
return WOLFSSL_CBIO_ERR_WANT_WRITE;
}
XMEMCPY(mb->data + mb->len, buf, (size_t)sz);
mb->len += sz;
return sz;
}
/* Application data round trip at deliberately awkward lengths and offsets.
* Every record is sealed and opened by the SE and read back byte for byte, so
* a record layer that corrupts data fails here even after a good handshake. */
static int xg25_tls13_echo(WOLFSSL* c, WOLFSSL* s, int payloadSz, int offset)
{
static unsigned char out[512];
static unsigned char in[512];
int i;
int ret;
if (offset + payloadSz > (int)sizeof(out)) {
return BAD_FUNC_ARG;
}
for (i = 0; i < payloadSz; i++) {
out[offset + i] = (unsigned char)(i * 7 + payloadSz);
}
ret = wolfSSL_write(c, out + offset, payloadSz);
if (ret != payloadSz) {
printf(" write failed: %d (err %d)\n", ret, wolfSSL_get_error(c, ret));
return -1;
}
XMEMSET(in, 0, sizeof(in));
ret = wolfSSL_read(s, in + offset, payloadSz);
if (ret != payloadSz) {
printf(" read failed: %d (err %d)\n", ret, wolfSSL_get_error(s, ret));
return -1;
}
if (XMEMCMP(out + offset, in + offset, (size_t)payloadSz) != 0) {
printf(" payload mismatch at %d bytes, offset %d\n",
payloadSz, offset);
return -1;
}
return 0;
}
static int xg25_tls13_one(const char* suite)
{
/* Static rather than automatic: two 4 KB queues plus the peer objects
* would otherwise sit on a small-stack build's stack. */
static membuf c2s; /* client writes, server reads */
static membuf s2c; /* server writes, client reads */
/* Odd lengths and offsets on purpose: unaligned starts and partial final
* blocks are what an engine with an alignment or block assumption trips
* over. */
static const int sizes[] = { 1, 15, 16, 17, 31, 63, 127, 128, 255 };
static const int offsets[] = { 0, 1, 2, 3, 1, 2, 3, 1, 2 };
WOLFSSL_CTX* cctx = NULL;
WOLFSSL_CTX* sctx = NULL;
WOLFSSL* c = NULL;
WOLFSSL* s = NULL;
int cdone = 0, sdone = 0;
int cret = WOLFSSL_FATAL_ERROR;
int sret = WOLFSSL_FATAL_ERROR;
int ret = -1;
int i;
XMEMSET(&c2s, 0, sizeof(c2s));
XMEMSET(&s2c, 0, sizeof(s2c));
cctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
sctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method());
if (cctx == NULL || sctx == NULL) {
printf(" CTX_new failed\n");
goto done;
}
/* A single-suite list means a completed handshake proves that suite was
* the one used. */
if (wolfSSL_CTX_set_cipher_list(cctx, suite) != WOLFSSL_SUCCESS ||
wolfSSL_CTX_set_cipher_list(sctx, suite) != WOLFSSL_SUCCESS) {
printf(" %s: not built in, skipped\n", suite);
ret = 0;
goto done;
}
/* The whole point: every private key operation, key schedule step,
* transcript hash and record seal below goes to the Secure Element. */
if (wolfSSL_CTX_SetDevId(cctx, WOLFSSL_SILABS_DEVID) != WOLFSSL_SUCCESS ||
wolfSSL_CTX_SetDevId(sctx, WOLFSSL_SILABS_DEVID) != WOLFSSL_SUCCESS) {
printf(" CTX_SetDevId failed\n");
goto done;
}
/* P-256 server certificate and its issuing CA, from the compiled-in test
* buffers. Test credentials only - never ship these. */
if (wolfSSL_CTX_use_certificate_buffer(sctx, serv_ecc_der_256,
(long)sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1)
!= WOLFSSL_SUCCESS) {
printf(" server cert load failed\n");
goto done;
}
if (wolfSSL_CTX_use_PrivateKey_buffer(sctx, ecc_key_der_256,
(long)sizeof_ecc_key_der_256, WOLFSSL_FILETYPE_ASN1)
!= WOLFSSL_SUCCESS) {
printf(" server key load failed\n");
goto done;
}
ret = wolfSSL_CTX_load_verify_buffer(cctx, ca_ecc_cert_der_256,
(long)sizeof_ca_ecc_cert_der_256, WOLFSSL_FILETYPE_ASN1);
if (ret != WOLFSSL_SUCCESS) {
printf(" CA load failed: %d\n", ret);
ret = -1;
goto done;
}
ret = -1;
/* Peer verification stays on: the client must actually validate the
* server's chain, which drives ECDSA verify through the SE. */
wolfSSL_CTX_set_verify(cctx, WOLFSSL_VERIFY_PEER, NULL);
wolfSSL_CTX_SetIORecv(cctx, mem_recv);
wolfSSL_CTX_SetIOSend(cctx, mem_send);
wolfSSL_CTX_SetIORecv(sctx, mem_recv);
wolfSSL_CTX_SetIOSend(sctx, mem_send);
c = wolfSSL_new(cctx);
s = wolfSSL_new(sctx);
if (c == NULL || s == NULL) {
printf(" SSL_new failed\n");
goto done;
}
wolfSSL_SetIOReadCtx(c, &s2c);
wolfSSL_SetIOWriteCtx(c, &c2s);
wolfSSL_SetIOReadCtx(s, &c2s);
wolfSSL_SetIOWriteCtx(s, &s2c);
for (i = 0; i < XG25_TLS_MAX_ITERS && !(cdone && sdone); i++) {
if (!cdone) {
cret = wolfSSL_connect(c);
if (cret == WOLFSSL_SUCCESS) {
cdone = 1;
}
}
if (!sdone) {
sret = wolfSSL_accept(s);
if (sret == WOLFSSL_SUCCESS) {
sdone = 1;
}
}
}
if (!cdone || !sdone) {
printf(" handshake FAILED (client err %d, server err %d)\n",
wolfSSL_get_error(c, cret), wolfSSL_get_error(s, sret));
goto done;
}
if (XSTRCMP(wolfSSL_get_version(c), "TLSv1.3") != 0) {
printf(" negotiated %s, expected TLSv1.3\n", wolfSSL_get_version(c));
goto done;
}
printf(" handshake OK: %s %s\n",
wolfSSL_get_version(c), wolfSSL_get_cipher(c));
for (i = 0; i < (int)(sizeof(sizes) / sizeof(sizes[0])); i++) {
if (xg25_tls13_echo(c, s, sizes[i], offsets[i]) != 0) {
goto done;
}
}
printf(" record layer OK: %d payloads, 1 to %d bytes\n",
(int)(sizeof(sizes) / sizeof(sizes[0])),
sizes[(sizeof(sizes) / sizeof(sizes[0])) - 1]);
ret = 0;
done:
wolfSSL_free(c);
wolfSSL_free(s);
wolfSSL_CTX_free(cctx);
wolfSSL_CTX_free(sctx);
return ret;
}
int xg25_tls13_test(void)
{
/* Three suites, exercising different engines. SHA-256 drives the key
* schedule and transcript hash through the SE, SHA-384 runs them in
* software, and the ChaCha suite covers a record cipher the AES suites
* never reach. */
static const char* suites[] = {
"TLS13-AES128-GCM-SHA256",
"TLS13-AES256-GCM-SHA384",
"TLS13-CHACHA20-POLY1305-SHA256"
};
int i;
int ret;
for (i = 0; i < (int)(sizeof(suites) / sizeof(suites[0])); i++) {
printf(" [%s]\n", suites[i]);
ret = xg25_tls13_one(suites[i]);
if (ret != 0) {
return ret;
}
}
return 0;
}
#endif /* WOLFSSL_XG25_TLS13 */

View File

@ -0,0 +1,162 @@
/* user_settings.h
*
* Copyright (C) 2006-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 3 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
/* wolfCrypt configuration for the EFR32xG25 Secure Element crypto callback
* port. Used by both the library and the application, as required. */
#ifndef WOLFSSL_XG25_USER_SETTINGS_H
#define WOLFSSL_XG25_USER_SETTINGS_H
#ifdef __cplusplus
extern "C" {
#endif
/* ---- Silicon Labs Secure Element -------------------------------------- */
/* Routes operations through the crypto callback framework by devId. This one
* define also turns on WOLF_CRYPTO_CB, registers the device from
* wolfCrypt_Init() and points WC_USE_DEVID at it, so the stock wolfCrypt test
* and benchmark exercise the hardware. */
#define WOLFSSL_SILABS_CRYPTOCB
/* Optional: TLS 1.3 handshake and record layer test. Adds a full handshake and
* application data exchange, both peers on the device, everything routed to
* the Secure Element - buffers at arbitrary offsets and one cipher object
* reused across many records, which is where alignment or carried-state
* problems show up. See tls13_test.c.
*
* Turning this on links the TLS sources, which are already in the project and
* compile to nothing while it is off.
*/
#if 0
#define WOLFSSL_XG25_TLS13
#endif
/* ---- Platform ---------------------------------------------------------- */
#ifdef WOLFSSL_XG25_TLS13
#define WOLFSSL_TLS13
#define WOLFSSL_NO_TLS12
#define HAVE_TLS_EXTENSIONS
#define HAVE_SUPPORTED_CURVES
#define WOLFSSL_USER_IO
#define NO_DH
/* RSA stays compiled in for the wolfCrypt test vectors, and TLS 1.3
* requires PSS for any RSA signature. */
#define WC_RSA_PSS
#else
/* This project exercises wolfCrypt only; no TLS is linked. */
#define WOLFCRYPT_ONLY
#endif
#define NO_OLD_TLS
#define WOLFSSL_GENERAL_ALIGNMENT 4
/* newlib-nano has no strcasecmp/strncasecmp; use wolfCrypt's own. */
#define USE_WOLF_STRCASECMP
#define USE_WOLF_STRNCASECMP
#define SINGLE_THREADED
#define NO_FILESYSTEM
#define NO_WRITEV
#define WOLFSSL_NO_SOCK
#define NO_MAIN_DRIVER
#define BENCH_EMBEDDED
#define WOLFSSL_SMALL_STACK
#define WOLFSSL_USER_CURRTIME
#define USE_CERT_BUFFERS_256
/* Optional: Thumb2 assembly for the symmetric and hash software paths. The SE
* handles these algorithms, so this only changes what the software fallback
* costs - and what the benchmark's SW column reports. The thumb2-*-asm_c.c
* sources are already in the project and compile to nothing while it is off.
*
* WOLFSSL_ARM_ARCH=7 selects the ARMv7-M/Thumb2 encodings the Cortex-M33 runs;
* WOLFSSL_ARMASM_NO_HW_CRYPTO is required because the M33 has no ARMv8
* cryptography extensions and no NEON.
*/
#if 0
#define WOLFSSL_ARMASM
#define WOLFSSL_ARMASM_THUMB2
#define WOLFSSL_ARMASM_INLINE
#define WOLFSSL_ARMASM_NO_HW_CRYPTO
#define WOLFSSL_ARMASM_NO_NEON
#define WOLFSSL_ARM_ARCH 7
#endif
/* ---- Hardening ---------------------------------------------------------
* What ./configure --enable-harden turns on, and its default for good reason:
* timing-attack resistance on the paths handling private keys, at some
* software cost. The SE is unaffected, but anything it declines falls back to
* these software implementations.
*
* TFM_TIMING_RESISTANT applies only to the fastmath backend, which this
* configuration does not use (see WOLFSSL_SP_MATH_ALL below), but is set so
* the setting survives a change of math backend.
*/
#define ECC_TIMING_RESISTANT
#define WC_RSA_BLINDING
#define TFM_TIMING_RESISTANT
/* Cortex-M33 single precision assembly for the software fallback paths. */
#define WOLFSSL_SP_MATH_ALL
#define WOLFSSL_HAVE_SP_RSA
#define WOLFSSL_HAVE_SP_ECC
#define WOLFSSL_SP_ARM_CORTEX_M_ASM
#define WOLFSSL_SP_SMALL
/* ---- Algorithms offloaded to the SE ------------------------------------ */
#define HAVE_AES_ECB
#define WOLFSSL_AES_DIRECT
#define WOLFSSL_AES_COUNTER
#define HAVE_AESGCM
#define HAVE_AESCCM
#define WOLFSSL_AES_192
#define WOLFSSL_AES_256
#define WOLFSSL_CMAC
#define WOLFSSL_SHA224
#define WOLFSSL_SHA384
#define WOLFSSL_SHA512
#define HAVE_HKDF
#define HAVE_PBKDF2
#define HAVE_CHACHA
#define HAVE_POLY1305
#define HAVE_ECC
#define ECC_SHAMIR
#define HAVE_ECC384
#define HAVE_ECC521
#define ALT_ECC_SIZE
/* ---- Trimmed away to fit and to keep the run short --------------------- */
#define NO_DSA
#define NO_DES3
#define NO_RC4
#define NO_MD4
#define NO_MD5
#define NO_PSK
#define NO_PWDBASED_TEST_LONG
#define WOLFSSL_NO_SHAKE128
#define WOLFSSL_NO_SHAKE256
/* The Series 2 High Security Engine has no RSA hardware. RSA stays in
* software; leave it on for the test vectors but keep the key size modest. */
#define RSA_MAX_SIZE 2048
#ifdef __cplusplus
}
#endif
#endif /* WOLFSSL_XG25_USER_SETTINGS_H */

View File

@ -0,0 +1,189 @@
project_name: wolfcrypt_test
package: platform
quality: experimental
label: wolfSSL - wolfCrypt test and benchmark (EFR32xG25)
description: >
Runs the wolfCrypt algorithm self-test and benchmark on an EFR32xG25, with
crypto routed to the Secure Element through the wolfSSL crypto callback port
(WOLFSSL_SILABS_CRYPTOCB). Output goes to the kit VCOM.
category: Example|Platform
filter:
- name: "Device Type"
value: ["SoC"]
- name: "MCU"
value: ["32-bit MCU"]
- name: "Project Difficulty"
value: ["Advanced"]
source:
- path: app.c
- path: ../../../wolfssl/wolfcrypt/src/aes.c
- path: ../../../wolfssl/wolfcrypt/src/arc4.c
- path: ../../../wolfssl/wolfcrypt/src/ascon.c
- path: ../../../wolfssl/wolfcrypt/src/asn.c
- path: ../../../wolfssl/wolfcrypt/src/async.c
- path: ../../../wolfssl/wolfcrypt/src/blake2b.c
- path: ../../../wolfssl/wolfcrypt/src/blake2s.c
- path: ../../../wolfssl/wolfcrypt/src/camellia.c
- path: ../../../wolfssl/wolfcrypt/src/chacha.c
- path: ../../../wolfssl/wolfcrypt/src/chacha20_poly1305.c
- path: ../../../wolfssl/wolfcrypt/src/cmac.c
- path: ../../../wolfssl/wolfcrypt/src/coding.c
- path: ../../../wolfssl/wolfcrypt/src/compress.c
- path: ../../../wolfssl/wolfcrypt/src/cpuid.c
- path: ../../../wolfssl/wolfcrypt/src/cryptocb.c
- path: ../../../wolfssl/wolfcrypt/src/curve25519.c
- path: ../../../wolfssl/wolfcrypt/src/curve448.c
- path: ../../../wolfssl/wolfcrypt/src/des3.c
- path: ../../../wolfssl/wolfcrypt/src/dh.c
- path: ../../../wolfssl/wolfcrypt/src/dsa.c
- path: ../../../wolfssl/wolfcrypt/src/ecc.c
- path: ../../../wolfssl/wolfcrypt/src/eccsi.c
- path: ../../../wolfssl/wolfcrypt/src/ed25519.c
- path: ../../../wolfssl/wolfcrypt/src/ed448.c
- path: ../../../wolfssl/wolfcrypt/src/error.c
- path: ../../../wolfssl/wolfcrypt/src/falcon.c
- path: ../../../wolfssl/wolfcrypt/src/fe_448.c
- path: ../../../wolfssl/wolfcrypt/src/fe_low_mem.c
- path: ../../../wolfssl/wolfcrypt/src/fe_operations.c
- path: ../../../wolfssl/wolfcrypt/src/fips.c
- path: ../../../wolfssl/wolfcrypt/src/fips_test.c
- path: ../../../wolfssl/wolfcrypt/src/ge_448.c
- path: ../../../wolfssl/wolfcrypt/src/ge_low_mem.c
- path: ../../../wolfssl/wolfcrypt/src/ge_operations.c
- path: ../../../wolfssl/wolfcrypt/src/hash.c
- path: ../../../wolfssl/wolfcrypt/src/hmac.c
- path: ../../../wolfssl/wolfcrypt/src/hpke.c
- path: ../../../wolfssl/wolfcrypt/src/integer.c
- path: ../../../wolfssl/wolfcrypt/src/kdf.c
- path: ../../../wolfssl/wolfcrypt/src/logging.c
- path: ../../../wolfssl/wolfcrypt/src/md2.c
- path: ../../../wolfssl/wolfcrypt/src/md4.c
- path: ../../../wolfssl/wolfcrypt/src/md5.c
- path: ../../../wolfssl/wolfcrypt/src/memory.c
- path: ../../../wolfssl/wolfcrypt/src/pkcs12.c
- path: ../../../wolfssl/wolfcrypt/src/pkcs7.c
- path: ../../../wolfssl/wolfcrypt/src/poly1305.c
- path: ../../../wolfssl/wolfcrypt/src/puf.c
- path: ../../../wolfssl/wolfcrypt/src/pwdbased.c
- path: ../../../wolfssl/wolfcrypt/src/random.c
- path: ../../../wolfssl/wolfcrypt/src/rc2.c
- path: ../../../wolfssl/wolfcrypt/src/ripemd.c
- path: ../../../wolfssl/wolfcrypt/src/rng_bank.c
- path: ../../../wolfssl/wolfcrypt/src/rsa.c
- path: ../../../wolfssl/wolfcrypt/src/sakke.c
- path: ../../../wolfssl/wolfcrypt/src/selftest.c
- path: ../../../wolfssl/wolfcrypt/src/sha.c
- path: ../../../wolfssl/wolfcrypt/src/sha256.c
- path: ../../../wolfssl/wolfcrypt/src/sha3.c
- path: ../../../wolfssl/wolfcrypt/src/sha512.c
- path: ../../../wolfssl/wolfcrypt/src/signature.c
- path: ../../../wolfssl/wolfcrypt/src/siphash.c
- path: ../../../wolfssl/wolfcrypt/src/sm2.c
- path: ../../../wolfssl/wolfcrypt/src/sm3.c
- path: ../../../wolfssl/wolfcrypt/src/sm4.c
- path: ../../../wolfssl/wolfcrypt/src/sp_arm32.c
- path: ../../../wolfssl/wolfcrypt/src/sp_arm64.c
- path: ../../../wolfssl/wolfcrypt/src/sp_armthumb.c
- path: ../../../wolfssl/wolfcrypt/src/sp_c32.c
- path: ../../../wolfssl/wolfcrypt/src/sp_c64.c
- path: ../../../wolfssl/wolfcrypt/src/sp_cortexm.c
- path: ../../../wolfssl/wolfcrypt/src/sp_int.c
- path: ../../../wolfssl/wolfcrypt/src/sp_riscv64.c
- path: ../../../wolfssl/wolfcrypt/src/sp_sm2_arm32.c
- path: ../../../wolfssl/wolfcrypt/src/sp_sm2_arm64.c
- path: ../../../wolfssl/wolfcrypt/src/sp_sm2_armthumb.c
- path: ../../../wolfssl/wolfcrypt/src/sp_sm2_c32.c
- path: ../../../wolfssl/wolfcrypt/src/sp_sm2_c64.c
- path: ../../../wolfssl/wolfcrypt/src/sp_sm2_cortexm.c
- path: ../../../wolfssl/wolfcrypt/src/sp_sm2_riscv64.c
- path: ../../../wolfssl/wolfcrypt/src/sp_sm2_x86_64.c
- path: ../../../wolfssl/wolfcrypt/src/sp_x86_64.c
- path: ../../../wolfssl/wolfcrypt/src/srp.c
- path: ../../../wolfssl/wolfcrypt/src/tfm.c
- path: ../../../wolfssl/wolfcrypt/src/tsp.c
- path: ../../../wolfssl/wolfcrypt/src/wc_encrypt.c
- path: ../../../wolfssl/wolfcrypt/src/wc_frodokem.c
- path: ../../../wolfssl/wolfcrypt/src/wc_frodokem_mat.c
- path: ../../../wolfssl/wolfcrypt/src/wc_lms.c
- path: ../../../wolfssl/wolfcrypt/src/wc_lms_impl.c
- path: ../../../wolfssl/wolfcrypt/src/wc_mldsa.c
- path: ../../../wolfssl/wolfcrypt/src/wc_mlkem.c
- path: ../../../wolfssl/wolfcrypt/src/wc_mlkem_poly.c
- path: ../../../wolfssl/wolfcrypt/src/wc_pkcs11.c
- path: ../../../wolfssl/wolfcrypt/src/wc_port.c
- path: ../../../wolfssl/wolfcrypt/src/wc_she.c
- path: ../../../wolfssl/wolfcrypt/src/wc_slhdsa.c
- path: ../../../wolfssl/wolfcrypt/src/wc_xmss.c
- path: ../../../wolfssl/wolfcrypt/src/wc_xmss_impl.c
- path: ../../../wolfssl/wolfcrypt/src/wolfcrypt_first.c
- path: ../../../wolfssl/wolfcrypt/src/wolfcrypt_last.c
- path: ../../../wolfssl/wolfcrypt/src/wolfentropy.c
- path: ../../../wolfssl/wolfcrypt/src/wolfevent.c
- path: ../../../wolfssl/wolfcrypt/src/wolfmath.c
- path: ../../../wolfssl/src/internal.c
- path: ../../../wolfssl/src/keys.c
- path: ../../../wolfssl/src/ssl.c
- path: ../../../wolfssl/src/tls.c
- path: ../../../wolfssl/src/tls13.c
- path: ../../../wolfssl/src/wolfio.c
- path: tls13_test.c
- path: ../../../wolfssl/wolfcrypt/src/port/arm/thumb2-aes-asm_c.c
- path: ../../../wolfssl/wolfcrypt/src/port/arm/thumb2-sha256-asm_c.c
- path: ../../../wolfssl/wolfcrypt/src/port/arm/thumb2-sha512-asm_c.c
- path: ../../../wolfssl/wolfcrypt/src/port/arm/thumb2-chacha-asm_c.c
- path: ../../../wolfssl/wolfcrypt/src/port/arm/thumb2-poly1305-asm_c.c
- path: ../../../wolfssl/wolfcrypt/src/port/silabs/silabs_aes.c
- path: ../../../wolfssl/wolfcrypt/src/port/silabs/silabs_cb_cipher.c
- path: ../../../wolfssl/wolfcrypt/src/port/silabs/silabs_cb_cmac.c
- path: ../../../wolfssl/wolfcrypt/src/port/silabs/silabs_cb_hash.c
- path: ../../../wolfssl/wolfcrypt/src/port/silabs/silabs_cb_kdf.c
- path: ../../../wolfssl/wolfcrypt/src/port/silabs/silabs_cb_pk.c
- path: ../../../wolfssl/wolfcrypt/src/port/silabs/silabs_cb_rng.c
- path: ../../../wolfssl/wolfcrypt/src/port/silabs/silabs_cryptocb.c
- path: ../../../wolfssl/wolfcrypt/src/port/silabs/silabs_ecc.c
- path: ../../../wolfssl/wolfcrypt/src/port/silabs/silabs_hash.c
- path: ../../../wolfssl/wolfcrypt/src/port/silabs/silabs_key.c
- path: ../../../wolfssl/wolfcrypt/src/port/silabs/silabs_random.c
- path: ../../../wolfssl/wolfcrypt/test/test.c
- path: ../../../wolfssl/wolfcrypt/benchmark/benchmark.c
include:
- path: .
file_list:
- path: user_settings.h
- path: ../../../wolfssl
file_list:
- path: wolfssl/wolfcrypt/settings.h
readme:
- path: README.md
component:
- id: se_manager
- id: sl_main
- id: device_init
- id: clock_manager
- id: printf
- id: iostream_retarget_stdio
- id: iostream_recommended_stream
- id: sleeptimer
- id: sl_string
- id: status_string
requires:
- name: device_has_semailbox
configuration:
- name: SL_STATUS_STRING_ENABLE_BLUETOOTH
value: 0
- name: SL_STATUS_STRING_ENABLE_WIFI
value: 0
- name: SL_BOARD_ENABLE_VCOM
value: 1
# wolfcrypt_test exercises deep call chains (ECC, RSA, ASN.1). The part has
# 512 KB of RAM and the app uses about 2 KB of static data, so spend some of it
# on stack rather than risk an overflow mid-test.
- name: SL_STACK_SIZE
value: 32768
- name: SL_IOSTREAM_USART_VCOM_FLOW_CONTROL_TYPE
value: usartHwFlowControlNone
define:
- name: WOLFSSL_USER_SETTINGS
toolchain_settings:
- option: optimize
value: speed