Skip to content

E17: SL4 Security — Encryption and authenticated integrity for file store #105

@DavidCozens

Description

@DavidCozens

Context

S05.06 introduces a SolidSyslogSecurityPolicy struct for injectable integrity checking on file store records. The initial implementation provides CRC-16 as the concrete integrity algorithm. This epic extends that foundation to provide encryption at rest and authenticated integrity, targeting IEC 62443 SL4 compliance.

Driving requirements

  • SR 4.1 (Confidentiality at rest): Audit log data stored on the device must be protected against disclosure.
  • SR 3.4 (Cryptographic integrity): Integrity of audit log data must be verifiable using cryptographic mechanisms.

Design decisions captured during S05.06

SecurityPolicy struct extension

The SolidSyslogSecurityPolicy struct introduced in S05.06 will be extended with:

typedef struct SolidSyslogSecurityPolicy
{
    uint16_t integrity_size;

    void (*compute_integrity)(const uint8_t *data, uint16_t length,
                              uint8_t       *integrity_out);

    bool (*verify_integrity) (const uint8_t *data, uint16_t length,
                              const uint8_t *integrity_in);

    /* Added by this epic: */
    uint16_t nonce_size;

    bool (*encrypt)(const uint8_t *plaintext,  uint16_t length,
                    const uint8_t *nonce,       uint8_t *ciphertext_out,
                    uint8_t       *tag_out);

    bool (*decrypt)(const uint8_t *ciphertext, uint16_t length,
                    const uint8_t *nonce,       const uint8_t *tag,
                    uint8_t       *plaintext_out);
} SolidSyslogSecurityPolicy;

Authenticated encryption couples integrity and encryption

With AES-GCM or ChaCha20-Poly1305, the authentication tag provides both integrity and confidentiality in a single operation. When this epic is played:

  • The compute_integrity / verify_integrity callbacks become part of the authenticated encryption — they are not separate operations.
  • A single policy object handles both concerns. Do not split integrity and encryption into separate abstractions.
  • The record format's integrity field holds the authentication tag.

Key management and nonce generation are platform-specific

These belong in the injected policy implementation, not in the file store:

  • Key derivation, storage, and rotation
  • Nonce generation (counter-based, random, or derived)
  • The file store only knows nonce_size and passes nonce bytes through — it does not generate or interpret them

File store structure requires no changes

The record format from S05.06 already accommodates this epic:

[ MAGIC    : 2 bytes ]
[ LENGTH   : 2 bytes ]
[ BODY     : n bytes ]   ← encrypted in this epic
[ INTEGRITY: 2 bytes ]   ← becomes authentication tag (may need size increase)
[ SENT     : 1 byte  ]

The integrity_size field in the policy allows the tag size to change without modifying the file store code. The only file store change may be adjusting integrity_size expectations if the tag is larger than 2 bytes (e.g. 16 bytes for GCM).

Out of scope

  • Tamper detection against deliberate modification by an attacker with physical access (that requires secure boot / hardware trust anchors)
  • Key provisioning infrastructure
  • Certificate management

Stories (to be refined when epic is played)

  • Extend SecurityPolicy with encrypt/decrypt and nonce_size
  • Implement AES-GCM or ChaCha20-Poly1305 concrete policy
  • Nonce management strategy (per-record counter stored in file header?)
  • Integration test with encrypted store files
  • BDD scenario: encrypted store survives power cycle and replay

Metadata

Metadata

Assignees

No one assigned

    Labels

    epicEpic issue

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions