Add SRAM PUF (Physically Unclonable Function) support to wolfCrypt. Derives device-unique cryptographic keys from the power-on state of SRAM memory using a BCH(127,64,t=10) fuzzy extractor with HKDF key derivation.
- **wolfCrypt PUF API** (`wolfcrypt/src/puf.c`, `wolfssl/wolfcrypt/puf.h`)
- `wc_PufInit`, `wc_PufReadSram`, `wc_PufEnroll`, `wc_PufReconstruct`
- `wc_PufDeriveKey` (HKDF-SHA256), `wc_PufGetIdentity` (SHA-256 device fingerprint)
- `wc_PufZeroize` (secure context cleanup)
- `wc_PufSetTestData` (synthetic SRAM for testing without hardware)
- **BCH(127,64,t=10) error-correcting codec** - corrects up to 10 bit flips per 127-bit codeword across 16 codewords
- **`WC_PUF_SHA3` build option** - select SHA3-256 instead of SHA-256 for identity hash and HKDF (default: SHA-256)
- **Precomputed GF(2^7) tables** - `const` arrays in `.rodata` (no runtime init, thread-safe, flash-resident on embedded)
- `./configure --enable-puf` (auto-enables HKDF dependency)
- CMake: `WOLFSSL_PUF=yes`
- `WOLFSSL_USER_SETTINGS`: define `WOLFSSL_PUF` and `WOLFSSL_PUF_SRAM`
- See wolfssl-examples/puf for example implementation on STM32 NUCLEO-H563ZI (Cortex-M33, STM32H563ZI)
- Supports test mode (synthetic SRAM)
- Builds to ~13KB `.elf`
- Tested on NUCLEO-H563ZI: enrollment, noisy reconstruction, key derivation all pass
- `.github/workflows/puf.yml`: host build + test workflow for PUF feature
- Doxygen API docs for all 8 public functions
- PUF group added to `doxygen_groups.h`
Follow-up to #7731 ("Changes needed for default TLS support in zephyr
kernel"). Zephyr 4.3's TLS socket integration uses three additional
wolfSSL features that were not needed by the 3.7 integration, plus an
extension to the native_sim time-source gates introduced in #7731.
native_sim timer gates (src/internal.c, wolfcrypt/src/wc_port.c):
Extend the !CONFIG_BOARD_NATIVE_POSIX gate in LowResTimer() and the
CONFIG_BOARD_NATIVE_POSIX RTC path in z_time() to also cover
CONFIG_BOARD_NATIVE_SIM. Zephyr 4.3 renamed the simulator board from
native_posix to native_sim; without this, k_cpu_idle() on native_sim
advances simulated time during DTLS retransmit loops and the RTC path
falls through to uptime-since-boot. Behavior on native_posix is
unchanged.
New Kconfig options (zephyr/Kconfig, zephyr/user_settings.h):
CONFIG_WOLFSSL_SESSION_EXPORT -> HAVE_EXT_CACHE
Required by consumers that serialize TLS session state across
connections via wolfSSL_i2d_SSL_SESSION / wolfSSL_d2i_SSL_SESSION.
CONFIG_WOLFSSL_KEEP_PEER_CERT -> KEEP_PEER_CERT
Retain the peer certificate after handshake so the application
layer can inspect it via wolfSSL_get_peer_certificate.
CONFIG_WOLFSSL_ALWAYS_VERIFY_CB -> WOLFSSL_ALWAYS_VERIFY_CB
Invoke an application-set verify callback on successful chain
validation in addition to validation failures.
All three are default-off; customers opt in the same way they do for
the existing CONFIG_WOLFSSL_DTLS / ALPN / PSK feature options.
.wolfssl_known_macro_extras: register HAVE_EXT_CACHE.
Refactors the output format of generated assembly files across all
platforms
(x86_64, ARM AArch64, ARMv8-32, Thumb2, PowerPC) for consistency and
correctness.
Changes
Data constant consolidation
- Pack multiple values per directive line (e.g., 4× .long or 8× .short
per
line) instead of one value per line, reducing file sizes significantly
- Normalize hex literal formatting: 64-bit values use full 8-byte
zero-padded
form (e.g., 0x0000000003ffffff instead of 0x3ffffff)
x86_64 assembly
- Use decimal immediate values for shift counts (e.g., $1 instead of
$0x01)
- .asm (MASM): use hex notation consistently for data constants;
update ALIGN
values to match data width (e.g., ALIGN 32 for 256-bit aligned data)
ARM .S files
- Move .type directive before .section for data objects (correct
ordering per
ELF convention)
ARM/Thumb2 inline C (_c.c) files
- Replace asm( with __asm__( for register variable constraints (better
portability)
- Add XALIGNED(8) attribute to constant lookup tables used in inline
asm
- Remove redundant #include <stdint.h> and
<wolfssl/wolfcrypt/libwolfssl_sources.h> headers
Files affected: 71 assembly and companion C files across
wolfcrypt/src/,
wolfcrypt/src/port/arm/, covering AES, ChaCha, Poly1305,
SHA-256/512/3,
Curve25519, ML-KEM, ML-DSA, and SP math routines.
1. sp_cond_swap_ct_ex (line ~5524) — XOR typo: b->sign ^= b->sign always
zeroed the sign. Fixed to b->sign ^= t->sign to correctly swap signs.
2. sp_mod_d (line ~7271) — Negative modulo correction was applied even
when the remainder was 0. Added (*r != 0) guard to avoid producing d
instead of 0.
3. sp_lshb (line ~8444) — Left-shift size check was off. Refactored to
correctly distinguish between pure-digit shifts and bit-within-digit
shifts when checking if the result fits, using separate overflow checks
for each case.
4. _sp_mulmod_tmp (line ~12160) — Zero inputs caused an allocation of
size 0, which is problematic. Added an early path: if either operand is
zero, set result to zero and skip the allocation/multiply entirely.
5. sp_mod_2d — copy path (line ~14762) — XMEMCPY copied digits *
SP_WORD_SIZEOF bytes but a may have fewer than digits used digits. Fixed
to copy min(a->used, digits) digits to avoid reading uninitialized
memory.
6. sp_mod_2d — negation loop (line ~14782) — Negation loop iterated
over r->used, which could exceed digits. Fixed to loop over min(r->used,
digits).
7. _sp_sqrmod (line ~17314) — Same zero-input issue as _sp_mulmod_tmp.
Added early zero path to skip the allocation/squaring when input is
zero.
8. sp_lcm (line ~19838) — Typo in sign check: b->sign >= MP_NEG
(comparing against a value that is 1, so >= 1 would also match MP_ZPOS)
changed to b->sign == MP_NEG.