1
0
mirror of https://github.com/wolfSSL/wolfssl.git synced 2026-10-24 04:09:07 +03:00
Files
wolfssl/wolfcrypt/test/test.h
Daniel Pouzzner 8a65208daa RNG SP-800-90* compliance mechanism completion (the balance of the
WC_RNG_RBGC_STRATUM_IMMUTABLE campaign):

* RNG state-invalidation delivery by entropy epoch

* Fork safety for the WC_RNG lock word

* RBGC lineage persistence with a global fallback source

* A uniform "transient vs. verdict" error taxonomy

* Lifecycle hardening that makes WC_RNG safe to reinstantiate under lease-free
  observers.

Protocol-level changes (random.[ch]):

* Entropy epoch (WC_RNG_HAVE_ENTROPY_EPOCH, on by default with atomics in
  multithreaded builds; WC_RNG_WANT_/WC_RNG_NO_ENTROPY_EPOCH override): a
  global event counter, wc_RNG_global_invalidate_entropy(), replaces the
  per-instance walk as the primary delivery mechanism for state-invalidation
  events (VM fork/resume, hibernation).  Each WC_RNG carries a stamp; every
  seeding operation captures the epoch (and PID) before acquiring material
  and stamps at completion, so an event that lands mid-operation leaves a
  stale stamp.  rng_entropy_event_propagate() converts {stale stamp,
  unlatched} to {latched, swept} lazily, at the instance's next aperture:
  "detection is also delivery," and every aperture consulted after a nonzero
  wc_RNG_entropy_needs_recovery() is post-purge.  wc_RNG_lock_put() reports
  an unpropagated increment as NEEDS_RECOVERY_E, so a holder whose last
  operation straddled the event learns of it at release.  The latch is
  cleared by a recovery only when the recovering caller's capture is still
  current.

* wc_RNG_entropy_needs_recovery() is the single authoritative verdict on a
  standing recovery obligation (latch, stale epoch, PID change, exhausted
  reseed budget), and the generate path, the stir path, the pool reader and
  the banked-seed consumer all key on it.  rng_pid_change_check() is retired
  into it: a fork() is an epoch event.  The reseed counter is thereby
  returned to its SP 800-90A meaning (budget only); invalidation never
  spends runway and is never enforced by counter saturation in lock builds.

* Fork safety for the lock word: WC_RNG_LOCK_ORPHANED (error-crypt.h:
  OBJECT_ORPHANED_E, -1036; HWPUF_* codes shift down by one).  A _HELD word
  stamped with another process's PID was held across a fork() by a holder
  absent in this process; the first post-fork contender marks it _ORPHANED
  (RngLockOrphanCheck(), from every lock getter), applies the invalidation
  once as CAS winner, and reports OBJECT_ORPHANED_E.  The verdict licenses
  nothing to the contender: the owner adopts the lease by
  wc_FreeRng_PreLocked() then wc_InitRng_ex2() with the new
  WC_RNG_INIT_FLAG_PRESERVE_LOCK (which clears _ORPHANED with the latch); a
  live holder's release or completed recovery also clears it.

* RBGC lineage persistence (WC_RNG_HAVE_LOCK && WC_RNG_HAVE_RBGC): a chain
  child retains RBGC_parent and pins it by RBGC_refcount (both live for as
  long as the lock word, preserved across _PRESERVE_LOCK reinits).
  wc_FreeRng() on a pinned parent wipes sensitive state and returns the new
  STILL_REFERENCED_E (error-crypt.h) -- the shell must outlive its
  children; wc_rng_free() leaks rather than freeing referenced memory.
  WC_RNG_FLAG_NO_RBGC_PARENT opts an instance out of being retained
  (wc_rng_new*() and *_New() constructors set it, since the void
  wc_rng_free() cannot report).  HAVE_FIPS forces lock-required parents and
  WC_RNG_RBGC_STRATUM_IMMUTABLE, and random.h refuses HAVE_FIPS with RBGC
  but without the lock facility.

* Global fallback RBGC source (WC_RNG_HAVE_GLOBAL_FALLBACK_RNG):
  wc_RNG_global_fallback_init[_user_seed]() / _get() / _free(), a static
  lock-required WC_RNG, freed by wolfCrypt_Cleanup().  PollAndReSeed() and
  wc_RNG_DRBG_NextSeedGenerate() climb a ladder for a chain-backed
  instance: the retained parent, then the global fallback (under FIPS only
  when it qualifies as "a sibling of the parent, an ancestor, or the initial
  randomness source" per SP 800-90C), then -- unless the instance is
  WC_RNG_FLAG_NO_PRIMARY_SEED -- the primary source.  A ladder rung whose
  release reports NEEDS_RECOVERY_E voids the reseed (DRBG_NEED_RESEED) or
  purges the bank just filled.  SP 800-90C qualification of a supplied root
  against the retained parent is enforced in wc_RNG_DRBG_ReseedRBGC() and
  wc_RNG_DRBG_NextSeedGenerate_RBGC() under FIPS.

* Runtime policy flags: wc_RNG_SetFlags() / wc_RNG_ClearFlags() /
  wc_RNG_GetFlags(), limited to WC_RNG_FLAGS_SETTABLE / _CLEARABLE
  (FAIL_FAST, ONLY_PRIMARY_SEED, NO_PRIMARY_SEED) and to exclusive
  ownership.  WC_RNG_FLAG_FAIL_FAST (WC_RNG_INIT_FLAG_FAIL_FAST at birth):
  a generate that would otherwise reseed in-line reports instead --
  NOT_READY_E for the budget, NEEDS_RECOVERY_E for a latched or stale
  instance (RngFailFastVerdict()) -- leaving the DRBG uncondemned;
  wc_RNG_Pool_Collect2() sets it transiently on its source so the ring claim
  is held for one bounded generate.  WC_RNG_FLAG_NO_PRIMARY_SEED /
  WC_RNG_INIT_FLAG_NO_PRIMARY_SEED forbids the primary source after
  instantiation (chain members that must stay chain-fed; MISSING_RNG_E on an
  instance with no chain parent); WC_RNG_FLAG_ONLY_PRIMARY_SEED is the
  converse, set transiently by the new wc_RNG_DRBG_Reseed_Now_Primary() for
  prediction-resistant constructions on chain-backed instances.
  WC_RNG_{INIT_,}FLAG_RECOVER_AND_PROMOTE_FROM_NEXT_SEED is renamed
  _UPGRADE_FROM_NEXT_SEED (rng_bank.h: WC_RNG_BANK_FLAG_AUTO_UPGRADE_FROM_
  NEXT_SEED).  WC_RNG_INIT_FLAG_* retain their shipped values, with the
  new flags appended; WC_RNG_FLAG_* are renumbered alongside.

* Transient-vs-verdict taxonomy: WC_RNG_ERR_IS_TRANSIENT() (random.h, with
  a mirror in rng_bank.h for boundaries that predate it) names the codes
  that mean "not now" -- BUSY_E, NOT_READY_E, NEEDS_RECOVERY_E, RAN_BLOCK_E,
  ENTROPY_RT_E, ENTROPY_APT_E.  wc_InitRng*() passes them through from the
  seed source verbatim (ReseedSourceFailure(), shared by instantiate and
  reseed) rather than folding them into RNG_FAILURE_E; rng_bank.c keys its
  retry loops on the same set.  BUSY_E and MEMORY_E -- a resource that
  requires waiting, in a context that can't -- never condemn, even with no
  reseed runway (RngGenerateFailure(), now also the single outcome mapping
  for wc_RNG_DRBG_Reseed_Now()).  wc_RNG_Status() precomputes the code for
  a status (NOT_READY_E / RNG_FAILURE_E / DRBG_CONT_FIPS_E) and replaces
  the ad hoc status checks throughout.  wc_GenerateSeed() with
  HAVE_ENTROPY_MEMUSE returns BUSY_E from a context that cannot run the
  wolfEntropy source rather than silently substituting a backup source.

* WC_RNG_INIT_FLAG_TEST_USER_SEED: caller-supplied seed material is
  health-tested and laid out exactly as module-gathered material (leading
  SEED_BLOCK_SZ bytes are the test block, excluded from DRBG input in FIPS
  and non-FULL_SEED builds); wc_InitRngFixedSeed() uses it, restoring its
  master behavior.  Without the flag the user seed is copied at the
  instantiate offset, so no supplied byte is discarded and no health test
  runs.  The strength floors live at the public entry points
  (UserSeedSzFloor(): WC_DRBG_SEED_SZ, plus a block under the flag where the
  block is excluded; zero refused); _InitRng() keeps only the one-block
  backstop.  wc_InitRngNonce_UserSeed() refuses without WC_RNG_HAVE_RBGC
  (provenance marking lives there) and validates its shape arguments.

Lifecycle hardening (random.[ch]):

* WC_RNG members shared by both DRBG cores -- drbgType, reseedCtr, the
  banked-next-seed aperture (nextSeed, nextSeedLen, nextSeedRBGCStratum) --
  move from DRBG_internal / DRBG_SHA512_internal into WC_RNG, for safe
  lock-free access by lease-free observers; the per-core structs keep the
  SMALL_STACK_CACHE newSeed_buf.  WC_DRBG_SEED_BUF_SIZE names the gathered
  seed length; the generic DRBG functions take the reseed counter by
  pointer.  NextSeedPtrs() and the per-core duplication it served are gone.

* _InitRng() zeroization (RngInitWipe()) skips the atomic words that can
  have lease-free concurrent observers (lock, RBGC_refcount, poolHead/Tail,
  nextStirLen, nextSeedLen), which are instead atomically (re)initialized;
  the apertures are painted _TORNDOWN at entry and reopened as the last act
  before publication, and rng->status becomes DRBG_OK only at the very end.
  WC_RNG_INIT_FLAG_PRESERVE_LOCK leaves the lock word and refcount exactly
  as found (refusing _LOCK_INITIALLY and _USE_FULL_MUTEX, and insisting the
  _REQUIRED bits agree), and discharges an inherited latch by CAS at entry
  rather than erasing it.  WC_RNG_STATIC_INITIALIZER is provided.

* Pool lifecycle: poolHead carries a 2-bit state above the epoch (UNALLOC,
  LIVE, CLAIMED, TORNDOWN).  wc_RNG_Pool_Alloc() allocates unclaimed and
  publishes by CAS; a writer claims by one CAS at entry and releases by CAS
  at every exit; wc_FreeRng() takes LIVE -> TORNDOWN by one CAS before any
  irreversible step and returns BUSY_E (nothing mutated) when a claim is
  held, never spinning; TORNDOWN refuses re-equipment until the next
  _InitRng().  Likewise the credited seed aperture gains
  WC_DRBG_NEXT_SEED_TORNDOWN, every ownership transition is a CAS, and a
  purge repaints a live claim _PURGED for its holder to unwind rather than
  reopening it from under the holder.  wc_FreeRng() frees the DRBG after
  nulling the pointer at every site, and uninstantiates only the core
  matching drbgType.

* wc_FreeRng() in lock builds takes the lease itself (unconditionally, so a
  standing latch or condemnation does not block teardown) and refuses a
  held instance with BUSY_E; wc_FreeRng_PreLocked() is the form for a
  caller already holding the lease, which it retains.  The WC_RNG_LOCK_
  REQUIRED-but-unheld case is OBJECT_NOT_LOCKED_E.  wc_RNG_lock_get_
  unconditional() / _put_unconditional() are the internal trivial forms.

* wc_RNG_DRBG_GetReseedCtr() becomes WOLFSSL_LOCAL (the counter is
  potentially sensitive internal state); wc_RNG_DRBG_NextSeedGenerate_
  Primary() is added; wc_RNG_DRBG_NextSeedCurrent(), wc_RNG_Pool_Current()
  and wc_RNG_lock_read() take const.  An instance with no DRBG (RDRAND et
  al.) never opens its seed aperture, and producers and consumers alike
  refuse it with WRONG_TYPE_OBJECT_E (was MISSING_RNG_E, which nothing on
  that path returned).  A stir refuses with the needs-recovery verdict
  (NEEDS_RECOVERY_E) when the instance is quarantined, due, or stale, and
  NOT_READY_E only when the interval trips within the call.

* WC_VERBOSE_RNG logging follows the taxonomy: transient codes are never
  logged as errors.

rng_bank.c / rng_bank.h:

* struct wc_rng_bank_inst now places its WC_RNG at offset 0, so
  WC_RNG_BANK_INST_TO_RNG() is a cast; wc_rng_bank_reinit_rng() (LOCAL)
  retires and reinstantiates any bank-owned rng, protected by WC_RNG.lock
  under _PRESERVE_LOCK where available (a held root yields BUSY_E) and by
  the inst-op gate otherwise; wc_rng_bank_inst_reinit() and
  wc_rng_bank_root_rng_reinit() are built on it.  A member is reborn only
  as a chain child of its root -- a root that cannot serve right now is a
  reason to retry, never to substitute a primary reseed.

* wc_rng_bank_reseed_range(): the RBGC arm takes the root's lease for the
  chain draw; the walk carries on past a per-instance failure (marking the
  instance due) and returns the first such failure, with a code that
  aborted the walk (WC_TIMEOUT_E, INTERRUPTED_E, a checkout failure)
  outranking it; wc_rng_bank_next_seed_generate_local() purges the member
  when the root's release reports an event under its hold, as
  wc_RNG_DRBG_NextSeedGenerate()'s chain arm does.

* wc_rng_bank_fini(): a member refusing to free (BUSY_E /
  STILL_REFERENCED_E) restores the bank refcount so the caller can and must
  retry; the root is freed after the members, so member pins are released
  before the root's refcount is judged.  The invalidation walk's root arm is
  unconditional (a root mid-reinit is NOT_INIT with its lock word live).
  Init retry loops key on WC_RNG_ERR_IS_TRANSIENT().

* rng_bank.h: WC_RNG_LOCK_ORPHANED / WC_RNG_LOCK_EXTRA_SHIFT 5 mirrored in
  the no-lock compat arm; for the WCv5.2.4 boundary, which carries the
  backported RNG services, WC_RNG_HAVE_STIR / WC_RNG_HAVE_RESEED_NOW
  capability markers and a wc_InitRngNonceRBGC() perso-argument shim, so
  consumers outside the boundary (src/ssl.c, src/ssl_crypto.c) gate on the
  markers rather than on FIPS version arithmetic.

linuxkm/lkcapi_sha_glue.c:

* wc_linuxkm_rng_state_invalidate(): with the entropy epoch, bumps the
  epoch and materializes only the bank root's latch synchronously
  (rng_invalidation_pre_check() keys on it), leaving members to lazy
  delivery so a consumer is admitted to a still-unlatched member and
  recovers it under its own lease rather than waiting out a quarantine;
  without the epoch, the synchronous walk as before.  The daemon-less bank
  path treats a transient member code from wc_rng_bank_reseed_range() as a
  deferred recovery, not a failure.

* Entropy daemon: a transient failure of the last-ditch root reinit is
  retried next pass rather than ending the daemon (which had made root
  recovery and next-seed feeding end for good on ordinary contention);
  the vmgenid poller's immediate root reseed takes the root's lease (it was
  OBJECT_NOT_LOCKED_E and void-cast); the kernel-log rule throughout --
  transient codes are one pass away and not errors, the SP 800-90B health
  verdicts are warnings (WC_LKM_RNG_ERR_IS_HEALTH()), anything else is an
  error -- at the recovery, banking, bonus-reseed and reinit arms; the
  banking pass's no-DRBG case is WRONG_TYPE_OBJECT_E; busy instances are
  counted in the recovery sweep's tally.

* wc_linuxkm_drbg_generate(): the kernel-facing language is two-valued --
  -EIO for a verdict (non-transient, or ENTROPY_RT_E / ENTROPY_APT_E),
  -EBUSY for every "not now" code; only BUSY_E outside the invalidation
  window (every instance held at once: an undersized bank) is logged as an
  error.  The pooling pass (re)equips any instance it finds poolless each
  turn, so no up-front allocation and no special case after a
  reinstantiation.  Bank sizing rationale documented.

* The _get_random_bytes() callback contract is best-effort, not
  unconditional success: a refusal from atomic context immediately after a
  global invalidation falls through silently to the native generator.
  linuxkm/WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS-7v3.patch: drop the
  WARN_ONCE on callback failure, and drop the routing of the batched
  get_random_{u8,u16,u32,u64}() through the callback (not FIPS-controlled
  consumers; get_random_bytes_user() and getrandom() remain fully covered).

Tests:

* wolfcrypt/test/test.c: flags_test() (WCFLAGS) replaces rng_flag_abi_test():
  pairwise-disjointness of every bit-flag namespace in the wolfcrypt headers
  at compile time and of the hand-numbered registries at run time, against
  the symbols rather than literal values; rng_epoch_test() (RNGEPOCH: epoch
  propagation on every aperture, mid-gather increments, busy and
  out-of-memory seed sources never condemn); rng_lifecycle_test() (RNGLIFE:
  RBGC parent pinning and STILL_REFERENCED_E, the destruction latch,
  wc_FreeRng_PreLocked() and the _PRESERVE_* reinit, the bank-walk mirror
  arm); rng_lock_fork_test() (RNGLKFRK: the orphaned-lease verdict and
  adoption across a real fork()); rng_init_flags_test() (contradictory and
  not-compiled-in init flags refused) and rng_seed_verdict_test() (transient
  codes from the seed source survive wc_InitRng*() verbatim; FIPS v7+ only,
  the pinned legacy random.c folds them); rng_seed_test() reactivated (dead
  since the seed-size defaults moved into random.h) and steered to SHA-256
  in SHA-512-preferring builds; WC_RNG_INIT_FLAG_TEST_USER_SEED arms in the
  wc_InitRngNonce_UserSeed() strict-contract block; leak fixes and
  goto-teardown in the RBGC-lifetime and pool tests; per-subtest in-kernel
  stack high-water marks (WC_LINUXKM_STACK_DEBUG_PER_TEST); WC_RNG moved to
  the heap in pkcs7authenveloped_run_vectors().

* tests/api/test_random.c, tests/unit-mcdc/test_random_*whitebox.c: follow
  the reseed counter to WC_RNG; forced seed failures use a nonsense code so
  the WC_VERBOSE_RNG line stays quiet; condemnation-on-reseed-failure arms
  saturate the counter explicitly, since invalidation no longer does.

* doc/dox_comments: every new API and flag; the instantiation-input and
  user-seed contracts; reseed/reseed_range return semantics; the next-seed
  return taxonomy.
2026-10-14 16:13:43 -05:00

517 lines
21 KiB
C

/* wolfcrypt/test/test.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
*/
#ifndef WOLFCRYPT_TEST_H
#define WOLFCRYPT_TEST_H
#include <wolfssl/wolfcrypt/types.h>
#ifndef WC_NO_RNG
/* for WC_RNG_HAVE_AUTO_LOCK and WC_RNG_LOCK_ATFORK; above extern "C" */
#include <wolfssl/wolfcrypt/random.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WC_TEST_RET_CUSTOM_TYPE
typedef WC_TEST_RET_CUSTOM_TYPE wc_test_ret_t;
#else
typedef sword32 wc_test_ret_t;
#endif
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
/* Needs the lock, threads it can start, and a heap for the compare buffer.
* WC_RNG_AUTO_LOCK_DEFAULT: the shared instance comes from wc_rng_new_ex(),
* which takes no flags, so a default-off build cannot give it a lock. */
#if defined(WC_RNG_HAVE_AUTO_LOCK) && WC_RNG_AUTO_LOCK_DEFAULT && \
!defined(WOLFSSL_ASYNC_CRYPT) && \
!defined(HAVE_INTEL_RDRAND) && !defined(WOLF_CRYPTO_CB_FIND) && \
!(defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_TRNG)) && \
!defined(WOLFSSL_STATIC_MEMORY) && !defined(WOLFSSL_NO_MALLOC) && \
!defined(WOLFSSL_XILINX_CRYPT_VERSAL) && \
(defined(WOLFSSL_PTHREADS) || \
(defined(USE_WINDOWS_API) && !defined(_WIN32_WCE)))
#define WC_TEST_RNG_AUTOLOCK
#endif
/* A lock the test can hold, plus the POSIX parts the timing tests use. */
#if defined(WC_TEST_RNG_AUTOLOCK) && !defined(__STRICT_ANSI__) && \
(defined(__unix__) || defined(__linux__) || defined(__APPLE__))
#define WC_TEST_RNG_HOLD
#endif
/* The fork test needs a real process model on top of the handlers. */
#if defined(WC_TEST_RNG_HOLD) && defined(WC_RNG_LOCK_ATFORK)
#define WC_TEST_RNG_AUTOFORK
#endif
/* fork() across a held WC_RNG.lock word: needs the word, a pid to compare,
* and a process model. No threads: the forking thread's own lease is the
* orphan. */
#if defined(WC_RNG_HAVE_LOCK) && defined(HAVE_HASHDRBG) && \
defined(HAVE_GETPID) && !defined(WOLFSSL_NO_GETPID) && \
!defined(__STRICT_ANSI__) && \
(defined(__unix__) || defined(__linux__) || defined(__APPLE__))
#define WC_TEST_RNG_LOCKFORK
#endif
#ifdef HAVE_STACK_SIZE
THREAD_RETURN WOLFSSL_THREAD wolfcrypt_test(void* args);
#else
wc_test_ret_t wolfcrypt_test(void* args);
#endif
void wc_test_render_error_message(const char* msg, wc_test_ret_t es);
#ifndef NO_MAIN_DRIVER
wc_test_ret_t wolfcrypt_test_main(int argc, char** argv);
#endif
#if defined(WOLFSSL_ESPIDF) || defined(_WIN32_WCE)
int wolf_test_task(void);
#endif
#ifndef WC_TEST_RET_HAVE_CUSTOM_MACROS
#define WC_TEST_RET_TAG_NC 0L
#define WC_TEST_RET_TAG_EC 1L
#define WC_TEST_RET_TAG_ERRNO 2L
#define WC_TEST_RET_TAG_I 3L
wc_static_assert(-(long)MIN_CODE_E < 0x7ffL);
#define WC_TEST_RET_ENC(line, i, tag) \
((wc_test_ret_t)(-((wc_test_ret_t)(line) + ((wc_test_ret_t)((word32)(i) & 0x7ffL) * 100000L) + ((wc_test_ret_t)(tag) << 29L))))
#ifndef WC_TEST_RET_LN
#define WC_TEST_RET_LN __LINE__
#endif
/* encode no code */
#define WC_TEST_RET_ENC_NC WC_TEST_RET_ENC(WC_TEST_RET_LN, 0, WC_TEST_RET_TAG_NC)
/* encode positive integer */
#define WC_TEST_RET_ENC_I(i) WC_TEST_RET_ENC(WC_TEST_RET_LN, ((i) > 0x7ff) ? 0x7ff : (i), WC_TEST_RET_TAG_I)
/* encode error code (negative integer) */
#define WC_TEST_RET_ENC_EC(ec) WC_TEST_RET_ENC(WC_TEST_RET_LN, -(ec), WC_TEST_RET_TAG_EC)
/* encode system/libc error code */
#if defined(HAVE_ERRNO_H) && !defined(NO_FILESYSTEM) && \
!defined(NO_STDIO_FILESYSTEM) && !defined(WOLFSSL_USER_IO)
#include <errno.h>
#define WC_TEST_RET_ENC_ERRNO WC_TEST_RET_ENC(WC_TEST_RET_LN, errno, WC_TEST_RET_TAG_ERRNO)
#else
#define WC_TEST_RET_ENC_ERRNO WC_TEST_RET_ENC_NC
#endif
#define WC_TEST_RET_DEC_TAG(x) ((-(x)) >> 29L)
/* decode line number */
#define WC_TEST_RET_DEC_LN(x) ((int)(((-(x)) & ~(3L << 29L)) % 100000L))
/* decode integer or errno */
#define WC_TEST_RET_DEC_I(x) ((int)((((-(x)) & ~(3L << 29L)) / 100000L)))
/* decode error code */
#define WC_TEST_RET_DEC_EC(x) ((int)(-WC_TEST_RET_DEC_I(x)))
#endif /* !WC_TEST_RET_HAVE_CUSTOM_MACROS */
#ifdef WC_TEST_EXPORT_SUBTESTS
#if defined(NO_FILESYSTEM) || defined(WC_NO_RNG)
#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \
!defined(USE_CERT_BUFFERS_3072) && !defined(USE_CERT_BUFFERS_4096)
#define USE_CERT_BUFFERS_2048
#endif
#if !defined(USE_CERT_BUFFERS_256)
#define USE_CERT_BUFFERS_256
#endif
#endif
/* Note, all macro gates used below must be available with just
* wolfcrypt/types.h included, i.e. no macros in alg-specific headers can be
* used here.
*/
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t macro_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t error_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t flags_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t octets_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t base64_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t base16_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t asn_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t md2_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t md5_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t md4_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha224_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha256_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha512_test(void);
#if !defined(WOLFSSL_NOSHA512_224) && \
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha512_224_test(void);
#endif
#if !defined(WOLFSSL_NOSHA512_256) && \
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha512_256_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha384_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sha3_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t shake128_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t shake256_test(void);
#ifdef WOLFSSL_KMAC
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t kmac_test(void);
#endif
#if defined(WOLFSSL_KMAC) || defined(WOLFSSL_CSHAKE)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cshake_test(void);
#endif
#ifdef WOLFSSL_SM3
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sm3_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hash_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_md5_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha224_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha256_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha384_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha512_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hmac_sha3_test(void);
#if defined(HAVE_HKDF) && !defined(NO_HMAC)
#if defined(WOLFSSL_AFALG_XILINX) || defined(WOLFSSL_AFALG_XILINX_AES) || \
defined(WOLFSSL_AFALG_XILINX_SHA3) || defined(WOLFSSL_AFALG_HASH_KEEP) || \
defined(WOLFSSL_AFALG_XILINX_RSA)
/* hkdf_test has issue with extern WOLFSSL_TEST_SUBROUTINE set on Xilinx with afalg */
static wc_test_ret_t hkdf_test(void);
#else
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hkdf_test(void);
#endif
#endif /* HAVE_HKDF && ! NO_HMAC */
#ifdef WOLFSSL_HAVE_PRF
#if defined(HAVE_HKDF) && !defined(NO_HMAC)
#ifdef WOLFSSL_BASE16
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t tls12_kdf_test(void);
#endif /* WOLFSSL_BASE16 */
#endif /* WOLFSSL_HAVE_HKDF && !NO_HMAC */
#endif /* WOLFSSL_HAVE_PRF */
#if defined(WOLFSSL_HAVE_PRF) && !defined(NO_HMAC) && defined(WOLFSSL_SHA384)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t prf_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sshkdf_test(void);
#ifdef WOLFSSL_TLS13
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t tls13_kdf_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t x963kdf_test(void);
#if defined(HAVE_HPKE) && \
(defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
defined(HAVE_CURVE448)) && \
defined(HAVE_AESGCM)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void);
#endif
#ifdef WC_SRTP_KDF
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t srtpkdf_test(void);
#endif
#if defined(WC_KDF_NIST_SP_800_56C) && \
(!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0))
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t nist_sp80056c_kdf_test(void);
#endif
#if defined(HAVE_CMAC_KDF) && (!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0))
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t nist_sp800108_cmac(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t nist_sp80056c_twostep_cmac(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t arc4_test(void);
#ifdef WC_RC2
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rc2_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t chacha_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t XChaCha_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t chacha20_poly1305_aead_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t XChaCha20Poly1305_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t des_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t des3_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes_cbc_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes_ctr_test(void);
#if defined(WOLFSSL_AES_CFB)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes_cfb_test(void);
#endif
#ifdef WOLFSSL_AES_XTS
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes_xts_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes192_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes256_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesofb_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cmac_test(void);
#ifdef HAVE_ASCON
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ascon_hash256_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ascon_aead128_test(void);
#endif
#if defined(WOLFSSL_SIPHASH)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t siphash_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t poly1305_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesgcm_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesgcm_default_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t gmac_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesccm_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aeskeywrap_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t camellia_test(void);
#ifdef WOLFSSL_SM4
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sm4_test(void);
#endif
#ifdef WC_RSA_NO_PADDING
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_no_pad_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rsa_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t dh_test(void);
#ifndef NO_DSA
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t dsa_test(void);
#endif
#ifdef WOLFCRYPT_HAVE_SRP
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t srp_test(void);
#endif
#ifndef WC_NO_RNG
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_test(void);
#ifdef WC_TEST_RNG_AUTOLOCK
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_thread_test(void);
#endif
#ifdef HAVE_WC_RNG_BANK
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t random_bank_test(void);
#endif
#if defined(HAVE_HASHDRBG) && !defined(CUSTOM_RAND_GENERATE_BLOCK) && \
(!defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0))
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rng_drbg_svc_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rng_drbg_rbgc_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rng_entropy_invalidate_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rng_drbg_nextseedstest(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rng_pool_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rng_epoch_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t rng_lifecycle_test(void);
#endif /* WC_NO_RNG */
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pwdbased_test(void);
#if defined(USE_CERT_BUFFERS_2048) && \
defined(HAVE_PKCS12) && \
!defined(NO_ASN) && !defined(NO_PWDBASED) && !defined(NO_HMAC) && \
!defined(NO_CERTS) && !defined(NO_DES3) && !defined(NO_SHA)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs12_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ripemd_test(void);
#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openssl_test(void); /* test mini api */
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openssl_pkey0_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openssl_pkey1_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openSSL_evpMD_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t openssl_evpSig_test(void);
#endif
#if defined(HAVE_PBKDF1) && !defined(NO_SHA)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pbkdf1_test(void);
#endif
#if defined(HAVE_PKCS12) && !defined(NO_SHA256)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs12_pbkdf_test(void);
#endif
#if defined(HAVE_PBKDF2) && !defined(NO_SHA256) && !defined(NO_HMAC)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pbkdf2_test(void);
#endif
#if !defined(NO_PWDBASED) && defined(HAVE_SCRYPT)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t scrypt_test(void);
#endif
#ifdef HAVE_ARGON2
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t argon2_test(void);
#endif
#ifdef HAVE_ECC
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_test(void);
#if defined(HAVE_ECC_ENCRYPT) && defined(HAVE_AES_CBC) && \
(defined(WOLFSSL_AES_128) || defined(WOLFSSL_AES_256))
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_encrypt_test(void);
#endif
#if defined(USE_CERT_BUFFERS_256) && !defined(WOLFSSL_ATECC508A) && \
!defined(WOLFSSL_ATECC608A) && !defined(NO_ECC256) && \
defined(HAVE_ECC_VERIFY) && defined(HAVE_ECC_SIGN) && \
(!defined(WOLF_CRYPTO_CB_ONLY_ECC) || defined(WOLFSSL_SWDEV)) && !defined(NO_ECC_SECP)
/* skip for ATECC508/608A, cannot import private key buffers */
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ecc_test_buffers(void);
#endif
#endif
#ifdef HAVE_CURVE25519
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t curve25519_test(void);
#endif
#ifdef HAVE_ED25519
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ed25519_test(void);
#endif
#ifdef HAVE_CURVE448
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t curve448_test(void);
#endif
#ifdef HAVE_ED448
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t ed448_test(void);
#endif
#ifdef WOLFSSL_HAVE_MLKEM
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mlkem_test(void);
#endif
#ifdef WOLFSSL_HAVE_FRODOKEM
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t frodokem_test(void);
#endif
#ifdef WOLFSSL_HAVE_MLDSA
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mldsa_test(void);
#endif
#ifdef HAVE_FALCON
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t falcon_test(void);
#endif
#if defined(WOLFSSL_HAVE_XMSS)
#if !defined(WOLFSSL_SMALL_STACK) && WOLFSSL_XMSS_MIN_HEIGHT <= 10
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t xmss_test_verify_only(void);
#endif
#if !defined(WOLFSSL_XMSS_VERIFY_ONLY)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t xmss_test(void);
#endif
#endif
#if defined(WOLFSSL_HAVE_LMS)
#if !defined(WOLFSSL_SMALL_STACK)
#if (LMS_MAX_HEIGHT >= 10) && !defined(WOLFSSL_NO_LMS_SHA256_256)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test_verify_only(void);
#endif
#endif
#if !defined(WOLFSSL_LMS_VERIFY_ONLY)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t lms_test(void);
#endif
#endif
#if defined(WOLFSSL_HAVE_SLHDSA)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t slhdsa_test(void);
#endif
#ifdef WOLFCRYPT_HAVE_ECCSI
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t eccsi_test(void);
#endif
#ifdef WOLFCRYPT_HAVE_SAKKE
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sakke_test(void);
#endif
#ifdef HAVE_BLAKE2B
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t blake2b_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t blake2b_hmac_test(void);
#endif
#ifdef HAVE_BLAKE2S
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t blake2s_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t blake2s_hmac_test(void);
#endif
#ifdef HAVE_LIBZ
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t compress_test(void);
#endif
#ifdef HAVE_PKCS7
#ifndef NO_PKCS7_ENCRYPTED_DATA
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs7encrypted_test(void);
#endif
#if defined(HAVE_LIBZ) && !defined(NO_PKCS7_COMPRESSED_DATA)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs7compressed_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs7signed_test(void);
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs7enveloped_test(void);
#if defined(HAVE_AESGCM) || defined(HAVE_AESCCM)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs7authenveloped_test(void);
#endif
#if !defined(NO_AES) && defined(HAVE_AES_CBC)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t pkcs7callback_test(byte* cert, word32 certSz, byte* key,
word32 keySz);
#endif
#endif
#if !defined(NO_ASN_TIME) && !defined(NO_RSA) && defined(WOLFSSL_TEST_CERT) && \
!defined(NO_FILESYSTEM)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cert_test(void);
#endif
#if defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_TEST_CERT) && \
!defined(NO_FILESYSTEM) && !defined(NO_RSA) && defined(WOLFSSL_GEN_CERT)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t certext_test(void);
#endif
#if defined(WOLFSSL_CERT_GEN_CACHE) && defined(WOLFSSL_TEST_CERT) && \
defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t decodedCertCache_test(void);
#endif
#if defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_ALT_NAMES) && \
defined(WOLFSSL_ASN_TEMPLATE) && \
(defined(WOLFSSL_TEST_CERT) || defined(OPENSSL_EXTRA) || \
defined(OPENSSL_EXTRA_X509_SMALL) || defined(WOLFSSL_PUBLIC_ASN))
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t flattenAltNames_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t memory_test(void);
#if defined(WOLFSSL_PUBLIC_MP) && \
((defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
defined(USE_FAST_MATH))
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mp_test(void);
#endif
#if defined(WOLFSSL_PUBLIC_MP) && defined(WOLFSSL_KEY_GEN)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t prime_test(void);
#endif
#if defined(ASN_BER_TO_DER) && \
(defined(WOLFSSL_TEST_CERT) || defined(OPENSSL_EXTRA) || \
defined(OPENSSL_EXTRA_X509_SMALL))
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t berder_test(void);
#endif
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t logging_test(void);
#if !defined(NO_ASN) && !defined(NO_ASN_TIME)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t time_test(void);
#endif
#if defined(__INCLUDE_NUTTX_CONFIG_H)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t wolfcrypt_mutex_test(void);
#else
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t mutex_test(void);
#endif
#if defined(USE_WOLFSSL_MEMORY) && !defined(FREERTOS)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t memcb_test(void);
#endif
#ifdef WOLFSSL_CAAM_BLOB
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t blob_test(void);
#endif
#ifdef HAVE_ARIA
#include "wolfssl/wolfcrypt/port/aria/aria-crypt.h"
void printOutput(const char *strName, unsigned char *data, unsigned int dataSz);
extern WOLFSSL_TEST_SUBROUTINE int ariagcm_test(MC_ALGID);
#endif
#if defined(WOLF_CRYPTO_CB) && !defined(WC_TEST_NO_CRYPTOCB_SW_TEST)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t cryptocb_test(void);
#endif
#if defined(WOLFSSL_SEC_QORIQ) && defined(WOLFSSL_SEC_QORIQ_SIM)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t sec_qoriq_test(void);
#endif
#ifdef WOLFSSL_CERT_PIV
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t certpiv_test(void);
#endif
#ifdef WOLFSSL_AES_SIV
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes_siv_test(void);
#endif
#if defined(WOLFSSL_AES_EAX) && \
(!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
extern WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aes_eax_test(void);
#endif /* WOLFSSL_AES_EAX */
#endif /* WC_TEST_EXPORT_SUBTESTS */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* WOLFCRYPT_TEST_H */