Skip to content

feat: S17.03 cryptographic confidentiality for at-rest records — AES-256-GCM (OpenSSL, Linux)#509

Merged
DavidCozens merged 12 commits into
mainfrom
feat/s17-03-aes-gcm-at-rest
Jun 2, 2026
Merged

feat: S17.03 cryptographic confidentiality for at-rest records — AES-256-GCM (OpenSSL, Linux)#509
DavidCozens merged 12 commits into
mainfrom
feat/s17-03-aes-gcm-at-rest

Conversation

@DavidCozens

@DavidCozens DavidCozens commented Jun 1, 2026

Copy link
Copy Markdown
Owner

Purpose

Closes #508 (S17.03, epic #105). Adds the first authenticated-encryption
at-rest SolidSyslogSecurityPolicy — AES-256-GCM over OpenSSL — giving stored
records confidentiality on top of the integrity that S17.01/S17.02 already
provided. This closes IEC 62443 SR 4.1 (information confidentiality) at the
cryptographic bar, alongside the existing SR 3.4 integrity.

One algorithm, one platform: the goal is to get the AEAD API shape right before
going public. Linux/OpenSSL only this story (Windows compiles the source but
gets no BDD wiring); an mbedTLS sibling is deferred to a future S17.04.

Change Description

Sliced into reviewable commits:

  1. refactor: reshape SolidSyslogSecurityPolicyIntegritySize /
    ComputeIntegrity / VerifyIntegrityTrailerSize / SealRecord /
    OpenRecord, using a single contiguous content region + a headerLength
    offset
    (content[0..headerLength) = associated data, the rest = body).
    This is the shape an AEAD needs (authenticate the cleartext header, encrypt
    the body in place). Chosen over the epic's two-pointer body/aad sketch
    because it leaves the just-shipped HMAC/CRC one-shot crypto untouched. All
    four existing policies (Null, CRC-16, OpenSSL + mbedTLS HMAC) and the
    RecordStore consumer migrate behaviour-preservingly — on-disk bytes and tags
    are byte-identical, so the existing suite is the regression net.
    SOLIDSYSLOG_MAX_INTEGRITY_SIZE keeps its name (only the vtable field
    renamed).
  2. feat: SolidSyslogOpenSslAesGcmPolicy — 6-file E11 shape mirroring the
    HMAC sibling. 32-byte key on demand via SolidSyslogKeyFunction
    (OPENSSL_cleansed per op), fresh 12-byte RAND_bytes nonce per record,
    nonce ‖ tag (28 B) trailer that fits the existing 32-byte budget.
    Pool-allocated via a new SOLIDSYSLOG_AES_GCM_POLICY_POOL_SIZE tunable;
    bad-config / exhaustion fall back to NullSecurityPolicy. A tag mismatch on
    open returns false silently (the tamper-detected path); only genuine
    OpenSSL errors are reported.
  3. test: real-crypto integration tests against libcrypto.
  4. feat: Linux BDD wiring--security-policy aes-256-gcm arm + an
    @aesgcm power-cycle-replay scenario; docs.
  5. chore: clang-format reflow + MISRA suppressions.

Nonce strategy

Random 12-byte nonce per record (no cross-reboot state to lose). The NIST
SP 800-38D §8.3 random-nonce ceiling is ~136 years at one event/second —
documented as headroom, not a caveat. No GCM-SIV.

Test Evidence

  • Unit (host, OpenSslFake) — the GCM fake is a capture-and-canned-return
    double (not a cipher); the unit tests verify the adapter's wiring rather than
    re-deriving GCM: lifecycle/pool/bad-config, fresh nonce into the trailer, key
    fetched + wiped, header as AAD, body handed to encrypt, nonce read back on
    open, decrypt-success propagation, and the silent tamper-reject path. Every
    fallible OpenSSL call in the seal/open sequence (CTX_new, both Inits,
    SET_IVLEN, both Updates, Final, GET_TAG/SET_TAG) has a dedicated error-path
    test — SolidSyslogOpenSslAesGcmPolicy.c is 100% line / 100% function
    coverage. Genuine round-trip / tamper / wrong-key correctness is owned by the
    integration suite below.
  • Integration (integration-linux-openssl + -windows-openssl, real
    libcrypto)
    — 7 tests: genuine round-trip, body-is-encrypted,
    header-in-clear, fresh-nonce-per-seal, tampered ciphertext/tag/header
    rejected, wrong key rejected.
  • BDD@aesgcm power-cycle-replay scenario passes locally end-to-end
    (records encrypted+tagged on write, decrypted+verified on replay after a
    power cycle). Runs Linux-only; excluded from Windows / FreeRTOS runners.
  • The behaviour-preserving reshape keeps the full existing unit + HMAC/CRC
    integration + BDD suites green. cppcheck-MISRA gate clean.
  • Verified locally on the gcc image (junit, OpenSSL integration, BDD target
    tests, cppcheck preset) and the freertos-host image (mbedTLS HMAC unit
    test, to confirm the reshape).

Areas Affected

  • Core/Interface/SolidSyslogSecurityPolicyDefinition.h — vtable reshape
    (extension-point contract; affects any custom SolidSyslogSecurityPolicy).
  • Core/Source/RecordStore.c, SolidSyslogBlockStoreStatic.c, the Null/CRC-16
    policies, and both HMAC siblings — migrated to the new contract.
  • Platform/OpenSsl/ — new AES-GCM policy (also compiled into the Windows
    OpenSSL build automatically).
  • Core/Interface/SolidSyslogTunablesDefaults.h — new pool tunable.
  • Tests, Tests/Support/OpenSslFake.{c,h}, Linux BDD target, the @aesgcm
    feature + CI tag filters, docs/security/at-rest-cryptography.md,
    docs/iec62443.md, DEVLOG.

Summary by CodeRabbit

  • New Features

    • Added AES‑256‑GCM authenticated‑encryption option for at‑rest record protection
    • Block store now supports configurable per‑record sealing/opening security policies
  • Documentation

    • Added at‑rest cryptography guide and updated IEC 62443 mapping
    • DEVLOG entry documenting AES‑GCM rollout
  • Tests

    • New unit and integration tests for AES‑GCM and updated policy contract
    • Added BDD scenario validating AES‑GCM power‑cycle replay
  • Chores

    • CI/BDD filters updated to exclude AES‑GCM on unsupported runners

DavidCozens and others added 5 commits June 1, 2026 21:15
Replace the IntegritySize/ComputeIntegrity/VerifyIntegrity vtable with
TrailerSize/SealRecord/OpenRecord, using a single contiguous content
region plus a headerLength offset (content[0..headerLength) = associated
data, content[headerLength..contentLength) = body). MAC and checksum
policies authenticate the whole content and ignore the split; this is the
shape an AEAD policy needs to authenticate the cleartext header and
encrypt the body in place (S17.03 AES-GCM lands next).

Behaviour-preserving: Null, Crc16, OpenSsl/MbedTls HMAC all migrate with
no change to on-disk bytes or tags. The RecordStore consumer passes
magic|length|message as content with headerLength = magic+length. The
SOLIDSYSLOG_MAX_INTEGRITY_SIZE tunable keeps its name.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
First AEAD at-rest policy: authenticated encryption of stored records
(confidentiality + integrity), closing IEC 62443 SR 4.1 at the
cryptographic bar. Encrypts the body in place, authenticates the
cleartext header as associated data, and writes nonce ‖ tag (28 bytes)
to the policy-owned trailer (fits SOLIDSYSLOG_MAX_INTEGRITY_SIZE).

Key fetched on demand via SolidSyslogKeyFunction (exactly 32 bytes for
AES-256) and OPENSSL_cleanse'd per operation; fresh 12-byte nonce per
record via RAND_bytes. Pool-allocated (E11) via the new
SOLIDSYSLOG_AES_GCM_POLICY_POOL_SIZE tunable; bad-config / exhaustion
fall back to the shared NullSecurityPolicy. A tag mismatch on open is
the expected tamper-detected path and returns false silently; only
genuine OpenSSL errors are reported.

Host unit tests drive lifecycle, round-trip, tamper (body/tag/header),
wrong-key, wrong-length-key, key-unavailable, nonce/encrypt/decrypt
failures, and key wipe against a new deterministic OpenSslFake GCM +
RAND_bytes interposition. Real-crypto correctness follows in the
OpenSslIntegration suite (S17.03 Phase C).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Exercises SolidSyslogOpenSslAesGcmPolicy on the real libcrypto (the unit
tests use the deterministic OpenSslFake): genuine round-trip, body is
actually encrypted, header stays in clear, each seal draws a fresh
nonce, and tampered ciphertext / tag / header and a wrong key are all
rejected. Runs on integration-linux-openssl and integration-windows-openssl.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds the --security-policy aes-256-gcm arm to the Linux BDD target
(CreateSecurityPolicy/DestroySecurityPolicy + parser validator + test)
and a @aesgcm power-cycle-replay scenario proving the AEAD policy is
transparent to behaviour: records encrypted and tagged on write are
decrypted and verified on replay-read after a power cycle. The scenario
runs Linux-only (OpenSSL) — excluded from the Windows and
FreeRTOS-plustcp runners (no AES-GCM wired there this story), and from
FreeRTOS-lwip via @store.

Documents the policy in docs/security/at-rest-cryptography.md (spectrum,
key-on-demand, the ~136-year random-nonce envelope, key-management
responsibility) and refreshes the now-shipped at-rest rows in
docs/iec62443.md. DEVLOG updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Pre-push Tier B: clang-format reflow of the touched files, (void)-cast
the memcpy in GcmDecrypt (MISRA 17.7, matching the codebase convention),
and add the AES-GCM policy's MISRA suppressions (11.3 vtable downcast,
5.7 repeated struct tag, 8.7 single-TU error source) mirroring the HMAC
sibling. misra_renumber resynced the HMAC/MbedTls suppression lines the
reshape shifted.

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

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@DavidCozens, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 56 minutes and 42 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 55d64731-8bc7-455d-8e6b-eb234654d374

📥 Commits

Reviewing files that changed from the base of the PR and between 2f344ca and d6c9a8e.

📒 Files selected for processing (6)
  • DEVLOG.md
  • Platform/MbedTls/Source/SolidSyslogMbedTlsHmacSha256Policy.c
  • Platform/OpenSsl/Source/SolidSyslogOpenSslHmacSha256Policy.c
  • Tests/SolidSyslogOpenSslAesGcmPolicyTest.cpp
  • Tests/Support/OpenSslFake.c
  • Tests/Support/OpenSslFake.h
📝 Walkthrough

Walkthrough

Reshapes the security-policy API to TrailerSize + SealRecord/OpenRecord, updates RecordStore/BlockStore to use trailers, migrates policies, implements OpenSSL AES‑256‑GCM (implementation, pool, errors, messages), updates tests/fakes/BDD/CI, and adds docs and CMake/MISRA entries.

Changes

Security Policy reshape, RecordStore integration, and policy migrations

Layer / File(s) Summary
Security policy contract
Core/Interface/SolidSyslogSecurityPolicyDefinition.h
SolidSyslogSecurityPolicy refactored: IntegritySize/Compute/Verify replaced by TrailerSize and SealRecord/OpenRecord using SolidSyslogSecurityRecord (content, contentLength, headerLength, trailer).
RecordStore & BlockStore integration
Core/Source/RecordStore.c, Core/Source/SolidSyslogBlockStoreStatic.c
Record layout and helpers now use TrailerSize; writes call SealRecord with content/header split and trailer out; reads call OpenRecord after reading trailer; BlockStore validation checks TrailerSize.
Policy migrations (Null, CRC16, HMACs)
Core/Source/SolidSyslogNullSecurityPolicy.c, Core/Source/SolidSyslogCrc16Policy.c, Platform/OpenSsl/Source/SolidSyslogOpenSslHmacSha256Policy.c, Platform/MbedTls/Source/SolidSyslogMbedTlsHmacSha256Policy.c
Existing policies migrated from compute/verify integrity API to SealRecord/OpenRecord; CRC/HMAC write and verify trailer bytes and continue to ignore headerLength (behaviour preserved).

OpenSSL AES‑256‑GCM policy implementation

Layer / File(s) Summary
AES‑GCM public interface & errors
Platform/OpenSsl/Interface/SolidSyslogOpenSslAesGcmPolicy.h, Platform/OpenSsl/Interface/SolidSyslogOpenSslAesGcmPolicyErrors.h
Adds SolidSyslogOpenSslAesGcmPolicyConfig (GetKey + KeyContext), Create/Destroy factory functions, and AES‑GCM-specific error enum and error-source extern.
AES‑GCM EVP implementation
Platform/OpenSsl/Source/SolidSyslogOpenSslAesGcmPolicy.c
Implements in-place AES‑256‑GCM SealRecord/OpenRecord using RAND_bytes 12‑byte nonce, header as AAD, trailer = nonce
AES‑GCM static pool & messages
Platform/OpenSsl/Source/SolidSyslogOpenSslAesGcmPolicyStatic.c, Platform/OpenSsl/Source/SolidSyslogOpenSslAesGcmPolicyMessages.c, Platform/OpenSsl/Source/SolidSyslogOpenSslAesGcmPolicyPrivate.h
Static pool-backed Create/Destroy with config validation, handle-index mapping, cleanup, and error-to-string / reporter wiring plus private struct declarations.

Test infrastructure and fakes

Layer / File(s) Summary
OpenSSL test fake: GCM & RAND
Tests/Support/OpenSslFake.c, Tests/Support/OpenSslFake.h
Adds deterministic interposed EVP AES‑256‑GCM and RAND_bytes implementations, captured inputs/counters, failure injection toggles, reset logic, and exported test accessors for GCM/RAND interactions.
Policy unit & integration tests
Tests/* (many test files)
Unit tests updated to use TrailerSize and SealRecord/OpenRecord API; new OpenSSL AES‑GCM unit and integration tests exercise creation, pool, seal/open round-trip, nonce freshness, AAD/header preservation, tamper rejection, wrong-key and key-unavailable behaviors, error reporting, and key cleansing. Test CMake updated to include AES‑GCM tests when OpenSSL enabled.

BDD, CI, build, MISRA, and docs

Layer / File(s) Summary
BDD CLI & wiring
Bdd/Targets/Linux/BddTargetCommandLine.c, Bdd/Targets/Linux/BddTargetCommandLine.h, Bdd/Targets/Linux/main.c
Adds aes-256-gcm CLI support/documentation, includes AES‑GCM header, and wires Create/Destroy branches using demo key callback.
BDD scenario & CI exclusions
Bdd/features/power_cycle_replay.feature, .github/workflows/ci.yml, ci/docker-compose.bdd.yml
Adds @aesgcm power-cycle replay scenario (Linux-only) and excludes @aesgcm from Windows OTel BDD and behave-freertos docker-compose runs.
Docs, CMake & MISRA
docs/security/at-rest-cryptography.md, docs/iec62443.md, Platform/OpenSsl/CMakeLists.txt, misra_suppressions.txt, DEVLOG.md
Adds at-rest cryptography doc and IEC62443 mapping updates, appends AES‑GCM sources to OpenSSL CMake target, updates MISRA suppressions for new files, and records DEVLOG entry for S17.03.

Sequence Diagram

sequenceDiagram
  participant App
  participant RecordStore
  participant SecurityPolicy
  participant OpenSSL
  App->>RecordStore: Write(magic|length|message)
  RecordStore->>RecordStore: Build content (magic|length|message)
  RecordStore->>SecurityPolicy: SealRecord(content, contentLen, headerLength=4, trailerOut)
  SecurityPolicy->>OpenSSL: FetchKey / RAND_bytes / EVP_Encrypt (key, nonce, AAD=header, plaintext=body)
  OpenSSL-->>SecurityPolicy: ciphertext + tag
  SecurityPolicy->>SecurityPolicy: Write trailer (nonce||tag), OPENSSL_cleanse(key)
  RecordStore->>App: Persist sealed record (content || trailer || sentFlag)
  App->>RecordStore: ReadNextUnsent()
  RecordStore->>SecurityPolicy: OpenRecord(content, contentLen, headerLength=4, trailerIn)
  SecurityPolicy->>OpenSSL: FetchKey / EVP_Decrypt (key, nonce, AAD=header, ciphertext, tag)
  OpenSSL-->>SecurityPolicy: success or auth-fail
  SecurityPolicy->>RecordStore: Return opened content OR false on auth-fail
  RecordStore->>App: Return record or error
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

  • #105: Epic implementing the Seal/Open API and AES‑256‑GCM objectives addressed by this PR.

Possibly related PRs

Poem

🐰 I nibble bytes and guard the logs,

I wrap bodies, tag the clocks.
Nonces fresh and headers clear,
Tests hop by with bashful cheer.
Hooray — the sealed records sleep secure.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.12% 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 PR title 'feat: S17.03 cryptographic confidentiality for at-rest records — AES-256-GCM (OpenSSL, Linux)' clearly and concisely describes the main feature being added: AES-256-GCM authenticated encryption for at-rest records.
Linked Issues check ✅ Passed The changeset fully implements all objectives from issue #508: reshapes SolidSyslogSecurityPolicy interface to TrailerSize/SealRecord/OpenRecord, migrates existing policies (Null/Crc16/HMAC variants) behaviour-preservingly, implements AES-256-GCM policy with key callback/nonce/trailer details, adds comprehensive unit/integration/BDD tests, and documents nonce rationale.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the linked issue #508 scope: the interface reshape, four existing policy migrations, AES-GCM implementation, tests, Linux BDD wiring, and documentation. No unrelated refactoring, dependency updates, or feature creep detected.
Description check ✅ Passed PR description is comprehensive, well-structured, and addresses all required template sections with clear purpose, detailed change rationale, thorough test evidence, and affected areas.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/s17-03-aes-gcm-at-rest

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 1, 2026

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1407 passed)
   🚦   build-freertos-host-tdd-plustcp: 100% successful (✔️ 1715 passed)
   🚦   build-linux-clang: 100% successful (✔️ 1353 passed)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1353 passed)
   🚦   integration-linux-openssl: 100% successful (✔️ 16 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 7 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: 84% successful (✔️ 43 passed, 🙈 8 skipped)
   🚦   bdd-freertos-qemu-lwip: 63% successful (✔️ 32 passed, 🙈 19 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1206 passed)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1353 passed)
   ⚠️   Clang-Tidy: 2 warnings (high: 2)
   ⚠️   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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Bdd/Targets/Linux/main.c (1)

67-69: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update comment to reflect both keyed policies.

The comment states "Only the keyed hmac-sha256 policy needs the handle to destroy" but now aes-256-gcm also requires the handle (line 266).

📝 Suggested comment fix
-/* Holds the created at-rest SecurityPolicy handle so DestroyStore can release
- * it. Only the keyed hmac-sha256 policy needs the handle to destroy; crc16 and
- * null are dispatched by name. */
+/* Holds the created at-rest SecurityPolicy handle so DestroyStore can release
+ * it. The keyed policies (hmac-sha256, aes-256-gcm) need the handle to destroy;
+ * crc16 is dispatched via singleton Destroy, and null needs no cleanup. */
🤖 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 `@Bdd/Targets/Linux/main.c` around lines 67 - 69, The comment above the at-rest
SecurityPolicy handle is outdated—update it to state that both keyed policies
(hmac-sha256 and aes-256-gcm) require the stored SecurityPolicy handle so
DestroyStore can release it; find the comment near the at-rest SecurityPolicy
handle declaration and replace the single-policy text ("Only the keyed
hmac-sha256 policy needs the handle to destroy") with phrasing that includes
both keyed policies (hmac-sha256 and aes-256-gcm) and clarifies that crc16 and
null are dispatched by name.
🤖 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.

Outside diff comments:
In `@Bdd/Targets/Linux/main.c`:
- Around line 67-69: The comment above the at-rest SecurityPolicy handle is
outdated—update it to state that both keyed policies (hmac-sha256 and
aes-256-gcm) require the stored SecurityPolicy handle so DestroyStore can
release it; find the comment near the at-rest SecurityPolicy handle declaration
and replace the single-policy text ("Only the keyed hmac-sha256 policy needs the
handle to destroy") with phrasing that includes both keyed policies (hmac-sha256
and aes-256-gcm) and clarifies that crc16 and null are dispatched by name.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 10140669-3014-4086-ac99-fc6129e82d8a

📥 Commits

Reviewing files that changed from the base of the PR and between 0defd43 and bdbec87.

📒 Files selected for processing (37)
  • .github/workflows/ci.yml
  • Bdd/Targets/Linux/BddTargetCommandLine.c
  • Bdd/Targets/Linux/BddTargetCommandLine.h
  • Bdd/Targets/Linux/main.c
  • Bdd/features/power_cycle_replay.feature
  • Core/Interface/SolidSyslogSecurityPolicyDefinition.h
  • Core/Interface/SolidSyslogTunablesDefaults.h
  • Core/Source/RecordStore.c
  • Core/Source/SolidSyslogBlockStoreStatic.c
  • Core/Source/SolidSyslogCrc16Policy.c
  • Core/Source/SolidSyslogNullSecurityPolicy.c
  • DEVLOG.md
  • Platform/MbedTls/Source/SolidSyslogMbedTlsHmacSha256Policy.c
  • Platform/OpenSsl/CMakeLists.txt
  • Platform/OpenSsl/Interface/SolidSyslogOpenSslAesGcmPolicy.h
  • Platform/OpenSsl/Interface/SolidSyslogOpenSslAesGcmPolicyErrors.h
  • Platform/OpenSsl/Source/SolidSyslogOpenSslAesGcmPolicy.c
  • Platform/OpenSsl/Source/SolidSyslogOpenSslAesGcmPolicyMessages.c
  • Platform/OpenSsl/Source/SolidSyslogOpenSslAesGcmPolicyPrivate.h
  • Platform/OpenSsl/Source/SolidSyslogOpenSslAesGcmPolicyStatic.c
  • Platform/OpenSsl/Source/SolidSyslogOpenSslHmacSha256Policy.c
  • Tests/Bdd/Targets/BddTargetCommandLineTest.cpp
  • Tests/CMakeLists.txt
  • Tests/MbedTls/SolidSyslogMbedTlsHmacSha256PolicyTest.cpp
  • Tests/OpenSslIntegration/CMakeLists.txt
  • Tests/OpenSslIntegration/SolidSyslogOpenSslAesGcmPolicyIntegrationTest.cpp
  • Tests/SolidSyslogBlockStoreTest.cpp
  • Tests/SolidSyslogCrc16PolicyTest.cpp
  • Tests/SolidSyslogNullSecurityPolicyTest.cpp
  • Tests/SolidSyslogOpenSslAesGcmPolicyTest.cpp
  • Tests/SolidSyslogOpenSslHmacSha256PolicyTest.cpp
  • Tests/Support/OpenSslFake.c
  • Tests/Support/OpenSslFake.h
  • ci/docker-compose.bdd.yml
  • docs/iec62443.md
  • docs/security/at-rest-cryptography.md
  • misra_suppressions.txt

DavidCozens and others added 2 commits June 1, 2026 23:37
The reshape gave every policy's SealRecord/OpenRecord two adjacent
uint16_t parameters (contentLength, headerLength), tripping
bugprone-easily-swappable-parameters; wrap each vtable implementation
(and the BlockStore test spy) in a NOLINT with the contract rationale,
matching the established codebase pattern.

In the AES-GCM policy, drop the TU-local named enum
OpenSslAesGcmPolicy_OpenResult (the project's EnumPrefix rule forces a
SolidSyslog prefix on named enums; TU-local enums stay anonymous) —
GcmDecrypt now returns bool and self-reports genuine OpenSSL errors,
keeping the silent tamper-detected path. Rework the OpenSslFake AES-GCM
interposition onto the char-sentinel-handle idiom (single static state,
no casting the opaque handle back to a struct), matching OpenSSL's
parameter names, so the fake passes tidy too. misra_renumber resynced.

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

The at-rest SecurityPolicy handle comment said only hmac-sha256 needs the
handle to destroy; aes-256-gcm (added this story) does too. Per CodeRabbit
review on #509.

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

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1407 passed)
   🚦   build-freertos-host-tdd-plustcp: 100% successful (✔️ 1715 passed)
   🚦   build-linux-clang: 100% successful (✔️ 1353 passed)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1353 passed)
   🚦   integration-linux-openssl: 100% successful (✔️ 16 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 7 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: 84% successful (✔️ 43 passed, 🙈 8 skipped)
   🚦   bdd-freertos-qemu-lwip: 63% successful (✔️ 32 passed, 🙈 19 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1206 passed)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1353 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.

…tyRecord

Bundle the security-policy method arguments into a SolidSyslogSecurityRecord
struct (Content, ContentLength, HeaderLength, Trailer) passed by const
pointer. This removes the two adjacent uint16_t lengths from every
implementation's signature — eliminating the bugprone-easily-swappable-parameters
findings at the root rather than suppressing them, so all the per-policy and
spy NOLINTs are gone. Named fields also make ContentLength vs HeaderLength
unmistakable at call sites, and the contract is now extensible without churning
every vtable signature.

Const-correct by construction: the policy may not repoint the fields, but the
member pointers are non-const so it still writes through Content (in-place
encrypt/decrypt) and Trailer (seal) — one signature serves both seal and open.

Behaviour-preserving: all five policies, the RecordStore consumer, every policy
test, the BlockStore spy, and the OpenSSL integration test migrate with no change
to on-disk bytes or outcomes. misra_renumber resynced the shifted suppression
lines.

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 (✔️ 1407 passed)
   🚦   build-freertos-host-tdd-plustcp: 100% successful (✔️ 1715 passed)
   🚦   build-linux-clang: 100% successful (✔️ 1353 passed)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1353 passed)
   🚦   integration-linux-openssl: 100% successful (✔️ 16 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 7 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: 84% successful (✔️ 43 passed, 🙈 8 skipped)
   🚦   bdd-freertos-qemu-lwip: 63% successful (✔️ 32 passed, 🙈 19 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1206 passed)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1353 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 and others added 4 commits June 2, 2026 08:01
… error path

The OpenSslFake's AES-GCM half was a working toy cipher (reversible XOR
keystream + FNV tag). The unit tests that leaned on it — round-trip, tamper,
wrong-key — only proved the fake reproduced GCM, duplicating the
OpenSslIntegration suite while testing none of the adapter's own logic.

Gut the fake down to a capture-and-canned-return double: EVP calls capture
their arguments, copy the body through unchanged, and return canned results.
Replace the coarse encrypt/decrypt/auth failure booleans with a single
per-step injection (OpenSslFake_SetGcmStepFails) so each OpenSSL call in the
seal/open sequence can be failed in turn.

Drop the seven fake-testing semantic tests; add per-step error tests pinning
every fallible EVP call (CTX_new, both Inits, SET_IVLEN, both Updates, Final,
GET_TAG/SET_TAG) plus the silent DecryptFinal tamper-reject path. Coverage of
SolidSyslogOpenSslAesGcmPolicy.c is now 100% line / 100% function; genuine
AES-256-GCM correctness stays owned by the integration suite.

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

cppcheck-misra flagged misra-c2012-11.8 (const-strip) where SealRecord passed
record->Trailer directly as the writable tag destination — the addon tracks the
outer const on *record and treats the non-const member pointer as const-stripped
(D.006 category 1). Bind the trailer to a local uint8_t* first, exactly as the
AES-GCM sibling already does for its nonce/tag, which sidesteps the false
positive without a suppression. Behaviour-identical; full cppcheck-misra now
exits clean with no new suppressions.

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

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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 (✔️ 1725 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 (✔️ 7 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: 84% successful (✔️ 43 passed, 🙈 8 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.

@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 (✔️ 1725 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 (✔️ 7 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: 84% successful (✔️ 43 passed, 🙈 8 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 5256608 into main Jun 2, 2026
27 checks passed
@DavidCozens DavidCozens deleted the feat/s17-03-aes-gcm-at-rest branch June 2, 2026 07:22
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.03: Cryptographic confidentiality for at-rest records — AES-256-GCM (OpenSSL, Linux demo)

1 participant