From f8aca7a1206b2e7830e5d3f4063e63faece3a7d0 Mon Sep 17 00:00:00 2001 From: aidan garske Date: Mon, 1 Jun 2026 22:51:20 -0700 Subject: [PATCH] Make wolfCOSE build and CI ISO C99 conformant Switch the Makefile and every CI workflow from -std=c11 to -std=c99 and add a c99-check gate (-pedantic-errors -Werror over all sources on gcc and clang, default and WOLFCOSE_FLOAT feature sets) plus a C99 Compliance workflow, so the C99 claim is enforced rather than asserted. Two issues the C99 switch surfaced, fixed here: - Define HAVE_ANONYMOUS_INLINE_AGGREGATES=1 on every wolfCOSE compile. -std=c99 otherwise disables it (wolfSSL gates it on __STDC_VERSION__ >= 201101L), which shrinks WC_RNG. wolfSSL itself builds with the compiler default (gnu11) where the macro is on, so against a dilithium-enabled wolfSSL its WC_RNG is 8 bytes larger than wolfCOSE -std=c99 expects; wolfSSL writes past wolfCOSE's stack WC_RNG and corrupts the RNG, breaking every COSE ECDSA verify. EdDSA (deterministic) and AES-GCM/HMAC, which draw no nonce, were unaffected. Stable wolfSSL is identical under c99/c11, so only master failed. - Key the master wolfSSL cache on its commit SHA. The workflows cached master under a static key and only rebuilt on a miss, freezing one master snapshot indefinitely. Pinned -stable caches keep their immutable keys. Also fix a uint64_t/size_t mismatch in tests/test_cose.c exposed by the gate: wc_CBOR_DecodeArrayStart takes size_t*, and the same variable doubled as a uint64_t CBOR tag; split into a size_t count and a uint64_t tag. --- .github/workflows/build-test.yml | 22 +++++--- .github/workflows/c99-compliance.yml | 61 +++++++++++++++++++++++ .github/workflows/comprehensive-tests.yml | 9 ++-- .github/workflows/coverage.yml | 7 ++- .github/workflows/coverity.yml | 7 ++- .github/workflows/examples.yml | 11 ++-- .github/workflows/minimal-build.yml | 12 +++-- .github/workflows/misra-2012.yml | 5 +- .github/workflows/misra-2023.yml | 16 ++++-- .github/workflows/multi-compiler.yml | 9 ++-- .github/workflows/sanitizer.yml | 14 ++++-- .github/workflows/scenarios.yml | 9 ++-- .github/workflows/static-analysis.yml | 19 +++++-- .github/workflows/wolfssl-versions.yml | 6 +-- Makefile | 35 +++++++++++-- tests/test_cose.c | 5 +- 16 files changed, 195 insertions(+), 52 deletions(-) create mode 100644 .github/workflows/c99-compliance.yml diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 172b2ca..b612970 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -33,12 +33,16 @@ jobs: if: runner.os == 'macOS' run: brew install autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" + - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-${{ matrix.os }}-v3-full + key: wolfssl-${{ matrix.os }}-master-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -61,7 +65,7 @@ jobs: - name: Build wolfCOSE run: | export WOLFSSL_DIR=$HOME/wolfssl-install - make CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -I$WOLFSSL_DIR/include" \ + make CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Run unit tests @@ -69,7 +73,7 @@ jobs: export WOLFSSL_DIR=$HOME/wolfssl-install export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib export DYLD_LIBRARY_PATH=$WOLFSSL_DIR/lib - make test CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -I$WOLFSSL_DIR/include" \ + make test CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Run tool round-trip test @@ -77,7 +81,7 @@ jobs: export WOLFSSL_DIR=$HOME/wolfssl-install export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib export DYLD_LIBRARY_PATH=$WOLFSSL_DIR/lib - make tool-test CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -I$WOLFSSL_DIR/include" \ + make tool-test CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" coverage: @@ -92,12 +96,16 @@ jobs: sudo apt-get update sudo apt-get install -y autoconf automake libtool lcov + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" + - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-ubuntu-latest-coverage-v3-full + key: wolfssl-ubuntu-latest-coverage-master-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -121,14 +129,14 @@ jobs: run: | export WOLFSSL_DIR=$HOME/wolfssl-install make clean - make CFLAGS="-std=c11 -Os --coverage -I./include -I$WOLFSSL_DIR/include" \ + make CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os --coverage -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="--coverage -L$WOLFSSL_DIR/lib -lwolfssl" - name: Run tests with coverage run: | export WOLFSSL_DIR=$HOME/wolfssl-install export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib - make test CFLAGS="-std=c11 -Os --coverage -I./include -I$WOLFSSL_DIR/include" \ + make test CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os --coverage -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="--coverage -L$WOLFSSL_DIR/lib -lwolfssl" - name: Generate coverage report diff --git a/.github/workflows/c99-compliance.yml b/.github/workflows/c99-compliance.yml new file mode 100644 index 0000000..3100dd3 --- /dev/null +++ b/.github/workflows/c99-compliance.yml @@ -0,0 +1,61 @@ +name: C99 Compliance + +on: + push: + branches: [ 'main', 'release/**' ] + pull_request: + branches: [ '*' ] + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + c99-check: + name: ISO C99 conformance (${{ matrix.cc }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + cc: [gcc, clang] + + steps: + - uses: actions/checkout@v4 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y autoconf automake libtool + + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" + - name: Cache wolfSSL + id: cache-wolfssl + uses: actions/cache@v4 + with: + path: ~/wolfssl-install + key: wolfssl-ubuntu-latest-v3-full-${{ steps.wolfssl-rev.outputs.sha }} + + - name: Build wolfSSL + if: steps.cache-wolfssl.outputs.cache-hit != 'true' + run: | + cd ~ + git clone --depth 1 https://github.com/wolfSSL/wolfssl.git + cd wolfssl + ./autogen.sh + ./configure --enable-ecc --enable-ed25519 --enable-ed448 \ + --enable-curve25519 --enable-curve448 \ + --enable-aesgcm --enable-aesccm \ + --enable-sha384 --enable-sha512 \ + --enable-keygen --enable-hkdf --enable-aeskeywrap \ + --enable-chacha --enable-poly1305 \ + --enable-dilithium --enable-rsapss \ + --prefix=$HOME/wolfssl-install + make -j$(nproc) + make install + + - name: Strict C99 conformance gate + run: | + make c99-check CC=${{ matrix.cc }} WOLFSSL_INC=$HOME/wolfssl-install/include diff --git a/.github/workflows/comprehensive-tests.yml b/.github/workflows/comprehensive-tests.yml index f79b970..66fb8d0 100644 --- a/.github/workflows/comprehensive-tests.yml +++ b/.github/workflows/comprehensive-tests.yml @@ -24,12 +24,15 @@ jobs: sudo apt-get update sudo apt-get install -y autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-ubuntu-latest-comprehensive-v1 + key: wolfssl-ubuntu-latest-comprehensive-v1-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -50,14 +53,14 @@ jobs: - name: Build wolfCOSE run: | export WOLFSSL_DIR=$HOME/wolfssl-install - make CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -I$WOLFSSL_DIR/include" \ + make CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Run comprehensive tests run: | export WOLFSSL_DIR=$HOME/wolfssl-install export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib - make comprehensive CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -I$WOLFSSL_DIR/include" \ + make comprehensive CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Test Summary diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index c86d5cd..29dfc1d 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -23,12 +23,15 @@ jobs: sudo apt-get update sudo apt-get install -y autoconf automake libtool lcov + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-ubuntu-latest-v3 + key: wolfssl-ubuntu-latest-v3-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -52,7 +55,7 @@ jobs: export WOLFSSL_DIR=$HOME/wolfssl-install export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib make coverage-force-failure CC=gcc \ - CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -I$WOLFSSL_DIR/include" \ + CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Check coverage thresholds diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 013ae84..c922aa3 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -25,12 +25,15 @@ jobs: sudo apt-get update sudo apt-get install -y autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-coverity-v3 + key: wolfssl-coverity-v3-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -55,4 +58,4 @@ jobs: token: ${{ secrets.COVERITY_SCAN_TOKEN }} email: ${{ secrets.COVERITY_SCAN_EMAIL }} command: | - make CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -I$HOME/wolfssl-install/include" LDFLAGS="-L$HOME/wolfssl-install/lib -lwolfssl" + make CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $HOME/wolfssl-install/include" LDFLAGS="-L$HOME/wolfssl-install/lib -lwolfssl" diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 962355e..1e2de95 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -24,12 +24,15 @@ jobs: sudo apt-get update sudo apt-get install -y autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-ubuntu-latest-v3 + key: wolfssl-ubuntu-latest-v3-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -50,21 +53,21 @@ jobs: - name: Build wolfCOSE run: | export WOLFSSL_DIR=$HOME/wolfssl-install - make CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -I$WOLFSSL_DIR/include" \ + make CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Run lifecycle demo (all algorithms) run: | export WOLFSSL_DIR=$HOME/wolfssl-install export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib - make demo CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -I$WOLFSSL_DIR/include" \ + make demo CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Run tool round-trip test (all algorithms) run: | export WOLFSSL_DIR=$HOME/wolfssl-install export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib - make tool-test CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -I$WOLFSSL_DIR/include" \ + make tool-test CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Binary size audit diff --git a/.github/workflows/minimal-build.yml b/.github/workflows/minimal-build.yml index 6838774..5a406c8 100644 --- a/.github/workflows/minimal-build.yml +++ b/.github/workflows/minimal-build.yml @@ -55,12 +55,16 @@ jobs: sudo apt-get update sudo apt-get install -y autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" + - name: Cache wolfSSL (${{ matrix.name }}) id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-minimal - key: ${{ matrix.cache_key }} + key: ${{ matrix.cache_key }}-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL (${{ matrix.name }}) if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -77,19 +81,19 @@ jobs: - name: Build wolfCOSE run: | export WOLFSSL_DIR=$HOME/wolfssl-minimal - make CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -I$WOLFSSL_DIR/include" \ + make CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Run unit tests run: | export WOLFSSL_DIR=$HOME/wolfssl-minimal export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib - make test CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -I$WOLFSSL_DIR/include" \ + make test CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Run tool round-trip test run: | export WOLFSSL_DIR=$HOME/wolfssl-minimal export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib - make tool-test CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -I$WOLFSSL_DIR/include" \ + make tool-test CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" diff --git a/.github/workflows/misra-2012.yml b/.github/workflows/misra-2012.yml index 8677f80..4dca512 100644 --- a/.github/workflows/misra-2012.yml +++ b/.github/workflows/misra-2012.yml @@ -30,12 +30,15 @@ jobs: sudo apt-get update sudo apt-get install -y cppcheck autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-ubuntu-latest-v3 + key: wolfssl-ubuntu-latest-v3-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' diff --git a/.github/workflows/misra-2023.yml b/.github/workflows/misra-2023.yml index aaa6847..9316635 100644 --- a/.github/workflows/misra-2023.yml +++ b/.github/workflows/misra-2023.yml @@ -32,12 +32,15 @@ jobs: sudo apt-get update sudo apt-get install -y autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-ubuntu-latest-v3 + key: wolfssl-ubuntu-latest-v3-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -81,7 +84,7 @@ jobs: # -Wdouble-promotion Rule 10.x implicit float-to-double # -Wnull-dereference Safety null pointer dereference # -Wsign-conversion Rule 10.x signed/unsigned conversion - MISRA_FLAGS="-std=c11 -Os \ + MISRA_FLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os \ -Wall -Wextra -Wpedantic -Wshadow -Wconversion \ -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes \ -Wold-style-definition -Wdeclaration-after-statement \ @@ -108,7 +111,7 @@ jobs: -DWOLFCOSE_CBOR_ENCODE -DWOLFCOSE_CBOR_DECODE \ -DWOLFCOSE_KEY_ENCODE -DWOLFCOSE_KEY_DECODE \ -DWOLFCOSE_FLOAT \ - -I./include -I$WOLFSSL_DIR/include" + -I./include -isystem $WOLFSSL_DIR/include" for f in src/*.c; do gcc $MISRA_FLAGS -c "$f" -o /dev/null 2>&1 | tee -a compiler-warnings.txt || true done @@ -166,12 +169,15 @@ jobs: sudo apt-get update sudo apt-get install -y clang-tidy autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-ubuntu-latest-v3 + key: wolfssl-ubuntu-latest-v3-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -213,7 +219,7 @@ jobs: # clang-tidy src/*.c \ -checks='-*,bugprone-*,cert-*,clang-analyzer-*,misc-*,-misc-include-cleaner,-bugprone-branch-clone,-bugprone-easily-swappable-parameters,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling' \ - -- -std=c11 -I./include -I$WOLFSSL_DIR/include \ + -- -std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -I./include -isystem $WOLFSSL_DIR/include \ -DHAVE_ECC -DHAVE_ED25519 -DHAVE_ED448 \ -DWC_RSA_PSS -DHAVE_DILITHIUM \ -DHAVE_AESGCM -DHAVE_AESCCM \ diff --git a/.github/workflows/multi-compiler.yml b/.github/workflows/multi-compiler.yml index 89314ba..d04c9be 100644 --- a/.github/workflows/multi-compiler.yml +++ b/.github/workflows/multi-compiler.yml @@ -35,12 +35,15 @@ jobs: sudo apt-get update sudo apt-get install -y ${{ matrix.cc }} autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-ubuntu-latest-v3 + key: wolfssl-ubuntu-latest-v3-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -62,7 +65,7 @@ jobs: run: | export WOLFSSL_DIR=$HOME/wolfssl-install make CC=${{ matrix.cc }} \ - CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Werror -Wshadow -Wconversion -I./include -I$WOLFSSL_DIR/include" \ + CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Werror -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Run unit tests @@ -70,5 +73,5 @@ jobs: export WOLFSSL_DIR=$HOME/wolfssl-install export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib make test CC=${{ matrix.cc }} \ - CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Werror -Wshadow -Wconversion -I./include -I$WOLFSSL_DIR/include" \ + CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Werror -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" diff --git a/.github/workflows/sanitizer.yml b/.github/workflows/sanitizer.yml index 5b87334..d13ffcd 100644 --- a/.github/workflows/sanitizer.yml +++ b/.github/workflows/sanitizer.yml @@ -24,12 +24,16 @@ jobs: sudo apt-get update sudo apt-get install -y autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" + - name: Cache wolfSSL (ASan) id: cache-wolfssl-asan uses: actions/cache@v4 with: path: ~/wolfssl-asan - key: wolfssl-asan-v3 + key: wolfssl-asan-v3-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL with ASan if: steps.cache-wolfssl-asan.outputs.cache-hit != 'true' @@ -55,11 +59,11 @@ jobs: export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib ASAN_FLAGS="-fsanitize=address -fno-omit-frame-pointer" make clean - make CFLAGS="-std=c11 -O1 -g -Wall -Wextra -Wpedantic $ASAN_FLAGS -I./include -I$WOLFSSL_DIR/include" \ + make CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -O1 -g -Wall -Wextra -Wpedantic $ASAN_FLAGS -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl $ASAN_FLAGS" - make test CFLAGS="-std=c11 -O1 -g -Wall -Wextra -Wpedantic $ASAN_FLAGS -I./include -I$WOLFSSL_DIR/include" \ + make test CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -O1 -g -Wall -Wextra -Wpedantic $ASAN_FLAGS -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl $ASAN_FLAGS" - make tool-test CFLAGS="-std=c11 -O1 -g -Wall -Wextra -Wpedantic $ASAN_FLAGS -I./include -I$WOLFSSL_DIR/include" \ + make tool-test CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -O1 -g -Wall -Wextra -Wpedantic $ASAN_FLAGS -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl $ASAN_FLAGS" - make demo CFLAGS="-std=c11 -O1 -g -Wall -Wextra -Wpedantic $ASAN_FLAGS -I./include -I$WOLFSSL_DIR/include" \ + make demo CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -O1 -g -Wall -Wextra -Wpedantic $ASAN_FLAGS -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl $ASAN_FLAGS" diff --git a/.github/workflows/scenarios.yml b/.github/workflows/scenarios.yml index 9e5c659..b157b69 100644 --- a/.github/workflows/scenarios.yml +++ b/.github/workflows/scenarios.yml @@ -24,12 +24,15 @@ jobs: sudo apt-get update sudo apt-get install -y autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-ubuntu-latest-scenarios-v1 + key: wolfssl-ubuntu-latest-scenarios-v1-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -50,14 +53,14 @@ jobs: - name: Build wolfCOSE run: | export WOLFSSL_DIR=$HOME/wolfssl-install - make CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -I$WOLFSSL_DIR/include" \ + make CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Run scenario examples run: | export WOLFSSL_DIR=$HOME/wolfssl-install export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib - make scenarios CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -I$WOLFSSL_DIR/include" \ + make scenarios CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -fstack-usage -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Scenario Summary diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 9750cbc..1cdf7c9 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -20,12 +20,15 @@ jobs: sudo apt-get update sudo apt-get install -y cppcheck autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-ubuntu-latest-v3 + key: wolfssl-ubuntu-latest-v3-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -71,12 +74,15 @@ jobs: sudo apt-get update sudo apt-get install -y clang-tools autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-ubuntu-latest-v3 + key: wolfssl-ubuntu-latest-v3-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -97,7 +103,7 @@ jobs: - name: Run scan-build run: | scan-build --status-bugs -o scan-results \ - make CC=clang CFLAGS="-std=c11 -Os -Wall -Wextra -I./include -I$HOME/wolfssl-install/include" \ + make CC=clang CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -I./include -isystem $HOME/wolfssl-install/include" \ LDFLAGS="-L$HOME/wolfssl-install/lib -lwolfssl" - name: Upload scan-build results @@ -119,12 +125,15 @@ jobs: sudo apt-get update sudo apt-get install -y autoconf automake libtool + - name: Resolve wolfSSL master commit + id: wolfssl-rev + run: echo "sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git HEAD | cut -f1)" >> "$GITHUB_OUTPUT" - name: Cache wolfSSL id: cache-wolfssl uses: actions/cache@v4 with: path: ~/wolfssl-install - key: wolfssl-ubuntu-latest-v3 + key: wolfssl-ubuntu-latest-v3-${{ steps.wolfssl-rev.outputs.sha }} - name: Build wolfSSL if: steps.cache-wolfssl.outputs.cache-hit != 'true' @@ -145,5 +154,5 @@ jobs: - name: Build with -fanalyzer run: | export WOLFSSL_DIR=$HOME/wolfssl-install - make CC=gcc CFLAGS="-std=c11 -Os -Wall -Wextra -fanalyzer -Werror -I./include -I$WOLFSSL_DIR/include" \ + make CC=gcc CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -fanalyzer -Werror -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" diff --git a/.github/workflows/wolfssl-versions.yml b/.github/workflows/wolfssl-versions.yml index 7c8f81f..e57f3f7 100644 --- a/.github/workflows/wolfssl-versions.yml +++ b/.github/workflows/wolfssl-versions.yml @@ -99,21 +99,21 @@ jobs: - name: Build wolfCOSE run: | export WOLFSSL_DIR=$HOME/wolfssl-install - make CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -I$WOLFSSL_DIR/include" \ + make CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Run unit tests run: | export WOLFSSL_DIR=$HOME/wolfssl-install export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib - make test CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -I$WOLFSSL_DIR/include" \ + make test CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: Run tool round-trip test run: | export WOLFSSL_DIR=$HOME/wolfssl-install export LD_LIBRARY_PATH=$WOLFSSL_DIR/lib - make tool-test CFLAGS="-std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -I$WOLFSSL_DIR/include" \ + make tool-test CFLAGS="-std=c99 -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion -I./include -isystem $WOLFSSL_DIR/include" \ LDFLAGS="-L$WOLFSSL_DIR/lib -lwolfssl" - name: wolfSSL version info diff --git a/Makefile b/Makefile index d3d2739..4742740 100644 --- a/Makefile +++ b/Makefile @@ -16,9 +16,12 @@ CC ?= gcc AR ?= ar -CFLAGS = -std=c11 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion +CFLAGS = -std=c99 -Os -Wall -Wextra -Wpedantic -Wshadow -Wconversion CFLAGS += -fstack-usage -CFLAGS += -I./include -I/usr/local/include +# Match wolfSSL's default (gnu11) struct ABI; -std=c99 alone disables +# HAVE_ANONYMOUS_INLINE_AGGREGATES and shrinks WC_RNG, corrupting the RNG. +CFLAGS += -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 +CFLAGS += -I./include -isystem /usr/local/include CFLAGS += $(EXTRA_CFLAGS) LDFLAGS = -L/usr/local/lib -lwolfssl @@ -56,7 +59,7 @@ SCEN_IOTFLEET = examples/scenarios/iot_fleet_config SCEN_SENSOR = examples/scenarios/sensor_attestation SCEN_BROADCAST = examples/scenarios/group_broadcast_mac -.PHONY: all shared test coverage tool tool-test demo demos comprehensive scenarios clean +.PHONY: all shared test coverage tool tool-test demo demos comprehensive scenarios c99-check clean # --- Core library --- all: $(LIB_A) @@ -157,6 +160,32 @@ scenarios: $(LIB_A) ./$(SCEN_BROADCAST) || exit 1 @echo "=== All scenario examples passed ===" +# --- C99 conformance gate --- +# Compiles every translation unit (core, tests, tool, examples) under strict +# ISO C99 with -pedantic-errors -Werror so any non-C99 construct fails the +# build. wolfSSL headers are -isystem so only wolfCOSE's own code is judged. +WOLFSSL_INC ?= /usr/local/include +C99_FLAGS = -std=c99 -pedantic-errors -Werror -Wall -Wextra -Wshadow -Wconversion \ + -Wvla -DHAVE_ANONYMOUS_INLINE_AGGREGATES=1 \ + -I./include -isystem $(WOLFSSL_INC) $(EXTRA_CFLAGS) +C99_SRC = $(SRC) $(TEST_SRC) $(TOOL_SRC) $(DEMO_SRC) \ + $(ENC_DEMO).c $(MAC_DEMO).c $(SIGN1_DEMO).c \ + $(COMP_SIGN).c $(COMP_ENCRYPT).c $(COMP_MAC).c $(COMP_ERRORS).c \ + $(SCEN_FIRMWARE).c $(SCEN_MULTIPARTY).c $(SCEN_IOTFLEET).c \ + $(SCEN_SENSOR).c $(SCEN_BROADCAST).c +# Default features plus the opt-in WOLFCOSE_FLOAT paths, so the gate judges +# every conditionally-compiled translation unit, not just the default subset. +C99_CONFIGS = "" "-DWOLFCOSE_FLOAT" + +c99-check: + @for cfg in $(C99_CONFIGS); do \ + for f in $(C99_SRC); do \ + echo " C99 $$cfg $$f"; \ + $(CC) $(C99_FLAGS) $$cfg -fsyntax-only $$f || exit 1; \ + done; \ + done + @echo "PASS: all sources conform to ISO C99 (-pedantic-errors)" + # --- Cleanup --- clean: rm -f $(OBJ) $(TEST_BIN) $(TOOL_BIN) $(DEMO_BIN) $(ENC_DEMO) $(MAC_DEMO) \ diff --git a/tests/test_cose.c b/tests/test_cose.c index cf6d611..7206afd 100644 --- a/tests/test_cose.c +++ b/tests/test_cose.c @@ -3947,7 +3947,8 @@ static int mutate_first_recipient_protected_alg(uint8_t* msg, size_t msgLen, { int ret = -1; WOLFCOSE_CBOR_CTX ctx; - uint64_t count = 0; + size_t count = 0; + uint64_t tag = 0; const uint8_t* protectedData = NULL; size_t protectedLen = 0; size_t protectedOffset = 0u; @@ -3958,7 +3959,7 @@ static int mutate_first_recipient_protected_alg(uint8_t* msg, size_t msgLen, if ((ctx.idx < ctx.bufSz) && (wc_CBOR_PeekType(&ctx) == WOLFCOSE_CBOR_TAG)) { - ret = wc_CBOR_DecodeTag(&ctx, &count); + ret = wc_CBOR_DecodeTag(&ctx, &tag); } else { ret = 0;