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
2 changes: 1 addition & 1 deletion .github/workflows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ full M33MU emulator matrix, which runs on every pull request (and nightly).

| Tier | Trigger | Purpose |
|------|---------|---------|
| **Fast (per-PR)** | every PR; push to master/main/dev/churn | host unit suites (one check each), Arm PSA-FF conformance, cross-compile, compiler matrix, sanitizers, valgrind, integrations, core/port split guard |
| **Fast (per-PR)** | every PR; push to master/main/dev/churn | host unit suites, ISO C99, house style, bare-scope scan, Arm PSA-FF conformance, cross-compile, compiler matrix, sanitizers, valgrind, integrations, core/port split guard |
| **M33MU matrix** | every PR; push to master/main/wolfTrust-dev; `cron: 0 8 * * *`; `workflow_dispatch` | full M33MU emulator matrix (see below) |

The M33MU workflow (`m33mu.yml`) runs the full matrix on every pull request,
Expand Down
34 changes: 34 additions & 0 deletions .github/workflows/c99-compliance.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: C99 Compliance

on:
push:
branches: [master, main, 'release/**', wolfTrust-dev, wolftfm-l3, wolfpsa-v5.9.1-ci]
pull_request:
workflow_dispatch:
workflow_call:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
c99-check:
name: ISO C99 (${{ matrix.cc }})
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
cc: [gcc, clang]
steps:
- uses: actions/checkout@v4
- name: Initialize test dependencies
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
git config --global url."https://github.com/".insteadOf git@github.com:
git submodule update --init --recursive
- name: Build and run existing host suites as ISO C99
run: make c99-check CC=${{ matrix.cc }}
21 changes: 21 additions & 0 deletions .github/workflows/empty-brace-scan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Empty Brace Scope Scan

on:
push:
branches: [master, main, 'release/**', wolfTrust-dev, wolftfm-l3, wolfpsa-v5.9.1-ci]
pull_request:
workflow_dispatch:
workflow_call:

permissions:
contents: read

jobs:
empty-brace-scan:
name: Empty Brace Scope Scan
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- name: Check for bare C scope blocks
run: python3 scripts/check-empty-brace-scopes.py
21 changes: 21 additions & 0 deletions .github/workflows/house-style.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: House Style

on:
push:
branches: [master, main, 'release/**', wolfTrust-dev, wolftfm-l3, wolfpsa-v5.9.1-ci]
pull_request:
workflow_dispatch:
workflow_call:

permissions:
contents: read

jobs:
house-style:
name: C house-style conventions
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- name: Check structured control flow and source conventions
run: sh scripts/check_house_style.sh
9 changes: 9 additions & 0 deletions .github/workflows/nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ permissions:
issues: write

jobs:
c99:
uses: ./.github/workflows/c99-compliance.yml

house-style:
uses: ./.github/workflows/house-style.yml

empty-brace-scan:
uses: ./.github/workflows/empty-brace-scan.yml

unit:
uses: ./.github/workflows/unit-tests.yml

Expand Down
21 changes: 20 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ include mk/common.mk

.DEFAULT_GOAL := all

.PHONY: all secure-image size-report test test-conformance test-target test-hardware fetch-psa-ff-tests \
.PHONY: all secure-image size-report test c99-check test-conformance test-target test-hardware fetch-psa-ff-tests \
clean firmware-stm32h563 run-stm32h563 run-stm32h563-tui run-stm32h563-uarts \
test-domain-host test-domain-compilers test-domain-sanitize \
test-domain-valgrind test-manifest-host test-manifest-compilers \
Expand All @@ -42,6 +42,25 @@ all: $(ARCH_DEFAULT_GOALS)
test:
@$(MAKE) --no-print-directory -C tests/host test

C99_CFLAGS := -std=c99 -pedantic-errors -Werror=vla \
-D_POSIX_C_SOURCE=200809L
C99_CC_VERSION := $(shell $(CC) --version 2>/dev/null)
ifneq ($(findstring clang,$(C99_CC_VERSION)),)
C99_CFLAGS += -Wno-newline-eof \
--system-header-prefix=wolfssl/ \
--system-header-prefix=wolfhsm/
else
C99_CFLAGS += -isystem $(abspath $(WOLFSSL_DIR)) \
-isystem $(abspath $(WOLFHSM_DIR))
endif

c99-check:
@CC="$(CC)" sh tests/c99/check.sh
@$(MAKE) --no-print-directory -C tests/host test \
TEST_KIND=c99 CC="$(CC)" \
BUILD_ROOT="$(abspath $(BUILD_DIR))/c99" \
EXTRA_CFLAGS="$(C99_CFLAGS)"

# FF-M target-only scenarios (partition restart, cross-domain isolation) that
# need a real Cortex-M execution model. Separate from `make test` (host-only),
# like `make test-conformance`. Auto-detect an M33MU emulator (or set
Expand Down
40 changes: 40 additions & 0 deletions docs/Coding-Standard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# C Coding Standard

wolfTrust adheres to the wolfSSL coding standards and targets ISO C99, with
project-specific no-`goto` and no-standalone-scope rules. The aim is to keep
the code straightforward to assess in a future MISRA C:2023 or DO-178 process.
These checks improve readiness; they are not a claim of MISRA compliance or
certification evidence.

## Required rules

- Compile project C as ISO C99. Variable-length arrays are prohibited.
- Do not use `goto`. Use structured control flow and status-gated fallthrough
cleanup.
- Do not use standalone brace blocks solely to shorten a variable's lifetime.
- Use C comments (`/* ... */`), spaces in core source, and no trailing
whitespace. Preserve existing section-banner style when editing nearby code.
- Explicitly erase sensitive buffers that must be cleared. Existing secure-
erasure routines use volatile byte writes; record that approach as a
deviation in any formal MISRA compliance plan.
- Use `WT_STATIC_ASSERT()` for file-scope compile-time checks; `_Static_assert`
is C11 and is not permitted.

Runnable tests follow the no-`goto` and no-standalone-scope rules. Vendored
submodules keep their upstream coding standards. The pinned wolfHSM callback
ABI requires anonymous aggregate support in dependency headers; formal
qualification must record that boundary as a dependency deviation. The strict
C99 host gate does not compile ARM-only source; target inline assembly and
compiler intrinsics require separate platform qualification.

## Automated checks

- `sh scripts/check_house_style.sh`
- `python3 scripts/check-empty-brace-scopes.py`
- `make c99-check CC=clang` or `make c99-check CC=gcc`

The C99 check first compiles a valid C99 probe and verifies that the compiler
rejects C11-only syntax and variable-length arrays. It then builds and runs
the existing host suites with strict C99 flags.

The matching GitHub Actions workflows run these gates on every pull request.
1 change: 1 addition & 0 deletions docs/_Sidebar.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
- [[Porting]]
- [[Building]]
- [[Testing]]
- [[Coding Standard]]
- [[Project Structure]]
- [[STM32H5 Guide]]
31 changes: 31 additions & 0 deletions include/wolftrust/static_assert.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* static_assert.h
*
* Copyright (C) 2026 wolfSSL Inc.
*
* This file is part of wolfTrust.
*
* wolfTrust 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.
*
* wolfTrust 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, see <https://www.gnu.org/licenses/>.
*/

#ifndef WOLFTRUST_STATIC_ASSERT_H
#define WOLFTRUST_STATIC_ASSERT_H

/* File-scope compile-time assertion that remains valid under ISO C99. */
#define WT_STATIC_ASSERT_JOIN_INNER(a, b) a##b
#define WT_STATIC_ASSERT_JOIN(a, b) WT_STATIC_ASSERT_JOIN_INNER(a, b)
#define WT_STATIC_ASSERT(condition, message) \
typedef char WT_STATIC_ASSERT_JOIN(wt_static_assert_, __LINE__) \
[(condition) ? 1 : -1]

#endif /* WOLFTRUST_STATIC_ASSERT_H */
2 changes: 1 addition & 1 deletion mk/common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ SECURE_CFLAGS_COSE := -I$(WOLFCOSE_DIR)/include \
-DWOLFCOSE_ENABLE_EAT_PSA_SIGN1_ISSUE
endif

SECURE_CFLAGS := $(CPU_FLAGS) -ffreestanding -fno-builtin -nostdlib -Os -g \
SECURE_CFLAGS := $(CPU_FLAGS) -std=c99 -ffreestanding -fno-builtin -nostdlib -Os -g \
-ffunction-sections -fdata-sections -Wall -Wextra \
-I$(ROOT)/include -I$(PORT_DIR) \
-DWT_TIMESLICE_MS=$(WT_TIMESLICE_MS) \
Expand Down
66 changes: 66 additions & 0 deletions scripts/check-c-comments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env python3
"""Find C++ comments in tracked C files without mistaking URLs for comments."""

import subprocess
import sys
from pathlib import Path


def scan_line(line, in_block, quote):
index = 0
while index < len(line):
if in_block:
end = line.find("*/", index)
if end < 0:
return False, True, quote
in_block = False
index = end + 2
elif quote:
if line[index] == "\\":
index += 2
elif line[index] == quote:
quote = None
index += 1
else:
index += 1
elif line.startswith("/*", index):
in_block = True
index += 2
elif line.startswith("//", index):
return True, in_block, quote
elif line[index] in ('"', "'"):
quote = line[index]
index += 1
else:
index += 1

if quote and not line.endswith("\\"):
quote = None
return False, in_block, quote


def main():
paths = subprocess.check_output(
["git", "ls-files", "-z", "--", "*.c", "*.h"]
).split(b"\0")
found = False
for raw_path in filter(None, paths):
path = Path(raw_path.decode(sys.getfilesystemencoding()))
in_block = False
quote = None
for number, line in enumerate(
path.read_text(encoding="utf-8", errors="replace").splitlines(), 1
):
comment, in_block, quote = scan_line(line, in_block, quote)
if comment:
print(f"{path}:{number}: C++ comment")
found = True
return 1 if found else 0


if __name__ == "__main__":
try:
raise SystemExit(main())
except (OSError, subprocess.CalledProcessError) as error:
print(error, file=sys.stderr)
raise SystemExit(2)
Loading
Loading