Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions embedded/ti-c2000-f28p55x/Header/ecc_p384_kat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* ecc_p384_kat.h - deterministic ECDSA P-384 (SECP384R1) known-answer vector.
*
* Source: RFC 6979 Appendix A.2.6 (P-384), message "sample", hash SHA-384.
* The same vector wolfCrypt's own ecc384_test_deterministic_k() uses. The
* digest is not stored: the device hashes "sample" with SHA-384 itself, so the
* KAT covers the hash-to-verify chain rather than just the curve math.
*
* Brace-init byte arrays (NOT "\x.." string literals): on cl2000 a char[]/byte[]
* initialized from a "\x.." string sign-extends bytes >= 0x80 into the 16-bit
* cell; a brace-init list stores clean octets.
*/
#ifndef ECC_P384_KAT_H
#define ECC_P384_KAT_H

/* Public key Q = (Ux, Uy), 48 bytes each, big-endian. */
static const unsigned char kat_p384_qx[48] = {
0xEC,0x3A,0x4E,0x41,0x5B,0x4E,0x19,0xA4,0x56,0x86,0x18,0x02,0x9F,0x42,0x7F,0xA5,
0xDA,0x9A,0x8B,0xC4,0xAE,0x92,0xE0,0x2E,0x06,0xAA,0xE5,0x28,0x6B,0x30,0x0C,0x64,
0xDE,0xF8,0xF0,0xEA,0x90,0x55,0x86,0x60,0x64,0xA2,0x54,0x51,0x54,0x80,0xBC,0x13
};
static const unsigned char kat_p384_qy[48] = {
0x80,0x15,0xD9,0xB7,0x2D,0x7D,0x57,0x24,0x4E,0xA8,0xEF,0x9A,0xC0,0xC6,0x21,0x89,
0x67,0x08,0xA5,0x93,0x67,0xF9,0xDF,0xB9,0xF5,0x4C,0xA8,0x4B,0x3F,0x1C,0x9D,0xB1,
0x28,0x8B,0x23,0x1C,0x3A,0xE0,0xD4,0xFE,0x73,0x44,0xFD,0x25,0x33,0x26,0x47,0x20
};

/* Signature (r, s), 48 bytes each, big-endian. */
static const unsigned char kat_p384_r[48] = {
0x94,0xED,0xBB,0x92,0xA5,0xEC,0xB8,0xAA,0xD4,0x73,0x6E,0x56,0xC6,0x91,0x91,0x6B,
0x3F,0x88,0x14,0x06,0x66,0xCE,0x9F,0xA7,0x3D,0x64,0xC4,0xEA,0x95,0xAD,0x13,0x3C,
0x81,0xA6,0x48,0x15,0x2E,0x44,0xAC,0xF9,0x6E,0x36,0xDD,0x1E,0x80,0xFA,0xBE,0x46
};
static const unsigned char kat_p384_s[48] = {
0x99,0xEF,0x4A,0xEB,0x15,0xF1,0x78,0xCE,0xA1,0xFE,0x40,0xDB,0x26,0x03,0x13,0x8F,
0x13,0x0E,0x74,0x0A,0x19,0x62,0x45,0x26,0x20,0x3B,0x63,0x51,0xD0,0xA3,0xA9,0x4F,
0xA3,0x29,0xC1,0x45,0x78,0x6E,0x67,0x9E,0x7B,0x82,0xC7,0x1A,0x38,0x62,0x8A,0xC8
};

/* The message that was signed; the device computes SHA-384 over it. */
static const char kat_p384_msg[] = "sample";

#endif /* ECC_P384_KAT_H */
14 changes: 13 additions & 1 deletion embedded/ti-c2000-f28p55x/Header/user_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,18 @@ extern "C" {
/* ------------------------------------------------------------------------- */
#undef HAVE_ECC
#define HAVE_ECC
#undef ECC_USER_CURVES /* build only the curves we name (just P-256) */
#undef ECC_USER_CURVES /* build only the curves named below: P-256, */
/* plus P-384 when WOLF_ECC384 is set */
#define ECC_USER_CURVES
Comment thread
dgarske marked this conversation as resolved.
#undef HAVE_ECC256
#define HAVE_ECC256
#ifdef WOLF_ECC384
/* SECP384R1 alongside P-256 (ECC384=1 build); pairs with SHA-384. */
#undef HAVE_ECC384
#define HAVE_ECC384
#undef WOLFSSL_SP_384
#define WOLFSSL_SP_384
#endif
#undef HAVE_ECC_VERIFY
#define HAVE_ECC_VERIFY
#undef HAVE_ECC_SIGN
Expand All @@ -254,8 +262,12 @@ extern "C" {
#define WOLFSSL_HAVE_SP_ECC
#undef WOLFSSL_SP_NO_MALLOC
#define WOLFSSL_SP_NO_MALLOC
#ifndef WOLF_ECC_FAST
/* Small (looped) SP code by default; ECCFAST=1 picks the windowed SP path,
* which trades flash for roughly ten times the ECDSA throughput. */
#undef WOLFSSL_SP_SMALL
#define WOLFSSL_SP_SMALL
#endif
#undef SP_WORD_SIZE
#define SP_WORD_SIZE 32
/* C28x int is 16-bit (WC_16BIT_CPU) but we use 32-bit SP digits + octet-wise
Expand Down
24 changes: 24 additions & 0 deletions embedded/ti-c2000-f28p55x/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,17 @@ WC_SRCS := \
$(WOLFROOT)/wolfcrypt/src/wc_mldsa.c \
$(WOLFROOT)/wolfcrypt/src/random.c

# ECC384=1 adds SECP384R1, ECCFAST=1 drops WOLFSSL_SP_SMALL, and ECCBENCH=1
# adds the ECDSA / SHA-384 image-verify timing harness. All three imply ECC.
ECC384 ?= 0
ECCFAST ?= 0
ECCBENCH ?= 0
ifneq ($(ECC384)$(ECCFAST)$(ECCBENCH),000)
# override: a command-line ECC=0 alongside one of these would otherwise leave
# WOLF_ECC384 defined with the ECC sources and HAVE_ECC block compiled out.
override ECC := 1
endif

# ECC=1 adds ECDSA/ECDH over SECP256R1 via SP single-precision math.
ECC ?= 0
ifeq ($(ECC),1)
Expand All @@ -102,6 +113,19 @@ ifeq ($(ECC),1)
$(WOLFROOT)/wolfcrypt/src/sp_c32.c
endif

ifeq ($(ECC384),1)
CFLAGS += --define=WOLF_ECC384
endif
ifeq ($(ECCFAST),1)
CFLAGS += --define=WOLF_ECC_FAST
endif
# The timing harness runs on its own: the wolfcrypt test and benchmark are left
# out so the run is short and the heap uncontended.
ifeq ($(ECCBENCH),1)
CFLAGS += --define=WOLF_ECC_BENCH --define=NO_CRYPT_TEST \
--define=NO_CRYPT_BENCHMARK
endif

# MLKEM=1 adds ML-KEM-768 (FIPS 203) via the wolfCrypt C implementation.
MLKEM ?= 0
ifeq ($(MLKEM),1)
Expand Down
20 changes: 20 additions & 0 deletions embedded/ti-c2000-f28p55x/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ Each is `make <NAME>=1` (default 0 unless noted), additive on top of the default
| Option | Adds |
|---|---|
| `ECC=1` | ECDSA/ECDH over SECP256R1 (SP math) |
| `ECC384=1` | Adds SECP384R1 (`HAVE_ECC384` + `WOLFSSL_SP_384`) |
| `ECCFAST=1` | Drops `WOLFSSL_SP_SMALL` for the windowed SP path (~10x faster ECDSA, +30 KB flash for P-256). Needs a wolfSSL with the SP scalar-recode fix for 16-bit bytes; older trees fail to build with `identifier "int8_t" is undefined`. |
| `ECCBENCH=1` | ECDSA sign/verify, ECDH and SHA-256/384 image-hash timings instead of the test/benchmark harness |
| `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) |
Expand Down Expand Up @@ -136,6 +139,23 @@ Measured at 150 MHz (SHA-256 Hash-DRBG via `WOLFSSL_GENSEED_FORTEST`; build with
| SHAKE128 / SHAKE256 | ~319 / 264 KiB/s |
| RNG (Hash-DRBG) | ~122 KiB/s |

ECDSA and ECDH (@150 MHz, `ECC_TIMING_RESISTANT` on). The default `WOLFSSL_SP_SMALL` build keeps SP code small at a large cost in speed; `ECCFAST=1` selects the windowed SP path:

| Operation | Default SP | Windowed SP (`ECCFAST=1`) |
|---|---|---|
| ECDSA P-256 sign | ~350 ms/op | 46 ms/op |
| ECDSA P-256 verify | ~635 ms/op | 64 ms/op |
| ECDH P-256 agree | ~308 ms/op | 57 ms/op |
| ECDSA P-384 sign | ~1280 ms/op | 98 ms/op |
| ECDSA P-384 verify | ~2260 ms/op | 183 ms/op |
| ECDH P-384 agree | ~1108 ms/op | 163 ms/op |

The default-SP column varies by a few percent run to run, since each run makes a fresh key and ECDSA verify is a public operation with no timing-resistance constraint.

The image hash walks a 4 KiB flash-resident block repeatedly to reach 128 KiB. That is equivalent to one sweep over a 128 KiB array on this part, which has no data cache in front of flash: measured on hardware, a true single pass took 0.740 s against 0.736 s for the repeated block. The small block is the default because a genuine 128 KiB octet array costs 256 KB of flash, one octet per 16-bit cell, and fills a whole flash bank. Build with `-DWOLF_IMG_BLK=131072` in `EXTRA_CFLAGS` for the single sweep.

For a secure-boot style check of a 128 KB flash image, the hash dominates once the windowed path is in use: SHA-384 over the image takes 0.75 s, giving 0.81 s for SHA-384 plus a P-256 verify and 0.93 s with P-384 (1.39 s and 2.96 s respectively on the default SP path). SHA-256 over the same image takes 0.46 s. Building with `EXTRA_CFLAGS="--opt_level=3 --opt_for_speed=5"` takes SHA-384 down to 0.64 s for about 7 KB more flash, but does not move the ECC math. The windowed path itself costs about 30 KB of flash for P-256 alone, 82 KB for both curves.

ML-DSA-87 (asymmetric, @150 MHz): verify 244 ms/op default, **189 ms/op** with `FASTVERIFY=1` and `--opt_level=3 --opt_for_speed=5` (23% faster, RAM 10.7 -> 23.9 KB, zero heap either way); keygen and signing also run (`SIGN=1`). ML-DSA-87 verify memory: ~10.7 KB total (key/workspace struct + ~2 KB stack, zero heap) with `WOLFSSL_MLDSA_VERIFY_SMALLEST_MEM` + `WOLFSSL_MLDSA_ASSIGN_KEY`.

## Memory notes
Expand Down
Loading
Loading