Safe API Framework
Layered API framework for safety-related applications (ERTMS RBC reference targeting CENELEC EN 50128 SIL 4)
Loading...
Searching...
No Matches
Checksum & CRC Utilities

Data integrity verification for redundant communication. More...

Files

file  src/redundancy/checksum/sapi_checksum.c
 CRC-64 implementation for data integrity checking.

Data Structures

struct  sapi_checksum_result_t
 Checksum result for validation. More...
struct  sapi_vital_message_t
 Vital channel message with integrated CRC-64. More...
struct  sapi_checksum_stats_t
 Checksum statistics for monitoring. More...

Typedefs

typedef uint64_t sapi_crc64_t
 CRC-64 checksum value (64-bit).

Enumerations

enum  sapi_crc64_polynomial_t { SAPI_CRC64_ERTMS , SAPI_CRC64_ISO , SAPI_CRC64_XZ }
 CRC-64 polynomial selection. More...

Functions

sapi_status_t sapi_checksum_crc64_init (sapi_crc64_polynomial_t polynomial)
 Initialize CRC-64 lookup tables for chosen polynomial.
sapi_crc64_t sapi_checksum_crc64 (const uint8_t *data, size_t size)
 Compute CRC-64 for data buffer.
sapi_status_t sapi_checksum_crc64_verify (const uint8_t *data, size_t size, sapi_crc64_t expected_crc, sapi_checksum_result_t *result_out)
 Verify CRC-64 of data against stored value.
sapi_crc64_polynomial_t sapi_checksum_crc64_get_polynomial (void)
 Get current CRC-64 polynomial in use.
sapi_status_t sapi_checksum_vital_message_create (sapi_vital_message_t *msg_out, uint32_t sender_id, uint32_t sequence, const uint8_t *payload, size_t payload_size)
 Create vital channel message with CRC.
sapi_status_t sapi_checksum_vital_message_verify (const sapi_vital_message_t *msg, uint32_t expected_sequence, uint8_t *payload_out, size_t payload_max_size, uint8_t *payload_size_out)
 Verify vital channel message and extract payload.
sapi_status_t sapi_checksum_get_stats (sapi_checksum_stats_t *stats_out)
 Get checksum statistics.
sapi_status_t sapi_checksum_reset_stats (void)
 Reset checksum statistics.

Detailed Description

Data integrity verification for redundant communication.

REQ-CHECKSUM-001: sapi_checksum_crc64_init() shall be callable exactly once; a subsequent call before any re-init mechanism exists shall return SAPI_STATUS_ALREADY_INITIALIZED and leave the already-selected table/polynomial unchanged. REQ-CHECKSUM-002: sapi_checksum_crc64() shall return 0 - never dereferencing data - if the module is not yet initialized, if its lookup table is unset, or if data is NULL while size is nonzero. REQ-CHECKSUM-003: sapi_checksum_crc64() shall be deterministic and O(n) in size, using a precomputed 256-entry lookup table (no bit-by-bit computation on the hot path). REQ-CHECKSUM-004: sapi_checksum_crc64_verify() shall report SAPI_STATUS_DATA_CORRUPTION (not merely a boolean) on mismatch and increment stats.verification_failures; on match it shall return SAPI_STATUS_OK and increment stats.verification_passes. REQ-CHECKSUM-005: sapi_checksum_vital_message_create() shall reject a payload larger than sizeof(sapi_vital_message_t::payload) with SAPI_STATUS_INVALID_PARAM, incrementing stats.payload_oversize, without writing msg_out. REQ-CHECKSUM-006: sapi_checksum_vital_message_verify() shall verify the message's CRC-64 before trusting any other field, and report SAPI_STATUS_DATA_CORRUPTION - without writing to payload_out/payload_size_out - on either a CRC mismatch or a sequence_number that does not equal the caller-supplied expected_sequence (incrementing stats.sequence_errors in the latter case). REQ-CHECKSUM-007: sapi_checksum_vital_message_verify() shall reject a decoded payload_size exceeding the caller's payload_max_size with SAPI_STATUS_INVALID_PARAM, incrementing stats.payload_oversize, without copying into payload_out. REQ-CHECKSUM-008: sapi_checksum_get_stats()/_reset_stats() are diagnostics-only (never on a safety-decision path); _get_stats() returns SAPI_STATUS_INVALID_PARAM for a NULL stats_out, otherwise both always return SAPI_STATUS_OK.

Typedef Documentation

◆ sapi_crc64_t

typedef uint64_t sapi_crc64_t

CRC-64 checksum value (64-bit).

Definition at line 100 of file sapi_checksum.h.

Enumeration Type Documentation

◆ sapi_crc64_polynomial_t

CRC-64 polynomial selection.

Different polynomials for different use cases and standards.

Enumerator
SAPI_CRC64_ERTMS 

ERTMS/ETCS standard: 0x1D4F63B86E40E541 Used in railway signaling systems, EN 50128 compliant

SAPI_CRC64_ISO 

ISO 3309 / HDLC standard: 0x000000000000001B Commonly used in communication protocols

SAPI_CRC64_XZ 

XZ/LZMA standard: 0x142F0E1EBA9EA3C3 Alternative for high-reliability systems

Definition at line 77 of file sapi_checksum.h.

Function Documentation

◆ sapi_checksum_crc64_init()

sapi_status_t sapi_checksum_crc64_init ( sapi_crc64_polynomial_t polynomial)

Initialize CRC-64 lookup tables for chosen polynomial.

Must be called once at startup before using CRC-64 functions. Generates lookup tables for O(1) byte-at-a-time computation.

Parameters
polynomialCRC polynomial to use (ERTMS, ISO, or XZ)
Returns
SAPI_STATUS_OK on success SAPI_STATUS_ALREADY_INITIALIZED if already initialized SAPI_STATUS_INVALID_PARAM if polynomial is not a recognized value
Safety:
Safety-critical function, may not be called multiple times

Example:

// At startup
// Later, use CRC functions
uint64_t sapi_crc64_t
CRC-64 checksum value (64-bit).
sapi_crc64_t sapi_checksum_crc64(const uint8_t *data, size_t size)
Compute CRC-64 for data buffer.
sapi_status_t sapi_checksum_crc64_init(sapi_crc64_polynomial_t polynomial)
Initialize CRC-64 lookup tables for chosen polynomial.
@ SAPI_CRC64_ERTMS

Definition at line 375 of file sapi_checksum.c.

◆ sapi_checksum_crc64()

sapi_crc64_t sapi_checksum_crc64 ( const uint8_t * data,
size_t size )

Compute CRC-64 for data buffer.

Computes CRC-64 using pre-computed lookup tables (O(1) per byte). Execution time is deterministic and bounded.

Parameters
dataData buffer to checksum (may be NULL if size=0)
sizeSize in bytes (0 to MAX_SIZE)
Returns
64-bit CRC value
Safety:
Deterministic, no dynamic allocation, bounded execution time

Note: Call sapi_checksum_crc64_init() before first use.

Example:

train_command_t cmd = {...};
// Compute CRC on data (excluding CRC field itself)
(const uint8_t *)&cmd,
sizeof(cmd) - sizeof(cmd->crc64)
);
// Store in message
cmd.crc64 = crc;

Definition at line 407 of file sapi_checksum.c.

◆ sapi_checksum_crc64_verify()

sapi_status_t sapi_checksum_crc64_verify ( const uint8_t * data,
size_t size,
sapi_crc64_t expected_crc,
sapi_checksum_result_t * result_out )

Verify CRC-64 of data against stored value.

Computes CRC-64 and compares to expected value. Returns detailed result for diagnostics.

Parameters
dataData buffer to verify
sizeSize in bytes
expected_crcExpected CRC-64 value (from message)
result_outReceives verification result
Returns
SAPI_STATUS_OK if verification passed SAPI_STATUS_DATA_CORRUPTION if CRC mismatch (data corrupted) SAPI_STATUS_INVALID_PARAM if result_out is NULL
Safety:
Deterministic computation, safe for safety-critical paths

Example:

(const uint8_t *)&received_cmd,
sizeof(received_cmd) - sizeof(received_cmd->crc64),
received_cmd.crc64,
&result
);
if (status != SAPI_STATUS_OK) {
// Data corrupted
sapi_log_error("CRC mismatch: expected 0x%llx, got 0x%llx",
result.expected, result.computed);
sapi_safestate_trigger(REASON_DATA_CORRUPTION);
}
sapi_status_t sapi_checksum_crc64_verify(const uint8_t *data, size_t size, sapi_crc64_t expected_crc, sapi_checksum_result_t *result_out)
Verify CRC-64 of data against stored value.
sapi_status_t
Common result/status codes.
Definition sapi_status.h:27
@ SAPI_STATUS_OK
Definition sapi_status.h:28
Checksum result for validation.

Definition at line 460 of file sapi_checksum.c.

◆ sapi_checksum_crc64_get_polynomial()

sapi_crc64_polynomial_t sapi_checksum_crc64_get_polynomial ( void )

Get current CRC-64 polynomial in use.

Returns the polynomial that was initialized at startup. Useful for logging and diagnostics.

Returns
Current polynomial (ERTMS, ISO, or XZ)

Definition at line 493 of file sapi_checksum.c.

◆ sapi_checksum_vital_message_create()

sapi_status_t sapi_checksum_vital_message_create ( sapi_vital_message_t * msg_out,
uint32_t sender_id,
uint32_t sequence,
const uint8_t * payload,
size_t payload_size )

Create vital channel message with CRC.

Wraps payload data with sequence number, timestamp, and CRC-64.

Parameters
msg_outMessage to fill
sender_idID of sending channel/site
sequenceSequence number for this message
payloadData to send
payload_sizeSize of payload (max 248 bytes)
Returns
SAPI_STATUS_OK on success SAPI_STATUS_INVALID_PARAM if msg_out is NULL, payload is too large, or payload is NULL while payload_size is nonzero
Safety:
No dynamic allocation, deterministic execution

Example:

train_command_t cmd = {...};
&msg,
CHANNEL_A, // sender
++sequence_num, // sequence
(const uint8_t *)&cmd,
sizeof(cmd)
);
// Send msg over network
sapi_ipc_send(channel, &msg, sizeof(msg), timeout_ms);
sapi_status_t sapi_checksum_vital_message_create(sapi_vital_message_t *msg_out, uint32_t sender_id, uint32_t sequence, const uint8_t *payload, size_t payload_size)
Create vital channel message with CRC.
sapi_status_t sapi_ipc_send(sapi_ipc_handle_t handle, const void *message, size_t message_size, sapi_duration_ms_t timeout_ms)
Sends one message, blocking at most timeout_ms.
Definition sapi_ipc.c:68
Vital channel message with integrated CRC-64.

Definition at line 502 of file sapi_checksum.c.

◆ sapi_checksum_vital_message_verify()

sapi_status_t sapi_checksum_vital_message_verify ( const sapi_vital_message_t * msg,
uint32_t expected_sequence,
uint8_t * payload_out,
size_t payload_max_size,
uint8_t * payload_size_out )

Verify vital channel message and extract payload.

Verifies CRC-64, checks sequence number continuity, and extracts payload. Returns error if any check fails.

Parameters
msgReceived message to verify
expected_sequenceExpected sequence number (for continuity check)
payload_outBuffer to receive extracted payload
payload_max_sizeMax size of payload buffer
payload_size_outReceives actual payload size
Returns
SAPI_STATUS_OK if all checks pass SAPI_STATUS_INVALID_PARAM if msg/payload_out/payload_size_out is NULL, or the decoded payload is larger than payload_max_size SAPI_STATUS_DATA_CORRUPTION if the CRC-64 fails or the sequence number does not match expected_sequence
Safety:
Deterministic, detects data corruption and reordering

Example:

sapi_vital_message_t received_msg;
train_command_t cmd;
uint8_t payload_size;
&received_msg,
last_sequence + 1, // expect next sequence
(uint8_t *)&cmd,
sizeof(cmd),
&payload_size
);
if (status == SAPI_STATUS_OK) {
// Message valid and sequence OK
last_sequence = received_msg.sequence_number;
} else if (status == SAPI_STATUS_ERROR) {
// CRC failed - data corrupted
sapi_safestate_trigger(REASON_DATA_CORRUPTION);
} else if (status == SAPI_STATUS_INVALID) {
// Sequence out of order
sapi_safestate_trigger(REASON_MESSAGE_REORDERING);
}
sapi_status_t sapi_checksum_vital_message_verify(const sapi_vital_message_t *msg, uint32_t expected_sequence, uint8_t *payload_out, size_t payload_max_size, uint8_t *payload_size_out)
Verify vital channel message and extract payload.

Definition at line 556 of file sapi_checksum.c.

◆ sapi_checksum_get_stats()

sapi_status_t sapi_checksum_get_stats ( sapi_checksum_stats_t * stats_out)

Get checksum statistics.

Returns counters useful for monitoring data integrity and diagnosing communication issues.

Parameters
stats_outReceives statistics
Returns
SAPI_STATUS_OK on success SAPI_STATUS_INVALID_PARAM if stats_out is NULL

Definition at line 616 of file sapi_checksum.c.

◆ sapi_checksum_reset_stats()

sapi_status_t sapi_checksum_reset_stats ( void )

Reset checksum statistics.

Clears all counters. Useful for per-cycle diagnostics.

Returns
SAPI_STATUS_OK always

Definition at line 626 of file sapi_checksum.c.