Skip to content

MISRA C Compliance

wolfCOSE strives for MISRA C compliance and is checked in CI on every pull request. The project is not yet fully MISRA C:2023 compliant since there is no checker for 2023 that is publicly available yet. We do fully test and support the 2012 Misra-C standard. Full MISRA C:2023 verification requires commercial tooling (like LDRA, Polyspace, Cppcheck Premium). The current free tooling provides around 80% coverage across syntax, essential type, and data-flow rules.

Coverage

MISRA C:2012

Verified via cppcheck's MISRA addon (--addon=misra) with all wolfCOSE algorithm and feature macros defined. Covers ~65-75% of decidable MISRA C:2023 rules including:

  • Syntax rules (comments, declarations, expressions)
  • Control flow rules (goto, switch, loops)
  • Declaration and type rules
  • Pointer and array rules

Workflow: .github/workflows/misra-2012.yml

All wolfCOSE and wolfSSL feature macros are explicitly defined so cppcheck checks the full code path rather than enumerating wolfSSL's hundreds of platform #ifdef configurations. This includes all four default-off experimental COSE-HPKE operation gates, WOLFCOSE_EXPERIMENTAL, wolfSSL HPKE support, and WOLFCOSE_ENABLE_DEPRECATED_ALGS, so draft HPKE code and opt-in RFC 9053 algorithm paths are analyzed rather than silently excluded. See Macros for the complete list.

MISRA C:2023

MISRA C:2023 is essentially MISRA C:2012 plus Amendments 1-4. Since free tooling does not directly support MISRA C:2023, compliance is approximated using two approaches:

Strict Compiler Warnings 17 MISRA-adjacent GCC flags beyond the project's standard -Wall -Wextra -Wpedantic -Wshadow -Wconversion:

Flag MISRA Rule Purpose
-Wcast-qual Rule 11.8 Const qualifier preservation
-Wstrict-prototypes Rule 8.2 Function declaration completeness
-Wmissing-prototypes Rule 8.2 Missing function prototypes
-Wold-style-definition Rule 8.2 Old-style function definitions
-Wdeclaration-after-statement Rule 8.x C90-style declaration ordering
-Wundef Rule 20.9 Undefined macro in #if
-Wfloat-equal Rule 13.4 Float equality comparison
-Wpointer-arith Rule 18.x Pointer arithmetic safety
-Wredundant-decls Rule 8.x Redundant declarations
-Wnested-externs Rule 8.x Nested extern declarations
-Wformat=2 Rule 21.6 Format string safety
-Wformat-security Rule 21.6 Format string security
-Wlogical-op Rule 12.x Logical vs bitwise operators
-Wjump-misses-init Rule 15.1 Goto skipping initialization
-Wdouble-promotion Rule 10.x Implicit float-to-double
-Wnull-dereference Safety Null pointer dereference
-Wsign-conversion Rule 10.x Signed/unsigned conversion

clang-tidy Checks covers standard library safety (Amendment 3), deep data-flow analysis, and CERT C rules that map to MISRA 2023 logic:

Check Category Coverage
bugprone-* Unsafe patterns (buffer overflows, integer overflows, suspicious constructs)
cert-* CERT C rules mapping to MISRA 2023 logic
clang-analyzer-* Inter-procedural data-flow analysis, pointer tracking
misc-* Miscellaneous safety checks (excluding misc-include-cleaner)

Workflow: .github/workflows/misra-2023.yml

Coverage Summary

Area cppcheck (2012) Compiler Flags + clang-tidy (2023) Commercial Tools
Syntax Rules High (~90%) High (~95%) 100%
Essential Types Medium (~50%) High (~80%) 100%
Data Flow Low (~30%) Medium (~50%) 100%
Std Lib Safety Low (~20%) Medium (~60%) 100%

MISRA C:2012 Rule Enforcement

The MISRA C:2012 workflow does not suppress any project rule IDs. It retains the raw analyzer output, separately reports approved deviations and proven analyzer limitations, and fails every undeviated finding in src/ or include/wolfcose/. The remaining cppcheck suppressions only exclude generic analyzer diagnostics and findings inside third-party wolfSSL headers.

The analyzer includes tests/misra_consumer.c as a downstream translation unit. This gives public APIs and public constants a real external use for Rules 8.7 and 2.5 without linking analyzer-only code into the library. For Rule 2.5, cppcheck does not count a macro used only by an #if or #ifdef; the report classifier accepts that limitation only after finding the exact macro in a tracked conditional preprocessing directive.

Approved deviations

ID Rule Location Rationale and validation
D-19.2-001 19.2 WOLFCOSE_KEY.key The public, discriminated union preserves the established ABI and embedded-memory footprint. kty and attachedType govern member access. Replacing it with a structure would break ABI and increase RAM. The full tests exercise the supported members, and CI anchors the deviation to the exact union boundaries.
D-11.8-002 11.8 wolfCose_Hpke0Seal plaintext input The pinned wolfSSL wc_HpkeSealBase() interface accepts a mutable plaintext pointer even though its implementation only consumes plaintext while writing to its distinct ciphertext output. The wrapper keeps the wolfCOSE public input const-qualified and avoids a payload-sized copy in constrained builds. The deviation is anchored to the one interoperability cast and covered by the HPKE unit and sanitizer CI lanes.
D-11.8-003 11.8 wolfCose_Hpke0Open ciphertext input The pinned wolfSSL wc_HpkeOpenBase() interface accepts a mutable ciphertext pointer even though its implementation only consumes ciphertext while writing to its distinct plaintext output. The wrapper keeps the wolfCOSE public input const-qualified and avoids a ciphertext-sized copy in constrained builds. The deviation is anchored to the one interoperability cast and covered by the HPKE unit and sanitizer CI lanes.

scripts/misra-deviations.json identifies only these source locations. The classifier also pins a hash of the public union declaration. It fails if an expected diagnostic disappears, an anchor or approved declaration changes, or an additional finding of either rule appears, so a deviation cannot silently broaden or become stale.

MISRA C:2023 Deviations (clang-tidy)

The following clang-tidy checks are suppressed in the MISRA 2023 workflow. GCC strict MISRA warnings are fully clean (0 warnings).

bugprone-branch-clone: Identical Consecutive Switch Branches

Location: src/wolfcose_alg.c (algorithm dispatch switches)

Justification: Different COSE algorithms intentionally map to the same wolfCrypt value. For example, ES512 and EdDSA both use WC_HASH_TYPE_SHA512, and A128GCM/A192GCM share the same nonce length. The switch branches are not bugs; they represent distinct algorithm IDs with identical cryptographic parameters.

bugprone-easily-swappable-parameters: Adjacent Parameters of Similar Types

Location: Multiple public API functions

Justification: Advisory warning about adjacent function parameters of the same type (e.g., size_t payloadLen, size_t detachedLen). Fixing requires reordering or wrapping parameters, which would break the public API. The parameter ordering follows RFC 9052 structure conventions.

Examples and Test Code

examples/ and tests/ are runnable demonstration and test programs, not part of the shippable library, and are held to the same style rules where it keeps them useful as reference implementations. They are clean of the rules the library observes (no goto, fixed-length-coordinate checks, const-qualified literal payloads, braced statement bodies, unsigned size arithmetic, explicit precedence). The remaining deviations are inherent to runnable demos:

Rule 21.6: Standard I/O (and 17.7 on its return value)

Location: examples/, tests/.

Justification: Demos and test harnesses print human-readable status and PASS/FAIL to the console with printf/fprintf; the ignored return value (Rule 17.7) is part of the same console-output use. A real integration replaces this one call with a platform output routine. Library code under src/ uses no standard I/O.

Rule 15.5: Multiple return / single point of exit

Location: examples/, tests/.

Justification: Demonstration code uses early returns for linear, readable top-to-bottom flow. The library itself observes single-exit with cascading if (ret == 0) and a single return.

Rule 2.5: Unused macro definitions

Location: examples/, tests/.

Justification: Same false positive as the library: CI passes explicit -D feature flags so cppcheck checks one code path, which makes the guarded-away feature #defines look unused.

Rules 8.6 / 5.9 / 8.9: External/internal identifier definitions

Location: examples/.

Justification: Each demo is a standalone program with its own main and demo_* helpers. cppcheck reports these when scanning all demo translation units in a single pass; each program links independently, so there is no real multiple-definition.

Fully Compliant Rules (Notable)

Rule Status Notes
Rule 15.1 (no goto) Compliant All functions use cascading if (ret == WOLFCOSE_SUCCESS) with a single return ret
Rule 15.5 (single exit) Compliant All functions have exactly one return statement
Rule 17.2 (no recursion) Compliant CBOR decoder uses iterative traversal with a bounded stack (WOLFCOSE_CBOR_MAX_DEPTH)
Rule 17.7 (check returns) Compliant All return values checked or explicitly cast to (void)
Rule 12.1 (explicit precedence) Compliant All &&/|| operands and mixed arithmetic explicitly parenthesized