Skip to content

feat: S17.04 cryptographic confidentiality for at-rest records — AES-256-GCM (mbedTLS, FreeRTOS)#511

Merged
DavidCozens merged 6 commits into
mainfrom
feat/s17-04-mbedtls-aes-gcm
Jun 2, 2026
Merged

feat: S17.04 cryptographic confidentiality for at-rest records — AES-256-GCM (mbedTLS, FreeRTOS)#511
DavidCozens merged 6 commits into
mainfrom
feat/s17-04-mbedtls-aes-gcm

Conversation

@DavidCozens

@DavidCozens DavidCozens commented Jun 2, 2026

Copy link
Copy Markdown
Owner

Purpose

Closes #510 (E17 #105). Adds SolidSyslogMbedTlsAesGcmPolicy — the embedded AEAD at-rest policy, the mbedTLS sibling to S17.03's SolidSyslogOpenSslAesGcmPolicy. Provides authenticated encryption of at-rest records (confidentiality + integrity) on the FreeRTOS / constrained-target path, closing IEC 62443 SR 4.1 at the cryptographic bar for embedded integrators on top of the SR 3.4 integrity S17.02 shipped there.

Change Description

Pure addition — the SealRecord/OpenRecord vtable reshape already landed in S17.03, so no shared interface or other policy is touched.

  • New policy under Platform/MbedTls/ (E11 six-file shape, mirrors the HMAC sibling for vendor wiring and the OpenSSL AES-GCM sibling for AEAD behaviour). One-shot mbedtls_gcm_crypt_and_tag / mbedtls_gcm_auth_decrypt; key fetched on demand and wiped with mbedtls_platform_zeroize. OpenRecord returns false silently on MBEDTLS_ERR_GCM_AUTH_FAILED (tamper/wrong-key), reports only genuine errors.
  • Injected nonce source. mbedTLS has no context-free RNG, so the config carries a caller-owned seeded mbedtls_ctr_drbg_context* (Rng, same DI shape as SolidSyslogMbedTlsStreamConfig.Rng); NULL Rng joins NULL config / GetKey as a bad-config → NullSecurityPolicy fallback. Reuses the role-based SOLIDSYSLOG_AES_GCM_POLICY_POOL_SIZE tunable and SOLIDSYSLOG_MAX_HMAC_KEY_SIZE; trailer = 28 B (fits the 32-B SOLIDSYSLOG_MAX_INTEGRITY_SIZE).
  • Crypto helpers take the SolidSyslogSecurityRecord (not unpacked key, nonce, body, … scalars). This clears clang-tidy's bugprone-easily-swappable-parameters without an inline NOLINT — the warning fires here but not on the OpenSSL sibling because mbedTLS's separate setkey/crypt calls defeat the check's used-together heuristic. The trailer/header layout lives in one place.
  • FreeRTOS BDD arm. --security-policy aes-256-gcm is wired into Bdd/Targets/FreeRtos/main.c; the existing @aesgcm power-cycle-replay scenario now runs on the FreeRTOS-plustcp QEMU runner (dropped its not @aesgcm exclusion). The AEAD nonce source reuses the TLS module's already-seeded CTR-DRBG via a new BddTargetTlsSender_GetRng() accessor rather than standing up a second entropy/DRBG pair on the constrained target.

Test Evidence

  • Host unit suite (28 tests, capture double). The MbedTlsFake GCM additions are a capture-and-canned-return double from inception — each mbedtls_gcm_* call captures its arguments (key, key-bits, cipher id, nonce, AAD, plaintext), copies the body through unchanged, and returns canned results; it is not a cipher and deliberately not a copy of the HMAC fake's predict-the-tag pattern. The suite pins the adapter's wiring and one error path per fallible call (SetGcmStepFails over SETKEY/CRYPT_AND_TAG/AUTH_DECRYPT, plus SetGcmAuthFails for the tamper verdict and SetCtrDrbgRandomFails for the nonce). This is the S17.03 toy-cipher trap avoided up front.
  • Integration suite (7 tests, real libmbedcrypto). Genuine round-trip (body encrypted, then restored), header stays in clear, each seal draws a fresh nonce, and tampered ciphertext / tag / header and a wrong key are all rejected — proving in-place AEAD decryption (output == input) round-trips on real mbedTLS.
  • BDD. The @aesgcm power-cycle-replay scenario runs on bdd-freertos-qemu-plustcp.
  • Verified locally in the cpputest-freertos container: unit + integration green, both FreeRTOS cross-target ELFs link (plustcp + lwip), clang-format / clang-tidy / cppcheck-misra clean.

Areas Affected

  • Platform/MbedTls/ — new policy (Interface + Source, six files). No change to existing mbedTLS adapters or any other Platform.
  • Tests/Support/MbedTlsFake.{c,h} — GCM capture double + CTR-DRBG capture (the mbedtls_ctr_drbg_random stub becomes capturing; existing stream/HMAC tests unaffected).
  • Tests/MbedTls/, Tests/MbedTlsIntegration/ — new unit + integration targets.
  • Bdd/Targets/FreeRtos/, Bdd/Targets/Common/BddTargetTlsSender* — AES-GCM arm + GetRng() accessor; ci/docker-compose.bdd.yml + power_cycle_replay.feature tag wiring.
  • misra_suppressions.txt — three suppressions mirroring the HMAC/OpenSSL siblings.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added AES-256-GCM syslog encryption policy (mbedTLS-backed) and support for selecting it at runtime on FreeRTOS-Plus-TCP targets.
    • Exposed a reusable RNG accessor for nonce generation to enable per-record nonces.
  • Tests

    • Added unit and integration tests for AES-256-GCM seal/open, failure modes, and RNG behavior; extended test doubles accordingly.
    • BDD scenarios updated to run AES‑GCM on compatible runners.
  • Documentation

    • DEVLOG entry describing the AES‑256‑GCM policy.
  • Chores

    • CI test filter updated to include @aesgcm scenarios; build/test wiring updated.

DavidCozens and others added 4 commits June 2, 2026 10:18
Adds SolidSyslogMbedTlsAesGcmPolicy — the embedded AEAD sibling to S17.03's
OpenSSL policy. Pure addition: the SealRecord/OpenRecord vtable reshape already
landed in S17.03, so no shared interface or other policy is touched.

Config injects a caller-owned seeded mbedtls_ctr_drbg_context (mbedTLS has no
context-free RNG, so the nonce source is injected rather than self-sourced as
the OpenSSL sibling does with RAND_bytes). One-shot mbedtls_gcm_crypt_and_tag /
_auth_decrypt; key fetched on demand and wiped with mbedtls_platform_zeroize.

Driven against the MbedTlsFake GCM capture double: it captures the arguments to
each mbedtls_gcm_* call, copies the body through unchanged, and returns canned
results — NOT a cipher. The unit suite pins the adapter's wiring and one error
path per fallible call (setkey, crypt_and_tag, auth_decrypt, ctr_drbg_random);
genuine round-trip / tamper / wrong-key correctness is the integration suite's
job (lands next). This avoids the S17.03 toy-cipher trap that had to be gutted
mid-story.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drives SolidSyslogMbedTlsAesGcmPolicy through real libmbedcrypto with a seeded
CTR-DRBG: genuine round-trip (body encrypted, then restored), header stays in
clear, each seal draws a fresh nonce, and tampered ciphertext / tag / header and
a wrong key are all rejected. Mirrors the OpenSSL AES-GCM integration suite.

Confirms in-place AEAD decryption (output == input) round-trips correctly on
mbedTLS — the gcm.h "output cannot be the same as input" note is conservative;
same-pointer in-place is the documented-safe full-overlap case for GCM.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rget

Wires --security-policy aes-256-gcm into Bdd/Targets/FreeRtos/main.c (validation
+ Create/Destroy branches + policy sources) and lets the @aesgcm power-cycle
replay scenario run on the FreeRTOS-plustcp QEMU runner (drops the not @aesgcm
exclusion from the behave-freertos tag filter). The AEAD nonce source reuses the
TLS module's already-seeded CTR-DRBG via a new BddTargetTlsSender_GetRng()
accessor rather than standing up a second entropy/DRBG pair on the constrained
target — the TLS sender is created before any store-file rebuild, so the DRBG is
seeded by the time the policy needs it.

Closes #510. Includes the S17.04 DEVLOG entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… analysis gates

GcmEncrypt/GcmDecrypt now take (const SolidSyslogSecurityRecord*, key) instead of
unpacked (key, nonce, body, ...) scalars. Two distinct-typed parameters clear
clang-tidy's bugprone-easily-swappable-parameters without an inline NOLINT — the
warning fired here (but not on the OpenSSL sibling) because mbedTLS's one-shot
setkey/crypt_and_tag hands key and nonce to separate calls, so the check's
SuppressParametersUsedTogether heuristic can't pair them. The helpers derive the
body/nonce/tag/AAD from the record's documented trailer layout in one place.

Also: shorten the BAD_CONFIG message to one literal (clang-format wrapped the
longer text into two adjacent literals, tripping bugprone-suspicious-missing-comma),
and add cppcheck-misra suppressions for 11.3 (the SelfFromBase downcast), 5.7
(anonymous-enum constant names shared with the OpenSSL sibling), and 8.7 (the
public ErrorSource object) — each mirrors the existing HMAC/OpenSSL sibling entry.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e04fc779-5e62-458b-80db-e935175f17a8

📥 Commits

Reviewing files that changed from the base of the PR and between 0686b2f and 8bbbdd6.

📒 Files selected for processing (1)
  • Tests/Support/MbedTlsFake.c
🚧 Files skipped from review as they are similar to previous changes (1)
  • Tests/Support/MbedTlsFake.c

📝 Walkthrough

Walkthrough

Adds SolidSyslogMbedTlsAesGcmPolicy with injected CTR-DRBG nonce source, pooled lifecycle, error mapping, extended mbedTLS test double, unit and integration tests, and FreeRTOS BDD wiring exposing the TLS sender RNG to the policy.

Changes

AES-256-GCM Security Policy Implementation

Layer / File(s) Summary
TLS sender RNG accessor for nonce injection
Bdd/Targets/Common/BddTargetTlsSender.h, Bdd/Targets/Common/BddTargetTlsSender_MbedTls_LwipRawTcp.c, Bdd/Targets/Common/BddTargetTlsSender_MbedTls_PlusTcpTcp.c
Declares and implements BddTargetTlsSender_GetRng() to expose the module-owned seeded CTR-DRBG context for per-record nonce generation.
Public API contract and error definitions
Platform/MbedTls/Interface/SolidSyslogMbedTlsAesGcmPolicy.h, Platform/MbedTls/Interface/SolidSyslogMbedTlsAesGcmPolicyErrors.h, Platform/MbedTls/Source/SolidSyslogMbedTlsAesGcmPolicyMessages.c
Defines SolidSyslogMbedTlsAesGcmPolicyConfig (GetKey, KeyContext, Rng), Create/Destroy API, error enum, error-source binding, and message mapping/reporting.
Core record encryption/decryption implementation
Platform/MbedTls/Source/SolidSyslogMbedTlsAesGcmPolicy.c
Implements Seal/Open: key fetch and validation, nonce generation into record->Trailer via injected CTR-DRBG, one-shot mbedTLS AES-256-GCM encrypt/decrypt with header as AAD, tag placement, error reporting, and key zeroization.
Static pool and policy lifecycle
Platform/MbedTls/Source/SolidSyslogMbedTlsAesGcmPolicyStatic.c
Pooled factory Create validates config (non-null GetKey and Rng), acquires slot, initializes base; Destroy resolves handle, frees slot with cleanup, and reports pool/exhaustion/unknown-destroy conditions.
Private implementation interface
Platform/MbedTls/Source/SolidSyslogMbedTlsAesGcmPolicyPrivate.h
Declares internal policy struct (Base + Config) and lifecycle/reporting prototypes for implementation use.
MbedTLS test double: GCM and CTR-DRBG capture
Tests/Support/MbedTlsFake.c, Tests/Support/MbedTlsFake.h
Extends test fake with deterministic CTR-DRBG output, capture-and-canned-return mbedtls_gcm_* interposes, failure injection hooks, and accessors for captured key/nonce/AAD/plaintext and RNG call metadata.
Unit test suite for AES-GCM policy
Tests/MbedTls/SolidSyslogMbedTlsAesGcmPolicyTest.cpp, Tests/MbedTls/CMakeLists.txt
Host tests exercising lifecycle, pool behavior, sealing/opening wiring, fail-closed error paths, key wipe assertions; CMake target added and registered with CTest.
Integration tests and FreeRTOS BDD wiring
Tests/MbedTlsIntegration/SolidSyslogMbedTlsAesGcmPolicyIntegrationTest.cpp, Tests/MbedTlsIntegration/CMakeLists.txt, Bdd/Targets/FreeRtos/main.c, Bdd/Targets/FreeRtos/CMakeLists.txt, ci/docker-compose.bdd.yml, Bdd/features/power_cycle_replay.feature
Integration tests with real libmbedcrypto validating round-trip, tamper and wrong-key detection, fresh nonce per seal; FreeRTOS target wired to create/destroy AES-GCM policy using BddTargetTlsSender_GetRng(); BDD runner filter updated to include @aesgcm.
Build configuration and documentation
DEVLOG.md, misra_suppressions.txt
DEVLOG entry added documenting design/DI decisions and testing strategy; MISRA suppressions added for new policy files.

Sequence Diagram — AES-GCM policy creation and nonce injection

sequenceDiagram
  participant BDD as BDD Scenario
  participant Main as FreeRTOS main.c
  participant Policy as SolidSyslogMbedTlsAesGcmPolicy
  participant TLS as TLS Sender
  participant DRBG as CTR-DRBG

  BDD->>Main: set security-policy aes-256-gcm
  Main->>TLS: BddTargetTlsSender_GetRng()
  TLS-->>Main: mbedtls_ctr_drbg_context* (seeded)
  Main->>Policy: SolidSyslogMbedTlsAesGcmPolicy_Create(config)
  Policy->>DRBG: mbedtls_ctr_drbg_random(nonce)
  DRBG-->>Policy: 12-byte nonce
  Policy-->>Main: policy handle
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • #105: Parent epic for S17 security policy work; this PR implements AES-GCM confidentiality for embedded targets.
  • #510: S17.04 AES-256-GCM at-rest policy (linked story implementing this work).

Possibly related PRs

  • DavidCozens/solid-syslog#481: Related changes to the FreeRTOS mbedTLS TLS sender DRBG handling; this PR adds a public accessor over the same DRBG.

Poem

🐰 In burrows where the counters hum,

a fresh 12-byte nonce will come,
AES wraps secrets snug and tight,
tests confirm each seal and fight,
hop—S17.04 guards the night.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.19% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding AES-256-GCM encryption support for at-rest records in mbedTLS/FreeRTOS, following conventional commits format.
Description check ✅ Passed The PR description is comprehensive and follows the template structure with Purpose, Change Description, Test Evidence, and Areas Affected sections clearly outlined.
Linked Issues check ✅ Passed Code changes fully implement the objectives from issue #510: new AES-256-GCM policy under Platform/MbedTls with on-demand key fetching, injected nonce source, proper error handling, host unit and integration tests, and FreeRTOS BDD wiring.
Out of Scope Changes check ✅ Passed All changes are tightly scoped to the stated objectives: new policy implementation, test infrastructure updates, BDD wiring, and documentation—no unrelated modifications present.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/s17-04-mbedtls-aes-gcm

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1417 passed)
   🚦   build-freertos-host-tdd-plustcp: 100% successful (✔️ 1732 passed)
   🚦   build-linux-clang: 100% successful (✔️ 1363 passed)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1363 passed)
   🚦   integration-linux-openssl: 100% successful (✔️ 16 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 14 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 16 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 48 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 88% successful (✔️ 45 passed, 🙈 6 skipped)
   🚦   bdd-freertos-qemu-plustcp: 86% successful (✔️ 44 passed, 🙈 7 skipped)
   🚦   bdd-freertos-qemu-lwip: 63% successful (✔️ 32 passed, 🙈 19 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1216 passed)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1363 passed)
   ⚠️   Clang-Tidy: No warnings
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
Tests/MbedTls/SolidSyslogMbedTlsAesGcmPolicyTest.cpp (1)

64-73: ⚡ Quick win

Use the repo’s CHECK_REPORTED helper here instead of defining another wrapper.

CHECK_REPORTED_ERROR is re-creating the ErrorHandlerFake assertion shape the test suite already standardizes. Reusing the canonical helper avoids drift and keeps these tests aligned with the rest of the repo.

Based on learnings, when asserting ErrorHandlerFake payloads, use the established CHECK_REPORTED(severity, source, code) macro rather than re-creating the underlying expectations.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/MbedTls/SolidSyslogMbedTlsAesGcmPolicyTest.cpp` around lines 64 - 73,
Replace the custom CHECK_REPORTED_ERROR macro with the repo-standard
CHECK_REPORTED helper: remove the CHECK_REPORTED_ERROR definition and change its
call sites to use CHECK_REPORTED(severity, &MbedTlsAesGcmPolicyErrorSource,
code) so the test asserts ErrorHandlerFake payloads using the canonical macro;
reference the macro name CHECK_REPORTED_ERROR to locate and delete it and use
CHECK_REPORTED and MbedTlsAesGcmPolicyErrorSource when updating assertions.
Tests/Support/MbedTlsFake.c (2)

707-722: ⚡ Quick win

Restructure mbedtls_ctr_drbg_random() to a single exit.

The early return -1; breaks the repo rule for **/*.c files. Keep the fake behavior, but funnel it through one return path.

Suggested change
 int mbedtls_ctr_drbg_random(void* p_rng, unsigned char* output, size_t output_len)
 {
+    int result = 0;
     ctrDrbgRandomCallCount++;
     lastCtrDrbgRandomContext = p_rng;
     lastCtrDrbgRandomBuf = output;
     lastCtrDrbgRandomLen = output_len;
     if (ctrDrbgRandomFails)
     {
-        return -1;
+        result = -1;
     }
-    for (size_t index = 0; index < output_len; index++)
+    else
     {
-        output[index] = (unsigned char) (0xA0U + index);
+        for (size_t index = 0; index < output_len; index++)
+        {
+            output[index] = (unsigned char) (0xA0U + index);
+        }
     }
-    return 0;
+    return result;
 }
As per coding guidelines, "`**/*.c`: Functions must have single return point — if natural shape has early return, restructure with result local and `if` wrapper".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/Support/MbedTlsFake.c` around lines 707 - 722, The function
mbedtls_ctr_drbg_random currently uses an early return when ctrDrbgRandomFails;
change it to a single exit by introducing a local int result initialized to 0,
keep the side-effect code (ctrDrbgRandomCallCount++, lastCtrDrbgRandomContext,
lastCtrDrbgRandomBuf, lastCtrDrbgRandomLen) unchanged, then replace the early
return with setting result = -1 inside the if (ctrDrbgRandomFails) block and
otherwise run the buffer-fill loop, and finally return result at the end of
mbedtls_ctr_drbg_random.

23-30: ⚡ Quick win

Remove the hard caps from captured GCM AAD/body buffers.

SolidSyslogMbedTlsAesGcmPolicy.c forwards record->HeaderLength and the full body length straight into mbedtls_gcm_*, but this fake only stores 16 bytes of AAD and 256 bytes of body while still reporting the uncapped lengths. Any larger-case test that compares against MbedTlsFake_LastGcmAad() or MbedTlsFake_LastGcmPlaintext() using those lengths will read past the capture buffers and the double will misrepresent what the policy actually passed.

Also applies to: 893-897, 923-926

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/Support/MbedTlsFake.c` around lines 23 - 30, The GCM fake currently
enforces MBEDTLSFAKE_GCM_MAX_AAD and MBEDTLSFAKE_GCM_MAX_BODY (the enum values)
which truncates captures while the test helpers (e.g., MbedTlsFake_LastGcmAad()
and MbedTlsFake_LastGcmPlaintext()) report the uncapped lengths; remove these
hard caps and instead record and store the full lengths passed into the fake
(use the passed-in aad_len/plaintext_len values) by allocating/storing buffers
sized to those lengths (or dynamically resizing capture buffers) and update any
related size fields so lookups/readers read exactly the captured lengths rather
than a fixed 16/256 limit.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Platform/MbedTls/Source/SolidSyslogMbedTlsAesGcmPolicy.c`:
- Around line 16-24: The enum defines AES_GCM_TRAILER_SIZE (GCM_NONCE_SIZE +
GCM_TAG_SIZE) but there is no compile-time check that it fits the shared buffer,
risking a runtime overrun of record->Trailer; add a _Static_assert that
AES_GCM_TRAILER_SIZE <= SOLIDSYSLOG_MAX_INTEGRITY_SIZE (using the same macro
name as the shared buffer) with a clear message so compilation fails if the
shared max-integrity constant is reduced, ensuring code paths that write the
trailer (referenced by AES_GCM_TRAILER_SIZE and record->Trailer) cannot overflow
the shared buffer.

---

Nitpick comments:
In `@Tests/MbedTls/SolidSyslogMbedTlsAesGcmPolicyTest.cpp`:
- Around line 64-73: Replace the custom CHECK_REPORTED_ERROR macro with the
repo-standard CHECK_REPORTED helper: remove the CHECK_REPORTED_ERROR definition
and change its call sites to use CHECK_REPORTED(severity,
&MbedTlsAesGcmPolicyErrorSource, code) so the test asserts ErrorHandlerFake
payloads using the canonical macro; reference the macro name
CHECK_REPORTED_ERROR to locate and delete it and use CHECK_REPORTED and
MbedTlsAesGcmPolicyErrorSource when updating assertions.

In `@Tests/Support/MbedTlsFake.c`:
- Around line 707-722: The function mbedtls_ctr_drbg_random currently uses an
early return when ctrDrbgRandomFails; change it to a single exit by introducing
a local int result initialized to 0, keep the side-effect code
(ctrDrbgRandomCallCount++, lastCtrDrbgRandomContext, lastCtrDrbgRandomBuf,
lastCtrDrbgRandomLen) unchanged, then replace the early return with setting
result = -1 inside the if (ctrDrbgRandomFails) block and otherwise run the
buffer-fill loop, and finally return result at the end of
mbedtls_ctr_drbg_random.
- Around line 23-30: The GCM fake currently enforces MBEDTLSFAKE_GCM_MAX_AAD and
MBEDTLSFAKE_GCM_MAX_BODY (the enum values) which truncates captures while the
test helpers (e.g., MbedTlsFake_LastGcmAad() and MbedTlsFake_LastGcmPlaintext())
report the uncapped lengths; remove these hard caps and instead record and store
the full lengths passed into the fake (use the passed-in aad_len/plaintext_len
values) by allocating/storing buffers sized to those lengths (or dynamically
resizing capture buffers) and update any related size fields so lookups/readers
read exactly the captured lengths rather than a fixed 16/256 limit.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ab3a6771-98de-4dc3-875a-db913283d2cc

📥 Commits

Reviewing files that changed from the base of the PR and between 5256608 and 43b7f0b.

📒 Files selected for processing (21)
  • Bdd/Targets/Common/BddTargetTlsSender.h
  • Bdd/Targets/Common/BddTargetTlsSender_MbedTls_LwipRawTcp.c
  • Bdd/Targets/Common/BddTargetTlsSender_MbedTls_PlusTcpTcp.c
  • Bdd/Targets/FreeRtos/CMakeLists.txt
  • Bdd/Targets/FreeRtos/main.c
  • Bdd/features/power_cycle_replay.feature
  • DEVLOG.md
  • Platform/MbedTls/Interface/SolidSyslogMbedTlsAesGcmPolicy.h
  • Platform/MbedTls/Interface/SolidSyslogMbedTlsAesGcmPolicyErrors.h
  • Platform/MbedTls/Source/SolidSyslogMbedTlsAesGcmPolicy.c
  • Platform/MbedTls/Source/SolidSyslogMbedTlsAesGcmPolicyMessages.c
  • Platform/MbedTls/Source/SolidSyslogMbedTlsAesGcmPolicyPrivate.h
  • Platform/MbedTls/Source/SolidSyslogMbedTlsAesGcmPolicyStatic.c
  • Tests/MbedTls/CMakeLists.txt
  • Tests/MbedTls/SolidSyslogMbedTlsAesGcmPolicyTest.cpp
  • Tests/MbedTlsIntegration/CMakeLists.txt
  • Tests/MbedTlsIntegration/SolidSyslogMbedTlsAesGcmPolicyIntegrationTest.cpp
  • Tests/Support/MbedTlsFake.c
  • Tests/Support/MbedTlsFake.h
  • ci/docker-compose.bdd.yml
  • misra_suppressions.txt

Comment thread Platform/MbedTls/Source/SolidSyslogMbedTlsAesGcmPolicy.c
…ty buffer

Address CodeRabbit: the policy hard-codes a 28-byte nonce‖tag trailer and only
documented that it fits SOLIDSYSLOG_MAX_INTEGRITY_SIZE. If that shared buffer is
ever tuned below 28, seal/open would overrun record->Trailer at runtime. Add a
SOLIDSYSLOG_STATIC_ASSERT so the build fails instead. Renumbers the policy's
5.7 / 11.3 cppcheck suppressions shifted by the new includes + assert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1417 passed)
   🚦   build-freertos-host-tdd-plustcp: 100% successful (✔️ 1732 passed)
   🚦   build-linux-clang: 100% successful (✔️ 1363 passed)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1363 passed)
   🚦   integration-linux-openssl: 100% successful (✔️ 16 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 14 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 16 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 48 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 88% successful (✔️ 45 passed, 🙈 6 skipped)
   🚦   bdd-freertos-qemu-plustcp: 86% successful (✔️ 44 passed, 🙈 7 skipped)
   🚦   bdd-freertos-qemu-lwip: 63% successful (✔️ 32 passed, 🙈 19 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1216 passed)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1363 passed)
   ⚠️   Clang-Tidy: No warnings
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

Address CodeRabbit nitpick: the GCM capture double stored only
MBEDTLSFAKE_GCM_MAX_AAD / _MAX_BODY bytes but reported the uncapped length, so a
future test passing AAD > 16 or body > 256 and walking LastGcmAad() /
LastGcmPlaintext() up to the reported length would read past the capture buffer.
Report exactly what was captured instead. No-op for the current fixtures
(4-byte header, 8-byte body); a larger case now fails loudly on length rather
than reading out of bounds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1417 passed)
   🚦   build-freertos-host-tdd-plustcp: 100% successful (✔️ 1732 passed)
   🚦   build-linux-clang: 100% successful (✔️ 1363 passed)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1363 passed)
   🚦   integration-linux-openssl: 100% successful (✔️ 16 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 14 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 16 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 48 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 88% successful (✔️ 45 passed, 🙈 6 skipped)
   🚦   bdd-freertos-qemu-plustcp: 86% successful (✔️ 44 passed, 🙈 7 skipped)
   🚦   bdd-freertos-qemu-lwip: 63% successful (✔️ 32 passed, 🙈 19 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1216 passed)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1363 passed)
   ⚠️   Clang-Tidy: No warnings
   ⚠️   CPPCheck: No warnings


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

@DavidCozens DavidCozens merged commit c48a27f into main Jun 2, 2026
27 checks passed
@DavidCozens DavidCozens deleted the feat/s17-04-mbedtls-aes-gcm branch June 2, 2026 13:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

S17.04: Cryptographic confidentiality for at-rest records — AES-256-GCM (mbedTLS, FreeRTOS demo)

1 participant