diff --git a/embedded/ti-c2000-f28p55x/Header/user_settings.h b/embedded/ti-c2000-f28p55x/Header/user_settings.h index 9e692af7..13389c6b 100644 --- a/embedded/ti-c2000-f28p55x/Header/user_settings.h +++ b/embedded/ti-c2000-f28p55x/Header/user_settings.h @@ -329,6 +329,36 @@ extern "C" { #define NO_AES #endif +#ifdef WOLF_HWAES +/* Offload AES-ECB/CBC/CTR to the on-chip AESA block through the crypto + * callback framework. Software AES stays compiled in: a context opts into + * hardware with wc_AesInit(&aes, NULL, WOLFSSL_C2000_DEVID), while one + * initialised with INVALID_DEVID stays pure software. That is what lets the + * KAT harness cross-check the two in a single image, so deliberately do NOT + * define WOLF_CRYPTO_CB_ONLY_AES. */ +#undef WOLF_CRYPTO_CB +#define WOLF_CRYPTO_CB +#undef WOLFSSL_C2000_AES +#define WOLFSSL_C2000_AES + +/* HAVE_AES_ECB is what compiles wc_AesEcbEncrypt/Decrypt and, with it, the ECB + * crypto-callback hook the hardware port needs; WOLFSSL_AES_DIRECT alone only + * creates the callback plumbing, not the entry points. Kept inside the HWAES + * block: it also switches the software CTR path to the bulk-ECB strategy and + * costs code size, so a software-only AES=1 build should not pay for it. */ +#undef HAVE_AES_ECB +#define HAVE_AES_ECB + +/* Single source of truth for the AESA device id. ti-c2000.h defaults this to + * 0x2000 behind #ifndef, so setting it here wins and lets WC_USE_DEVID be + * derived from it: wolfcrypt_test and benchmark then target the same device + * the KAT harness passes to wc_AesInit(), with no literal to keep in sync. */ +#undef WOLFSSL_C2000_DEVID +#define WOLFSSL_C2000_DEVID 0x2000 +#undef WC_USE_DEVID +#define WC_USE_DEVID WOLFSSL_C2000_DEVID +#endif + /* Curve25519 (X25519) + Ed25519. Enabled with EXTRA_CFLAGS=--define=WOLF_25519 * (X25519=1 build). No __uint128_t and no SP-25519 backend on C28x, so the * default fe[10] 32-bit-limb field arithmetic is used; Ed25519 reuses the diff --git a/embedded/ti-c2000-f28p55x/Makefile b/embedded/ti-c2000-f28p55x/Makefile index ce4f86b9..ca2a1afb 100644 --- a/embedded/ti-c2000-f28p55x/Makefile +++ b/embedded/ti-c2000-f28p55x/Makefile @@ -36,13 +36,16 @@ endif CL := $(CGT_ROOT)/bin/cl2000 +# Header/ must precede $(WOLFROOT): wolfSSL's documented user_settings.h +# workflow puts one at the wolfSSL tree root, which would otherwise shadow this +# example's and silently build a different configuration. INCS := \ -I$(CGT_ROOT)/include \ -I$(DRV) \ -I$(DEV)/common/include \ -I$(DEV)/headers/include \ - -I$(WOLFROOT) \ - -I$(CURDIR)/Header + -I$(CURDIR)/Header \ + -I$(WOLFROOT) # --float_support=fpu32 and --abi=eabi must match the prebuilt driverlib.lib. # Define WOLF_C2000_SCI_STDOUT to route printf to SCIA (XDS110 COM); omit it to @@ -108,13 +111,16 @@ ifeq ($(MLKEM),1) $(WOLFROOT)/wolfcrypt/src/wc_mlkem_poly.c endif +# aes.c + wc_encrypt.c are wanted by AES=1, AESEXTRA=1 and HWAES=1. Each sets +# NEED_AES_CORE and the pair is appended once below: the build is a single +# cl2000 invocation, so a source listed twice multiply-defines at link. +NEED_AES_CORE := 0 + # AES=1 adds AES-CBC/CTR/CFB/GCM (software, table-driven; GCM_SMALL GHASH). AES ?= 0 ifeq ($(AES),1) CFLAGS += --define=WOLF_AES - WC_SRCS += \ - $(WOLFROOT)/wolfcrypt/src/aes.c \ - $(WOLFROOT)/wolfcrypt/src/wc_encrypt.c + NEED_AES_CORE := 1 endif # X25519=1 adds Curve25519 (X25519) + Ed25519 (default fe[10] 32-bit backend). @@ -164,14 +170,24 @@ ifeq ($(AESEXTRA),1) CFLAGS += --define=WOLF_AES --define=WOLF_AESEXTRA WC_SRCS += \ $(WOLFROOT)/wolfcrypt/src/cmac.c - # aes.c and wc_encrypt.c are also pulled in by AES=1; add them here only when - # AES=1 did not, so they are not listed twice in the single cl2000 invocation - # (which would multiply-define their symbols at link). - ifneq ($(AES),1) - WC_SRCS += \ - $(WOLFROOT)/wolfcrypt/src/aes.c \ - $(WOLFROOT)/wolfcrypt/src/wc_encrypt.c - endif + NEED_AES_CORE := 1 +endif + +# HWAES=1 offloads AES-ECB/CBC/CTR to the on-chip AESA accelerator (TI EIP-120t +# at 0x42000) via crypto callbacks. Software AES stays compiled in so one image +# can compare both paths. Implies AES=1; driverlib.lib is already linked. +HWAES ?= 0 +ifeq ($(HWAES),1) + CFLAGS += --define=WOLF_AES --define=WOLF_HWAES + # WC_USE_DEVID points wolfcrypt_test and benchmark at the hardware device; + # without it they init every Aes context with INVALID_DEVID and silently + # measure/test software only. It is derived from WOLFSSL_C2000_DEVID in + # Header/user_settings.h rather than repeated as a literal here, so the two + # cannot drift apart. + WC_SRCS += \ + $(WOLFROOT)/wolfcrypt/src/cryptocb.c \ + $(WOLFROOT)/wolfcrypt/src/port/ti/ti-c2000-aes.c + NEED_AES_CORE := 1 endif # RSA=1 adds RSA verify (SP math backend, shared with the ECC P-256 build). @@ -261,6 +277,13 @@ ifeq ($(MEMPROF),1) CFLAGS += --define=WOLF_MEM_PROFILE endif +# Append the shared AES core once, after every toggle has had its say. +ifeq ($(NEED_AES_CORE),1) + WC_SRCS += \ + $(WOLFROOT)/wolfcrypt/src/aes.c \ + $(WOLFROOT)/wolfcrypt/src/wc_encrypt.c +endif + ALL_SRCS := $(WC_SRCS) $(HARNESS_SRCS) $(BSP_SRCS) $(ASM_SRCS) .PHONY: all clean diff --git a/embedded/ti-c2000-f28p55x/README.md b/embedded/ti-c2000-f28p55x/README.md index f642a38a..cd623781 100644 --- a/embedded/ti-c2000-f28p55x/README.md +++ b/embedded/ti-c2000-f28p55x/README.md @@ -10,7 +10,7 @@ The default build runs a KAT suite plus `wolfcrypt_test` and (optionally) `bench - SHA3-224/256/384/512, SHAKE128, SHAKE256 (split-64 Keccak permutation, ~53% faster than the generic C path on C28x) - ML-DSA-87 (Dilithium level 5) verify, and the full keygen+sign+verify round-trip (`SIGN=1`) - ML-KEM-768 (FIPS 203) keygen/encap/decap round-trip (`MLKEM=1`) -- AES-128/192/256 CBC/CTR/CFB/GCM (`AES=1`); AES-CMAC, AES-CCM, AES-GMAC (`AESEXTRA=1`) +- AES-128/192/256 CBC/CTR/CFB/GCM (`AES=1`); AES-CMAC, AES-CCM, AES-GMAC (`AESEXTRA=1`); hardware-accelerated AES-ECB/CBC/CTR on the on-chip AESA block (`HWAES=1`) - HMAC-SHA256 + HKDF (`HKDF=1`) - ChaCha20-Poly1305 AEAD + Poly1305 (`CHACHA=1`) - X25519 + Ed25519 (`X25519=1`) @@ -54,6 +54,7 @@ Each is `make =1` (default 0 unless noted), additive on top of the default | `MLKEM=1` | ML-KEM-768 (FIPS 203) | | `AES=1` | AES-CBC/CTR/CFB/GCM (table-driven, `GCM_SMALL`) | | `AESEXTRA=1` | AES-CMAC, AES-CCM, AES-GMAC (implies the AES core) | +| `HWAES=1` | Offload AES-ECB/CBC/CTR to the on-chip AESA accelerator via crypto callbacks (implies the AES core). See "Hardware AES" below | | `X25519=1` | Curve25519 (X25519) + Ed25519 | | `HKDF=1` | HMAC + HKDF (RFC 2104 / RFC 5869) | | `CHACHA=1` | ChaCha20-Poly1305 AEAD (RFC 8439) | @@ -100,6 +101,31 @@ ML-DSA-87 (asymmetric, @150 MHz): verify ~225 ms/op; keygen and signing also run - Big SP/`*_NO_MALLOC` structs (ecc_key, RsaKey, ChaChaPoly_Aead) belong in `.bss`/static, not on the stack: the SP point/modexp call tree plus a stack-allocated key can overflow the 16 KW stack. - `wc_RsaSSL_Verify` in the `RSA_VERIFY_ONLY` / `SP_NO_MALLOC` config runs the modexp in place in the caller's buffer, so the output buffer must be at least the key size (256 B for RSA-2048). +## Hardware AES (`HWAES=1`) + +The F28P550SJ has an on-chip AES accelerator ("AESA", a TI EIP-120t at `0x00042000`) that C2000Ware exposes through `driverlib/f28p55x/driverlib/aes.h`. `HWAES=1` offloads AES-ECB/CBC/CTR to it via the wolfCrypt crypto-callback framework (`wolfcrypt/src/port/ti/ti-c2000-aes.c` in the wolfSSL tree, gated on `WOLFSSL_C2000_AES`). `driverlib.lib` is already linked by this example, so no extra build plumbing is needed. + +Software AES stays compiled in. A context opts into hardware with `wc_AesInit(&aes, NULL, WOLFSSL_C2000_DEVID)`; one initialised with `INVALID_DEVID` runs pure software. `wolf_aes_hw_test()` uses both and compares them, which is the point: on a 16-bit-byte target the octet marshalling into the accelerator's 32-bit registers is the highest-risk part of the port, and a mismatch is exactly what you want to see. The harness prints 13 lines covering ECB/CBC/CTR at 128/192/256 bits, multi-block, split calls, in-place decrypt and a non-block-aligned CTR split, each checked against software and (for the first block of each mode) against the published NIST SP800-38A vector. + +`HWAES=1` also defines `WC_USE_DEVID=0x2000` so `wolfcrypt_test` and `benchmark` exercise the device too -- without it they init every context with `INVALID_DEVID` and silently measure software. + +Measured at 150 MHz (`make HWAES=1 BENCH=1`, which prints paired `SW`/`HW` rows): + +| Operation | Software | AESA | Speedup | +|---|---|---|---| +| AES-128-ECB encrypt | 471 KiB/s | 2.37 MiB/s | 5.2x | +| AES-256-ECB encrypt | 377 KiB/s | 2.32 MiB/s | 6.3x | +| AES-128-CBC encrypt | 405 KiB/s | 2.36 MiB/s | 6.0x | +| AES-128-CBC decrypt | 388 KiB/s | 2.34 MiB/s | 6.2x | +| AES-256-CBC encrypt | 333 KiB/s | 2.31 MiB/s | 7.1x | +| AES-256-CBC decrypt | 322 KiB/s | 2.29 MiB/s | 7.3x | +| AES-128-CTR | 408 KiB/s | 1.45 MiB/s | 3.6x | +| AES-256-CTR | 335 KiB/s | 1.44 MiB/s | 4.4x | + +AES-GCM barely moves (~32 to ~34 KiB/s): only its internal ECB calls reach the accelerator and the `GCM_SMALL` byte-wise GHASH dominates. Using the block's own GCM mode is future work. CFB, CCM, CMAC and everything else stay in software -- the callback returns `CRYPTOCB_UNAVAILABLE` and wolfCrypt falls through transparently. + +Two hardware quirks are documented in `IDE/C2000/README.md` in the wolfSSL tree and worth knowing before touching this code: driverlib expects little-endian octets within each 32-bit word (not a raw cast of a `byte*`), and the block's CTR counter increment does **not** match wolfCrypt's big-endian 128-bit `IncrementAesCounter()` once an increment carries across an octet boundary -- so the port drives the accelerator in ECB mode and keeps the counter in software. Both quirks produce a *correct first block*, which is why the multi-block cases in the harness matter. + ## RNG caveat -The F28P55x has **no hardware TRNG**. The example uses `WOLFSSL_GENSEED_FORTEST` (random.c's built-in incrementing test seed feeding the real SHA-256 Hash-DRBG): exercises the real DRBG path but is **development-only, not cryptographically secure**. For production, wire a real entropy source into `wc_GenerateSeed()`. +The F28P550SJ has **no hardware TRNG**. This build uses `WOLFSSL_GENSEED_FORTEST` (random.c's built-in incrementing test seed feeding the real SHA-256 Hash-DRBG): it exercises the real DRBG path but is **development-only, not cryptographically secure**. For production, wire a real entropy source into `wc_GenerateSeed()`. diff --git a/embedded/ti-c2000-f28p55x/Source/wolf_main.c b/embedded/ti-c2000-f28p55x/Source/wolf_main.c index 6c282de6..e1a893f6 100644 --- a/embedded/ti-c2000-f28p55x/Source/wolf_main.c +++ b/embedded/ti-c2000-f28p55x/Source/wolf_main.c @@ -55,6 +55,9 @@ #ifdef WOLF_AES #include #endif +#ifdef WOLF_HWAES +#include +#endif #ifdef WOLF_25519 #include #include @@ -1170,6 +1173,155 @@ static void wolf_aes_test(void) } #endif /* WOLF_AES */ +#ifdef WOLF_HWAES +/* Cross-check the AESA hardware against software AES. + * + * Two contexts deliberately: 'hw' carries WOLFSSL_C2000_DEVID so every aes.c + * hook routes to the callback, 'sw' carries INVALID_DEVID so every hook skips + * it. That separation matters -- with HAVE_AES_ECB on, a devId-bearing + * context would route even the software CTR path's internal wc_AesEcbEncrypt + * back to hardware. + * + * NIST SP800-38A vectors are asserted where we have them; multi-block, + * split-call and in-place cases are checked hardware-against-software, since + * software AES is already covered by wolfcrypt_test. */ +static void hw_report(const char* name, int r, const byte* a, const byte* b, + word32 len) +{ + printf("HW %s: %s\r\n", name, + (r == 0 && XMEMCMP(a, b, len) == 0) ? "PASS" : "FAIL"); +} + +static void wolf_aes_hw_test(void) +{ + /* NIST SP800-38A F.1/F.2/F.5 four-block plaintext. */ + static const byte pt[64] = { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, + 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c, + 0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, + 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11, + 0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef, + 0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17, + 0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10}; + static const byte k128[16] = { + 0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6, + 0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c}; + static const byte k192[24] = { + 0x8e,0x73,0xb0,0xf7,0xda,0x0e,0x64,0x52, + 0xc8,0x10,0xf3,0x2b,0x80,0x90,0x79,0xe5, + 0x62,0xf8,0xea,0xd2,0x52,0x2c,0x6b,0x7b}; + static const byte k256[32] = { + 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, + 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, + 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4}; + static const byte iv[16] = { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; + static const byte ctr_iv[16] = { + 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, + 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff}; + /* First-block published answers (F.1.1, F.2.1, F.5.1). */ + static const byte ecb_ct1[16] = { + 0x3a,0xd7,0x7b,0xb4,0x0d,0x7a,0x36,0x60, + 0xa8,0x9e,0xca,0xf3,0x24,0x66,0xef,0x97}; + static const byte cbc_ct1[16] = { + 0x76,0x49,0xab,0xac,0x81,0x19,0xb2,0x46, + 0xce,0xe9,0x8e,0x9b,0x12,0xe9,0x19,0x7d}; + /* Full 64-octet CTR answer, not just block 1: this vector's counter starts + * at ...fe ff, so block 2 is the first needing a carry across an octet + * boundary, and checking only block 1 hides a broken increment. */ + static const byte ctr_ct[64] = { + 0x87,0x4d,0x61,0x91,0xb6,0x20,0xe3,0x26, + 0x1b,0xef,0x68,0x64,0x99,0x0d,0xb6,0xce, + 0x98,0x06,0xf6,0x6b,0x79,0x70,0xfd,0xff, + 0x86,0x17,0x18,0x7b,0xb9,0xff,0xfd,0xff, + 0x5a,0xe4,0xdf,0x3e,0xdb,0xd5,0xd3,0x5e, + 0x5b,0x4f,0x09,0x02,0x0d,0xb0,0x3e,0xab, + 0x1e,0x03,0x1d,0xda,0x2f,0xbe,0x03,0xd1, + 0x79,0x21,0x70,0xa0,0xf3,0x00,0x9c,0xee}; + + /* .bss, not stack: the C28x stack is 16 KW and an Aes is not small. */ + static Aes hw, sw; + static byte oh[64], os[64], dh[64]; + int rh, rs; + + if (wc_AesInit(&hw, NULL, WOLFSSL_C2000_DEVID) != 0 || + wc_AesInit(&sw, NULL, INVALID_DEVID) != 0) { + printf("HW AES init: FAIL\r\n"); + return; + } + + /* ---- ECB, 64 octets (exercises the multi-block loop) ---- */ + rh = wc_AesSetKey(&hw, k128, 16, NULL, AES_ENCRYPTION); + rs = wc_AesSetKey(&sw, k128, 16, NULL, AES_ENCRYPTION); + if (rh == 0) rh = wc_AesEcbEncrypt(&hw, oh, pt, 64); + if (rs == 0) rs = wc_AesEcbEncrypt(&sw, os, pt, 64); + hw_report("AES-128-ECB encrypt vs NIST", rh, oh, ecb_ct1, 16); + hw_report("AES-128-ECB encrypt vs SW", (rh | rs), oh, os, 64); + + rh = wc_AesSetKey(&hw, k128, 16, NULL, AES_DECRYPTION); + if (rh == 0) rh = wc_AesEcbDecrypt(&hw, dh, oh, 64); + hw_report("AES-128-ECB decrypt round-trip", rh, dh, pt, 64); + + /* ---- CBC, 64 octets ---- */ + rh = wc_AesSetKey(&hw, k128, 16, iv, AES_ENCRYPTION); + rs = wc_AesSetKey(&sw, k128, 16, iv, AES_ENCRYPTION); + if (rh == 0) rh = wc_AesCbcEncrypt(&hw, oh, pt, 64); + if (rs == 0) rs = wc_AesCbcEncrypt(&sw, os, pt, 64); + hw_report("AES-128-CBC encrypt vs NIST", rh, oh, cbc_ct1, 16); + hw_report("AES-128-CBC encrypt vs SW", (rh | rs), oh, os, 64); + + rh = wc_AesSetKey(&hw, k128, 16, iv, AES_DECRYPTION); + if (rh == 0) rh = wc_AesCbcDecrypt(&hw, dh, oh, 64); + hw_report("AES-128-CBC decrypt round-trip", rh, dh, pt, 64); + + /* ---- CBC split across calls: proves aes->reg chaining ---- */ + rh = wc_AesSetKey(&hw, k128, 16, iv, AES_ENCRYPTION); + if (rh == 0) rh = wc_AesCbcEncrypt(&hw, oh, pt, 16); + if (rh == 0) rh = wc_AesCbcEncrypt(&hw, oh + 16, pt + 16, 48); + hw_report("AES-128-CBC split-call chain", (rh | rs), oh, os, 64); + + /* ---- CBC in-place decrypt: proves the last-block save ---- */ + XMEMCPY(dh, os, 64); + rh = wc_AesSetKey(&hw, k128, 16, iv, AES_DECRYPTION); + if (rh == 0) rh = wc_AesCbcDecrypt(&hw, dh, dh, 64); + hw_report("AES-128-CBC in-place decrypt", rh, dh, pt, 64); + + /* ---- CTR, 64 octets ---- */ + rh = wc_AesSetKey(&hw, k128, 16, ctr_iv, AES_ENCRYPTION); + rs = wc_AesSetKey(&sw, k128, 16, ctr_iv, AES_ENCRYPTION); + if (rh == 0) rh = wc_AesCtrEncrypt(&hw, oh, pt, 64); + if (rs == 0) rs = wc_AesCtrEncrypt(&sw, os, pt, 64); + hw_report("AES-128-CTR vs NIST (64B)", rh, oh, ctr_ct, 64); + hw_report("AES-128-CTR SW vs NIST (64B)", rs, os, ctr_ct, 64); + hw_report("AES-128-CTR vs SW", (rh | rs), oh, os, 64); + + /* ---- CTR split at a non-block boundary: proves aes->left/aes->tmp ---- */ + rh = wc_AesSetKey(&hw, k128, 16, ctr_iv, AES_ENCRYPTION); + if (rh == 0) rh = wc_AesCtrEncrypt(&hw, oh, pt, 10); + if (rh == 0) rh = wc_AesCtrEncrypt(&hw, oh + 10, pt + 10, 54); + hw_report("AES-128-CTR partial split", (rh | rs), oh, os, 64); + + /* ---- 192- and 256-bit keys: the 6- and 8-word AES_setKey1 paths ---- */ + rh = wc_AesSetKey(&hw, k192, 24, iv, AES_ENCRYPTION); + rs = wc_AesSetKey(&sw, k192, 24, iv, AES_ENCRYPTION); + if (rh == 0) rh = wc_AesCbcEncrypt(&hw, oh, pt, 64); + if (rs == 0) rs = wc_AesCbcEncrypt(&sw, os, pt, 64); + hw_report("AES-192-CBC encrypt vs SW", (rh | rs), oh, os, 64); + + rh = wc_AesSetKey(&hw, k256, 32, iv, AES_ENCRYPTION); + rs = wc_AesSetKey(&sw, k256, 32, iv, AES_ENCRYPTION); + if (rh == 0) rh = wc_AesCbcEncrypt(&hw, oh, pt, 64); + if (rs == 0) rs = wc_AesCbcEncrypt(&sw, os, pt, 64); + hw_report("AES-256-CBC encrypt vs SW", (rh | rs), oh, os, 64); + + wc_AesFree(&hw); + wc_AesFree(&sw); +} +#endif /* WOLF_HWAES */ + #ifdef WOLF_25519 static void wolf_curve25519_test(void) { @@ -1747,11 +1899,27 @@ int main(void) printf("\r\n"); printf("=== wolfSSL wolfCrypt on TI C2000 LAUNCHXL-F28P55X ===\r\n"); + #ifdef WOLF_MEM_PROFILE /* Route XMALLOC/XFREE/XREALLOC through the heap high-water tracker. */ wolf_mem_install(); #endif +#ifdef WOLF_HWAES + /* wolfCrypt_Init() is mandatory first: it sets every device-table slot to + * INVALID_DEVID, and RegisterDevice only claims a slot marked that way. + * Without it the table is BSS-zero and registration fails with BUFFER_E. */ + if (wolfCrypt_Init() != 0) { + printf("wolfCrypt_Init: FAIL\r\n"); + } + else if (wc_C2000_Init(WOLFSSL_C2000_DEVID) != 0) { + printf("C2000 AESA init: FAIL\r\n"); + } + else { + printf("C2000 AESA init: PASS\r\n"); + } +#endif + wolf_sha3_256_test(); wolf_sha256_test(); wolf_shake256_test(); @@ -1796,6 +1964,11 @@ int main(void) wolf_aes_test(); #endif /* WOLF_AES */ +#ifdef WOLF_HWAES + printf("\r\n--- AES hardware (AESA) vs software ---\r\n"); + wolf_aes_hw_test(); +#endif /* WOLF_HWAES */ + #ifdef WOLF_25519 printf("\r\n--- Curve25519 (X25519) + Ed25519 ---\r\n"); wolf_curve25519_test();