Safe API Framework 0.1.0 build 384e6ae
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/rte_checksum.c
 CRC-64 implementation for data integrity checking.

Data Structures

struct  rte_checksum_result_t
 Checksum result for validation. More...
struct  rte_vital_message_t
 Vital channel message with integrated CRC-64. More...
struct  rte_checksum_stats_t
 Checksum statistics for monitoring. More...

Typedefs

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

Enumerations

enum  rte_crc64_polynomial_t { RTE_CRC64_ERTMS , RTE_CRC64_ISO , RTE_CRC64_XZ }
 CRC-64 polynomial selection. More...

Functions

rte_status_t rte_checksum_crc64_init (rte_crc64_polynomial_t polynomial)
 Initialize CRC-64 lookup tables for chosen polynomial.
rte_crc64_t rte_checksum_crc64 (const uint8_t *data, size_t size)
 Compute CRC-64 for data buffer.
rte_status_t rte_checksum_crc64_verify (const uint8_t *data, size_t size, rte_crc64_t expected_crc, rte_checksum_result_t *result_out)
 Verify CRC-64 of data against stored value.
rte_crc64_polynomial_t rte_checksum_crc64_get_polynomial (void)
 Get current CRC-64 polynomial in use.
rte_status_t rte_checksum_vital_message_create (rte_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.
rte_status_t rte_checksum_vital_message_verify (const rte_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.
rte_status_t rte_checksum_get_stats (rte_checksum_stats_t *stats_out)
 Get checksum statistics.
rte_status_t rte_checksum_reset_stats (void)
 Reset checksum statistics.

Detailed Description

Data integrity verification for redundant communication.

REQ-CHECKSUM-001: rte_checksum_crc64_init() shall be callable exactly once; a subsequent call before any re-init mechanism exists shall return RTE_STATUS_ALREADY_INITIALIZED and leave the already-selected table/polynomial unchanged. REQ-CHECKSUM-002: rte_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. 0 is not a valid checksum; the status-returning API shall not report success in this state (REQ-CHECKSUM-009). REQ-CHECKSUM-003: rte_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: rte_checksum_crc64_verify() shall report RTE_STATUS_DATA_CORRUPTION (not merely a boolean) on mismatch and increment stats.verification_failures; on match it shall return RTE_STATUS_OK and increment stats.verification_passes. Before rte_checksum_crc64_init() it shall return RTE_STATUS_NOT_INITIALIZED with result_out->match == 0 and no stats change. REQ-CHECKSUM-005: rte_checksum_vital_message_create() shall reject a payload larger than sizeof(rte_vital_message_t::payload) with RTE_STATUS_INVALID_PARAM, incrementing stats.payload_oversize, without writing msg_out. REQ-CHECKSUM-006: rte_checksum_vital_message_verify() shall verify the message's CRC-64 before trusting any other field, and report RTE_STATUS_DATA_CORRUPTION on a CRC mismatch or a sequence_number that does not equal the caller-supplied expected_sequence (incrementing stats.sequence_errors in the latter case), and forward RTE_STATUS_NOT_INITIALIZED from the CRC check - in both cases without writing payload_out/ payload_size_out. REQ-CHECKSUM-007: rte_checksum_vital_message_verify() shall reject a decoded payload_size exceeding the caller's payload_max_size with RTE_STATUS_INVALID_PARAM, incrementing stats.payload_oversize, without copying into payload_out. REQ-CHECKSUM-008: rte_checksum_get_stats()/_reset_stats() are diagnostics-only (never on a safety-decision path); _get_stats() returns RTE_STATUS_INVALID_PARAM for a NULL stats_out, otherwise both always return RTE_STATUS_OK. REQ-CHECKSUM-009: rte_checksum_crc64_verify(), rte_checksum_vital_message_create() and rte_checksum_vital_message_verify() shall return RTE_STATUS_NOT_INITIALIZED and write neither msg_out nor the payload outputs nor any stats counter while the module is not initialized (ISS-037).

Typedef Documentation

◆ rte_crc64_t

typedef uint64_t rte_crc64_t

CRC-64 checksum value (64-bit).

Definition at line 113 of file rte_checksum.h.

Enumeration Type Documentation

◆ rte_crc64_polynomial_t

CRC-64 polynomial selection.

Different polynomials for different use cases and standards.

Enumerator
RTE_CRC64_ERTMS 

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

RTE_CRC64_ISO 

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

RTE_CRC64_XZ 

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

Definition at line 90 of file rte_checksum.h.

Function Documentation

◆ rte_checksum_crc64_init()

rte_status_t rte_checksum_crc64_init ( rte_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
RTE_STATUS_OK on success RTE_STATUS_ALREADY_INITIALIZED if already initialized RTE_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
rte_crc64_t crc = rte_checksum_crc64(data, size);
uint64_t rte_crc64_t
CRC-64 checksum value (64-bit).
rte_status_t rte_checksum_crc64_init(rte_crc64_polynomial_t polynomial)
Initialize CRC-64 lookup tables for chosen polynomial.
rte_crc64_t rte_checksum_crc64(const uint8_t *data, size_t size)
Compute CRC-64 for data buffer.
@ RTE_CRC64_ERTMS

Definition at line 385 of file rte_checksum.c.

◆ rte_checksum_crc64()

rte_crc64_t rte_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 rte_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 417 of file rte_checksum.c.

◆ rte_checksum_crc64_verify()

rte_status_t rte_checksum_crc64_verify ( const uint8_t * data,
size_t size,
rte_crc64_t expected_crc,
rte_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
RTE_STATUS_OK if verification passed RTE_STATUS_DATA_CORRUPTION if CRC mismatch (data corrupted) RTE_STATUS_INVALID_PARAM if result_out is NULL RTE_STATUS_NOT_INITIALIZED if rte_checksum_crc64_init() has not been called: result_out->match is 0, computed is 0, expected is expected_crc, no stats counter changes (REQ-CHECKSUM-009; the 0 of REQ-CHECKSUM-002 is not a valid checksum)
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 != RTE_STATUS_OK) {
// Data corrupted
rte_log_error("CRC mismatch: expected 0x%llx, got 0x%llx",
result.expected, result.computed);
rte_safestate_trigger(REASON_DATA_CORRUPTION);
}
rte_status_t rte_checksum_crc64_verify(const uint8_t *data, size_t size, rte_crc64_t expected_crc, rte_checksum_result_t *result_out)
Verify CRC-64 of data against stored value.
rte_status_t
Common result/status codes.
Definition rte_status.h:27
@ RTE_STATUS_OK
Definition rte_status.h:28
Checksum result for validation.

Definition at line 470 of file rte_checksum.c.

◆ rte_checksum_crc64_get_polynomial()

rte_crc64_polynomial_t rte_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 514 of file rte_checksum.c.

◆ rte_checksum_vital_message_create()

rte_status_t rte_checksum_vital_message_create ( rte_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
RTE_STATUS_OK on success RTE_STATUS_INVALID_PARAM if msg_out is NULL, payload is too large, or payload is NULL while payload_size is nonzero RTE_STATUS_NOT_INITIALIZED if rte_checksum_crc64_init() has not been called: msg_out is not written (a message built then would carry crc64 == 0, the REQ-CHECKSUM-002 value, which is not a valid checksum; REQ-CHECKSUM-009)
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
rte_ipc_send(channel, &msg, sizeof(msg), timeout_ms);
rte_status_t rte_checksum_vital_message_create(rte_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.
rte_status_t rte_ipc_send(rte_ipc_handle_t handle, const void *message, size_t message_size, rte_duration_ms_t timeout_ms)
Sends one message, blocking at most timeout_ms.
Definition rte_ipc.c:77
Vital channel message with integrated CRC-64.

Definition at line 523 of file rte_checksum.c.

◆ rte_checksum_vital_message_verify()

rte_status_t rte_checksum_vital_message_verify ( const rte_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
RTE_STATUS_OK if all checks pass RTE_STATUS_INVALID_PARAM if msg/payload_out/payload_size_out is NULL, or the decoded payload is larger than payload_max_size RTE_STATUS_DATA_CORRUPTION if the CRC-64 fails or the sequence number does not match expected_sequence RTE_STATUS_NOT_INITIALIZED, forwarded unchanged from rte_checksum_crc64_verify(), if rte_checksum_crc64_init() has not been called; like DATA_CORRUPTION it writes neither payload_out nor payload_size_out (REQ-CHECKSUM-006, REQ-CHECKSUM-009)
Safety:
Deterministic, detects data corruption and reordering

Example:

rte_vital_message_t received_msg;
uint8_t payload_size;
&received_msg,
last_sequence + 1, // expect next sequence
(uint8_t *)&cmd,
sizeof(cmd),
&payload_size
);
if (status == RTE_STATUS_OK) {
// Message valid and sequence OK
last_sequence = received_msg.sequence_number;
} else if (status == RTE_STATUS_ERROR) {
// CRC failed - data corrupted
rte_safestate_trigger(REASON_DATA_CORRUPTION);
} else if (status == RTE_STATUS_INVALID) {
// Sequence out of order
rte_safestate_trigger(REASON_MESSAGE_REORDERING);
}
rte_status_t rte_checksum_vital_message_verify(const rte_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 581 of file rte_checksum.c.

◆ rte_checksum_get_stats()

rte_status_t rte_checksum_get_stats ( rte_checksum_stats_t * stats_out)

Get checksum statistics.

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

Parameters
stats_outReceives statistics
Returns
RTE_STATUS_OK on success RTE_STATUS_INVALID_PARAM if stats_out is NULL

Definition at line 647 of file rte_checksum.c.

◆ rte_checksum_reset_stats()

rte_status_t rte_checksum_reset_stats ( void )

Reset checksum statistics.

Clears all counters. Useful for per-cycle diagnostics.

Returns
RTE_STATUS_OK always

Definition at line 657 of file rte_checksum.c.