|
Safe Data API
CRC-protected (optionally redundant) data containers for Zephyr
|
|
v0.0-dev+gbb519af | |
Type-erased core operations; all integrity logic in one audited place. More...
Macros | |
| #define | SAFE_DATA_RECOVERED (-EAGAIN) |
| Return code for a fault that the redundant shadow copy covers. | |
Typedefs | |
| typedef int(* | safe_data_mutator_t) (void *payload, void *user) |
| Mutator callback used by safe_data_update() / SAFE_UPDATE(). | |
Functions | |
| int | safe_data_init (struct k_mutex *lock, void *payload, size_t len, uint32_t *crc, void *shadow) |
| Initialise the lock and seal the current payload contents. | |
| int | safe_data_verify (const void *payload, size_t len, uint32_t crc, const void *shadow) |
| Verify payload integrity. Pure: read-only and lock-free; it NEVER modifies the payload, so it is safe to call concurrently with writers (a transient mismatch may then be reported - callers needing atomicity should use the higher-level helpers). | |
| int | safe_data_verify_repair (void *payload, size_t len, uint32_t crc, void *shadow) |
| Verify payload integrity and repair a recoverable fault in place. | |
| int | safe_data_read (struct k_mutex *lock, void *payload, size_t len, uint32_t *crc, void *shadow, void *out) |
Verify under lock and copy the payload out to out. | |
| int | safe_data_write (struct k_mutex *lock, void *payload, size_t len, uint32_t *crc, void *shadow, const void *in) |
Copy in into the payload under lock and reseal the integrity tag. | |
| int | safe_data_update (struct k_mutex *lock, void *payload, size_t len, uint32_t *crc, void *shadow, safe_data_mutator_t fn, void *user) |
Atomic read-modify-write: lock, verify, run fn, reseal on success. | |
| int | safe_data_commit (struct k_mutex *lock, void *payload, size_t len, uint32_t *crc, void *shadow) |
| Reseal after an explicit external modification (advanced use). Lock, recompute the integrity tag, unlock. | |
Type-erased core operations; all integrity logic in one audited place.
Application code should prefer the typed container layer (Containers and Typed Access) - the macros there only derive (&payload, sizeof(payload), &crc, &lock, shadow) from a typed container and forward to these functions.
| #define SAFE_DATA_RECOVERED (-EAGAIN) |
Return code for a fault that the redundant shadow copy covers.
From safe_data_verify() (pure) it means the fault is recoverable: the payload was NOT modified. From safe_data_verify_repair() it means the payload has been repaired in place and is valid again once the tag is resealed.
Definition at line 83 of file safe_data.h.
Referenced by safe_data_read(), safe_data_selftest(), safe_data_update(), safe_data_verify_repair(), and verify_quiet().
| typedef int(* safe_data_mutator_t) (void *payload, void *user) |
Mutator callback used by safe_data_update() / SAFE_UPDATE().
Invoked with the lock held and the payload already verified. Mutate payload in place. Return 0 to commit (the integrity tag is resealed) or a negative errno to abort (the payload is rolled back / left as-is and NOT resealed). A positive return value is a contract violation: it is clamped to -EINVAL, the transaction aborts, and the event is counted in the statistics.
| payload | Pointer to the (verified) payload, cast to its real type. |
| user | Opaque user context forwarded from the call site. |
Definition at line 98 of file safe_data.h.
| int safe_data_commit | ( | struct k_mutex * | lock, |
| void * | payload, | ||
| size_t | len, | ||
| uint32_t * | crc, | ||
| void * | shadow ) |
Reseal after an explicit external modification (advanced use). Lock, recompute the integrity tag, unlock.
| lock | Container mutex, or NULL to skip locking. |
| payload | Payload buffer whose current contents are sealed as-is. |
| len | Payload size in bytes (> 0). |
| crc | Integrity tag storage (recomputed). |
| shadow | Redundant shadow buffer of len bytes (refreshed), or NULL if disabled. |
Definition at line 454 of file safe_data.c.
References safe_data_fault_info::len, SAFE_DATA_FAULT_KIND_LOCK_TIMEOUT, and safe_event().
Satisfies requirements SD-REQ-002 (Argument validation), SD-REQ-014 (Bounded lock acquisition), SD-REQ-015 (No ISR-context locking), SD-REQ-016 (Serialised access — no torn snapshots), SD-REQ-020 (Reduced API surface at the Strict level), and SD-REQ-022 (Unchecked commit).
| int safe_data_init | ( | struct k_mutex * | lock, |
| void * | payload, | ||
| size_t | len, | ||
| uint32_t * | crc, | ||
| void * | shadow ) |
Initialise the lock and seal the current payload contents.
Must be called once before any other operation. The payload should be fully written (no indeterminate padding) before sealing.
| lock | Container mutex (initialised here). |
| payload | Payload buffer. |
| len | Payload size in bytes (> 0). |
| crc | Integrity tag storage. |
| shadow | Redundant shadow buffer of len bytes, or NULL if disabled. |
Definition at line 224 of file safe_data.c.
References safe_data_fault_info::len.
Satisfies requirements SD-REQ-001 (Sealing on initialisation), and SD-REQ-002 (Argument validation).
| int safe_data_read | ( | struct k_mutex * | lock, |
| void * | payload, | ||
| size_t | len, | ||
| uint32_t * | crc, | ||
| void * | shadow, | ||
| void * | out ) |
Verify under lock and copy the payload out to out.
A recoverable fault is repaired and resealed before copying, so a 0 return always means out holds a valid snapshot.
| lock | Container mutex, or NULL to skip locking. |
| payload | Payload buffer. |
| len | Payload size in bytes (> 0). |
| crc | Integrity tag storage (resealed after a repair). |
| shadow | Redundant shadow buffer of len bytes, or NULL if disabled. |
| out | Destination buffer of len bytes for the validated copy. |
Definition at line 326 of file safe_data.c.
References safe_data_fault_info::len, SAFE_DATA_FAULT_KIND_LOCK_TIMEOUT, SAFE_DATA_RECOVERED, safe_data_verify_repair(), and safe_event().
Satisfies requirements SD-REQ-002 (Argument validation), SD-REQ-005 (Validated read), SD-REQ-014 (Bounded lock acquisition), SD-REQ-015 (No ISR-context locking), and SD-REQ-016 (Serialised access — no torn snapshots).
| int safe_data_update | ( | struct k_mutex * | lock, |
| void * | payload, | ||
| size_t | len, | ||
| uint32_t * | crc, | ||
| void * | shadow, | ||
| safe_data_mutator_t | fn, | ||
| void * | user ) |
Atomic read-modify-write: lock, verify, run fn, reseal on success.
This is the correct "checkout": the lock is held for the entire transaction and the integrity tag is resealed automatically, so it can never go stale.
| lock | Container mutex, or NULL to skip locking. |
| payload | Payload buffer, verified before and resealed after fn. |
| len | Payload size in bytes (> 0). |
| crc | Integrity tag storage (resealed on commit). |
| shadow | Redundant shadow buffer of len bytes, or NULL if disabled (without it an aborting mutator must not have modified the payload - there is no rollback buffer). |
| fn | Mutator invoked with the lock held and the payload verified. |
| user | Opaque context forwarded to fn. |
Definition at line 386 of file safe_data.c.
References safe_data_fault_info::len, SAFE_DATA_FAULT_KIND_LOCK_TIMEOUT, SAFE_DATA_FAULT_KIND_MUTATOR_CLAMPED, SAFE_DATA_RECOVERED, safe_data_verify_repair(), and safe_event().
Satisfies requirements SD-REQ-002 (Argument validation), SD-REQ-007 (Transactional read-modify-write), SD-REQ-008 (Mutator contract enforcement), SD-REQ-014 (Bounded lock acquisition), SD-REQ-015 (No ISR-context locking), and SD-REQ-016 (Serialised access — no torn snapshots).
| int safe_data_verify | ( | const void * | payload, |
| size_t | len, | ||
| uint32_t | crc, | ||
| const void * | shadow ) |
Verify payload integrity. Pure: read-only and lock-free; it NEVER modifies the payload, so it is safe to call concurrently with writers (a transient mismatch may then be reported - callers needing atomicity should use the higher-level helpers).
| payload | Payload buffer to check. |
| len | Payload size in bytes (> 0). |
| crc | Stored integrity tag to check against. |
| shadow | Redundant shadow buffer of len bytes, or NULL if disabled. |
Definition at line 277 of file safe_data.c.
References safe_data_fault_info::len, SAFE_DATA_FAULT_KIND_UNRECOVERABLE, safe_event(), and verify_quiet().
Satisfies requirements SD-REQ-002 (Argument validation), SD-REQ-003 (Pure verification), and SD-REQ-011 (Configurable unrecoverable-fault reaction).
| int safe_data_verify_repair | ( | void * | payload, |
| size_t | len, | ||
| uint32_t | crc, | ||
| void * | shadow ) |
Verify payload integrity and repair a recoverable fault in place.
MUST be called with the container lock held (or with equivalent external mutual exclusion): the repair writes to the payload, and doing that concurrently with a writer would corrupt live data. The locked helpers (read/update/SAFE_SECTION) call this internally; after SAFE_DATA_RECOVERED the caller reseals the stored tag to make the repair durable.
| payload | Payload buffer to check and, if recoverable, repair in place. |
| len | Payload size in bytes (> 0). |
| crc | Stored integrity tag to check against. |
| shadow | Redundant shadow buffer of len bytes, or NULL if disabled. |
Definition at line 290 of file safe_data.c.
References safe_data_fault_info::len, payload_matches_shadow(), SAFE_DATA_FAULT_KIND_RECOVERED_PAYLOAD, SAFE_DATA_FAULT_KIND_RECOVERED_TAG, SAFE_DATA_FAULT_KIND_UNRECOVERABLE, SAFE_DATA_RECOVERED, safe_event(), and verify_quiet().
Referenced by safe_data_read(), safe_data_selftest(), and safe_data_update().
Satisfies requirements SD-REQ-002 (Argument validation), SD-REQ-004 (In-place repair under mutual exclusion), SD-REQ-009 (Single-copy fault recovery), SD-REQ-010 (Double-fault detection), and SD-REQ-011 (Configurable unrecoverable-fault reaction).
| int safe_data_write | ( | struct k_mutex * | lock, |
| void * | payload, | ||
| size_t | len, | ||
| uint32_t * | crc, | ||
| void * | shadow, | ||
| const void * | in ) |
Copy in into the payload under lock and reseal the integrity tag.
With CONFIG_SAFE_DATA_WRITE_CHECKS_OLD the previous contents are verified first; a detected corruption is reported (stats + fault callback, kind OVERWRITTEN) but does not change the outcome of the write.
| lock | Container mutex, or NULL to skip locking. |
| payload | Payload buffer (overwritten). |
| len | Payload size in bytes (> 0). |
| crc | Integrity tag storage (resealed). |
| shadow | Redundant shadow buffer of len bytes, or NULL if disabled. |
| in | Source buffer of len bytes to copy into the payload. |
Definition at line 354 of file safe_data.c.
References safe_data_fault_info::len, SAFE_DATA_FAULT_KIND_LOCK_TIMEOUT, SAFE_DATA_FAULT_KIND_OVERWRITTEN, safe_event(), and verify_quiet().
Satisfies requirements SD-REQ-002 (Argument validation), SD-REQ-006 (Atomic sealed write), SD-REQ-014 (Bounded lock acquisition), SD-REQ-015 (No ISR-context locking), SD-REQ-016 (Serialised access — no torn snapshots), and SD-REQ-018 (Write may not silently mask corruption).