Skip to content
Draft
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
78 changes: 78 additions & 0 deletions .github/workflows/ti-c2000-compile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: TI C2000 (C28x) compile-only

# Compile-guard for the TI C2000 C28x port (CHAR_BIT == 16). It builds the
# wolfCrypt subset that carries the CHAR_BIT != 8 gated fixes with the TI cl2000
# code generation tools - no linking, no C2000Ware, no hardware. Purpose: catch
# compile regressions in the octet/SP/ML-DSA gated paths. On-target run-tests
# live on a hardware-in-the-loop runner (there is no public C28x simulator).

# START OF COMMON SECTION
on:
# Only build when something that can affect the C28x compile changes, so the
# job (and the CGT it pulls) does not burn runner minutes on unrelated PRs.
push:
branches: [ 'master', 'main', 'release/**' ]
paths:
- 'wolfcrypt/src/**'
- 'wolfssl/wolfcrypt/**'
- 'scripts/ti-c2000/**'
- '.github/workflows/ti-c2000-compile.yml'
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
branches: [ '*' ]
paths:
- 'wolfcrypt/src/**'
- 'wolfssl/wolfcrypt/**'
- 'scripts/ti-c2000/**'
- '.github/workflows/ti-c2000-compile.yml'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# END OF COMMON SECTION

jobs:
ti_c2000_compile:
name: cl2000 compile-only
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.draft == false }}
runs-on: ubuntu-22.04
timeout-minutes: 20
env:
# TI C2000 code generation tools. The CGT is a free download from TI.
# Update CGT_VER / CGT_URL when bumping the toolchain. If the TI URL
# starts requiring a click-through, host the installer as a repo/org
# cache artifact and point CGT_URL at it (the cache step below makes the
# download a once-per-version cost).
CGT_VER: "22.6.2.LTS"
CGT_URL: "https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-LP0nQ4O8eX/22.6.2.LTS/ti_cgt_c2000_22.6.2.LTS_linux-x64_installer.bin"
CGT_DIR: "${{ github.workspace }}/ti-cgt-c2000"
steps:
- uses: actions/checkout@v4
name: Checkout wolfSSL

- name: Cache TI C2000 CGT
id: cgt-cache
uses: actions/cache@v4
with:
path: ${{ env.CGT_DIR }}
key: ti-cgt-c2000-${{ env.CGT_VER }}

- name: Download + install TI C2000 CGT
if: steps.cgt-cache.outputs.cache-hit != 'true'
run: |
set -e
curl -fsSL "$CGT_URL" -o /tmp/cgt.bin
chmod +x /tmp/cgt.bin
/tmp/cgt.bin --mode unattended --prefix "$CGT_DIR"

- name: Locate cl2000
id: find-cl
run: |
CL=$(find "$CGT_DIR" -type f -name cl2000 | head -1)
test -n "$CL" || { echo "cl2000 not found under $CGT_DIR"; exit 1; }
echo "cgt_root=$(dirname "$(dirname "$CL")")" >> "$GITHUB_OUTPUT"

- name: Compile-only guard
run: |
CGT_ROOT="${{ steps.find-cl.outputs.cgt_root }}" \
scripts/ti-c2000/compile.sh
7 changes: 7 additions & 0 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,7 @@ WOLFSSL_CLANG_TIDY
WOLFSSL_CLIENT_EXAMPLE
WOLFSSL_CONTIKI
WOLFSSL_CRL_ALLOW_MISSING_CDP
WOLFSSL_DILITHIUM_VERIFY_SMALLEST_MEM
WOLFSSL_DISABLE_EARLY_SANITY_CHECKS
WOLFSSL_DRBG_SHA256
WOLFSSL_DTLS13_ECHO_LEGACY_SESSION_ID
Expand Down Expand Up @@ -1115,6 +1116,12 @@ __SUNPRO_CC
__SVR4
__TASKING__
__TI_COMPILER_VERSION__
__TMS320C2000__
__TMS320C2800__
__TMS320C28XX__
__TMS320C54X__
__TMS320C5500__
__TMS320C55X__
__TURBOC__
__UNIX__
__USE_GNU
Expand Down
65 changes: 65 additions & 0 deletions scripts/ti-c2000/compile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/bin/sh
# compile.sh - compile-only guard for the TI C2000 (C28x, CHAR_BIT==16) port.
#
# Builds the wolfCrypt subset that compiles under CHAR_BIT==16 with the TI cl2000
# code generation tools, using scripts/ti-c2000/user_settings.h. No linking, no
# C2000Ware, no hardware: this only catches compile regressions in the
# CHAR_BIT != 8 gated code paths (SHA-2/3/SHAKE, ML-DSA-87 verify, SP-ECC).
#
# Usage:
# CGT_ROOT=/path/to/ti-cgt-c2000_xx.y.z scripts/ti-c2000/compile.sh
#
# CGT_ROOT must point at a TI C2000 codegen install (the dir containing
# bin/cl2000). The CGT is a free download from TI; in CI it is fetched/cached
# by .github/workflows/ti-c2000-compile.yml.

set -e

: "${CGT_ROOT:?set CGT_ROOT to the ti-cgt-c2000 install (dir with bin/cl2000)}"

# Repo root = two levels up from this script.
SELF_DIR=$(cd "$(dirname "$0")" && pwd)
WOLFROOT=$(cd "$SELF_DIR/../.." && pwd)
CL="$CGT_ROOT/bin/cl2000"

if [ ! -x "$CL" ]; then
echo "ERROR: cl2000 not found/executable at $CL" >&2
exit 2
fi

OUT=$(mktemp -d)
trap 'rm -rf "$OUT"' EXIT

INCS="-I$CGT_ROOT/include -I$WOLFROOT -I$SELF_DIR"
CFLAGS="-v28 --abi=eabi --float_support=fpu32 --tmu_support=tmu1 -O2 \
--define=WOLFSSL_USER_SETTINGS --display_error_number --diag_warning=225"

# wolfCrypt sources to compile-guard under CHAR_BIT==16. This is the set that
# carries the CHAR_BIT != 8 gated fixes (plus their direct deps) - the
# regression surface for this port. hash.c (an unmodified dispatch wrapper) is
# intentionally omitted: its wc_OidGetHash() OID switch needs the fuller ASN/OID
# config of a real build to avoid a 16-bit-int case-label fold, and it is
# covered by the on-target example build, not by this minimal guard.
SRCS="error wc_port memory logging misc coding \
sha256 sha512 sha3 wc_mldsa random ecc sp_int sp_c32"

rc=0
for s in $SRCS; do
printf 'CC %s.c ... ' "$s"
if "$CL" $CFLAGS $INCS --compile_only --skip_assembler \
--asm_directory="$OUT" --obj_directory="$OUT" \
"$WOLFROOT/wolfcrypt/src/$s.c" > "$OUT/$s.log" 2>&1; then
echo "ok"
else
echo "FAIL"
cat "$OUT/$s.log"
rc=1
fi
done

if [ "$rc" -eq 0 ]; then
echo "TI C2000 compile-only guard: PASS"
else
echo "TI C2000 compile-only guard: FAIL" >&2
fi
exit "$rc"
84 changes: 84 additions & 0 deletions scripts/ti-c2000/user_settings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* user_settings.h - minimal wolfCrypt config for the TI C2000 (C28x,
* CHAR_BIT==16) compile-only CI guard.
*
* This is NOT a board config: it has no BSP/device dependencies. Its only job
* is to enable the subset of wolfCrypt that exercises the CHAR_BIT != 8 gated
* code paths (SHA-2/3/SHAKE, ML-DSA-87 verify, ECDSA/ECDH P-256 via SP math)
* so that scripts/ti-c2000/compile.sh can compile them with cl2000 and catch
* regressions. cl2000 predefines __TMS320C28XX__, so types.h auto-enables
* WOLFSSL_WIDE_BYTE; we do not set it here.
*/
#ifndef TI_C2000_CI_USER_SETTINGS_H
#define TI_C2000_CI_USER_SETTINGS_H

#define WOLFCRYPT_ONLY /* crypto only - no TLS (no MD5/SHA1 dep) */
#define WOLFSSL_GENERAL_ALIGNMENT 2
#define HAVE_LIMITS_H
#define WOLFSSL_NO_ASM
#define NO_INLINE
#define SINGLE_THREADED
#define NO_FILESYSTEM
#define NO_WOLFSSL_DIR
#define NO_MAIN_DRIVER
#define NO_DEV_RANDOM
#define WOLFSSL_IGNORE_FILE_WARN
#define BENCH_EMBEDDED
#define NO_WOLFSSL_MEMORY
#define WOLFSSL_GENSEED_FORTEST /* dev-only seed; no TRNG on this part */

/* Hashes */
#define WOLFSSL_SHA512
#define WOLFSSL_SHA384
#define WOLFSSL_SHA3
#define WOLFSSL_SHAKE128
#define WOLFSSL_SHAKE256

/* ML-DSA-87 verify (smallest-mem streaming verifier) */
#define WOLFSSL_HAVE_MLDSA
#define WOLFSSL_NO_ML_DSA_44
#define WOLFSSL_NO_ML_DSA_65
#define WOLFSSL_MLDSA_NO_ASN1
#define WOLFSSL_MLDSA_VERIFY_ONLY
#define WOLFSSL_MLDSA_VERIFY_SMALL_MEM
#define WOLFSSL_MLDSA_VERIFY_NO_MALLOC
#define WOLFSSL_MLDSA_VERIFY_SMALLEST_MEM
#undef WOLFSSL_MLDSA_ALIGNMENT
#define WOLFSSL_MLDSA_ALIGNMENT 16
#define WOLFSSL_SMALL_STACK

/* ECDSA / ECDH P-256 via SP single-precision math (sp_c32.c) */
#define HAVE_ECC
#define ECC_USER_CURVES
#define HAVE_ECC256
#define HAVE_ECC_VERIFY
#define HAVE_ECC_SIGN
#define HAVE_ECC_DHE
#define ECC_TIMING_RESISTANT
#define WOLFSSL_SP_MATH
#define WOLFSSL_HAVE_SP_ECC
#define WOLFSSL_SP_NO_MALLOC
#define WOLFSSL_SP_SMALL
#define SP_WORD_SIZE 32
#define WOLFSSL_SP_ALLOW_16BIT_CPU

/* Off: anything that pulls in big-int/ASN/symmetric not under test here. */
#define NO_RSA
#define NO_DH
#define NO_DSA
#define NO_ASN
#define NO_CERTS
#define NO_PWDBASED
#define NO_PKCS7
#define NO_PKCS12
#define NO_SIG_WRAPPER
#define NO_AES
#define NO_DES3
#define NO_RC4
#define NO_MD4
#define NO_MD5
#define NO_SHA
#define NO_HMAC
#define NO_ASN_TIME
#define WOLFSSL_USER_CURRTIME

#endif /* TI_C2000_CI_USER_SETTINGS_H */
35 changes: 32 additions & 3 deletions wolfcrypt/benchmark/benchmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -2357,6 +2357,15 @@ static const char* bench_result_words2[][6] = {

static int numBlocks = NUM_BLOCKS;
static word32 bench_size = BENCH_SIZE;
#ifdef WOLFSSL_NO_MALLOC
/* No heap: use file-scope static buffers for the core bench buffers.
* Sized to hold bench_buf_size (BENCH_SIZE + BENCH_CIPHER_ADD rounded up
* to the 16-byte AES block size) plus the +16 slack used at the alloc
* site, plus 64 bytes so the buffer can be 64-byte aligned at runtime. */
#define BENCH_MAX_PAD (BENCH_CIPHER_ADD + 16 + 64)
static THREAD_LS_T XGEN_ALIGN byte bench_plain_buf[BENCH_SIZE + BENCH_MAX_PAD];
static THREAD_LS_T XGEN_ALIGN byte bench_cipher_buf[BENCH_SIZE + BENCH_MAX_PAD];
#endif
static int base2 = 1;
static int digest_stream = 1;
#ifndef NO_HMAC
Expand Down Expand Up @@ -3805,7 +3814,23 @@ static void* benchmarks_do(void* args)
if (bench_buf_size % 16)
bench_buf_size += 16 - (bench_buf_size % 16);

#ifdef WOLFSSL_AFALG_XILINX_AES
#ifdef WOLFSSL_NO_MALLOC
/* No heap: point at the file-scope static buffers. bench_size can be
* raised at runtime (benchmark_configure(), the -base16/auth size paths,
* or hash-file input), so confirm the requested size still fits the fixed
* static capacity before using them - otherwise the later XMEMSET / crypto
* writes would run past the end of the buffer. */
if ((unsigned long)bench_buf_size + 16UL >
(unsigned long)sizeof(bench_plain_buf)) {
printf("%sBenchmark size %lu exceeds WOLFSSL_NO_MALLOC static buffer "
"(%lu); rebuild with a larger BENCH_SIZE\n", err_prefix,
(unsigned long)bench_buf_size,
(unsigned long)sizeof(bench_plain_buf));
goto exit;
}
bench_plain = bench_plain_buf;
bench_cipher = bench_cipher_buf;
#elif defined(WOLFSSL_AFALG_XILINX_AES)
Comment thread
dgarske marked this conversation as resolved.
bench_plain = (byte*)aligned_alloc(64, (size_t)bench_buf_size + 16); /* native heap */
bench_cipher = (byte*)aligned_alloc(64, (size_t)bench_buf_size + 16); /* native heap */
#else
Expand Down Expand Up @@ -3918,7 +3943,8 @@ static void* benchmarks_do(void* args)
}
#endif

#if defined(WOLFSSL_ASYNC_CRYPT) || defined(HAVE_INTEL_QA_SYNC)
#if (defined(WOLFSSL_ASYNC_CRYPT) || defined(HAVE_INTEL_QA_SYNC)) && \
!defined(WOLFSSL_NO_MALLOC)
bench_key = (byte*)XMALLOC(sizeof(bench_key_buf),
HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
bench_iv = (byte*)XMALLOC(sizeof(bench_iv_buf),
Expand Down Expand Up @@ -4744,9 +4770,12 @@ static void* benchmarks_do(void* args)

exit:
/* free benchmark buffers */
#ifndef WOLFSSL_NO_MALLOC
/* under WOLFSSL_NO_MALLOC these point at file-scope static buffers */
XFREE(bench_plain, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
XFREE(bench_cipher, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
#ifdef WOLFSSL_ASYNC_CRYPT
#endif
#if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WOLFSSL_NO_MALLOC)
XFREE(bench_key, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
XFREE(bench_iv, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT);
#endif
Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/src/coding.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ static WC_INLINE byte Base64_Char2Val_CT(byte c)
v |= ((slashStart >> 8) ^ (slashEnd >> 8)) & (slashStart + 63 + 1);
v |= ((plusStart >> 8) ^ (plusEnd >> 8)) & (plusStart + 62 + 1);

return (byte)(v - 1);
return WC_OCTET(v - 1);
}

#ifndef BASE64_NO_TABLE
Expand Down
Loading