TI C2000 example: HWAES=1 AESA offload with HW-vs-SW cross-KATs
parent
c8e71603ae
commit
8fca85fa57
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 <NAME>=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()`.
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@
|
|||
#ifdef WOLF_AES
|
||||
#include <wolfssl/wolfcrypt/aes.h>
|
||||
#endif
|
||||
#ifdef WOLF_HWAES
|
||||
#include <wolfssl/wolfcrypt/port/ti/ti-c2000.h>
|
||||
#endif
|
||||
#ifdef WOLF_25519
|
||||
#include <wolfssl/wolfcrypt/curve25519.h>
|
||||
#include <wolfssl/wolfcrypt/ed25519.h>
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Reference in New Issue