Verification
The verification library adds reusable, allocation-free no_std cryptographic primitives (Core #518). It is not a package manager, signature-policy engine, trust store, file-format parser, or a runtime enforcement mechanism. No firmware consumer enables cryptographic package verification by default.
API and feature selection
The default sha256 Cargo feature provides two streaming interfaces:
Sha256Verifiercomputes a complete SHA-256 digest incrementally.ContentVerifier::new(expected_length, expected_digest)checks the exact logical length and the complete 32-byte expected digest of a streamed payload.
update takes caller-provided byte slices; the library does not allocate a full-file buffer. Stream length and update failures permanently poison the verifier, even when a caller ignores an error. Finalizing before the declared length is consumed fails. The logical SHA-256 input length is bounded to 2^61 - 1 bytes.
The optional ed25519 feature exposes validated PublicKey instances, accepting 32-byte public keys and 64-byte signatures. Verification uses Dalek's strict Ed25519 check on the exact supplied message bytes, rejecting invalid and weak key encodings. This is not Ed25519ph, a signing API, or a way to authenticate keys found inside untrusted packages. A zero-feature build exports only typed errors/results.
use verification::ContentVerifier;
// Authenticate the expected length/digest independently before accepting content.
let mut verifier = ContentVerifier::new(expected_len, expected_sha256)?;
for chunk in chunks {
verifier.update(chunk)?;
}
verifier.verify()?;The values expected_len, expected_sha256 and chunks are inputs supplied by the caller; this illustrates the interface, not a working package installation.
Integration and trust boundaries
SHA-256 detects differences relative to a trusted expected digest; by itself it does not provide authenticity. Ed25519 verification establishes the signature over supplied bytes only when the public key is already trusted. Package identity, version, rollback defense, target/ABI compatibility and permission grants must be defined by a separately authenticated manifest and policy.
Core tracks those follow-up responsibilities in #402 (canonical manifest and signed bytes), #491 (trusted staging/activation) and #495 (loader enforcement/TOCTOU). None is delivered by this library. The existing VFS hash device is unchanged and still uses an allocating, dynamically dispatched context; direct verification calls deliberately avoid that context.
Memory evidence and validation
On native x86_64, live state has been measured at 120 bytes for the incremental SHA-256 verifier, 160 bytes for a content verifier and 192 bytes for a validated public key. Focused tests report no heap allocations in the verification paths, but these sizes exclude caller buffers, peak stack and dependencies.
Cortex-M4, browser WASM and native no-allocator link probes passed, and four feature combinations were tested. These were compile/link checks, not actual MCU or browser execution. No safe MCU task-stack, total-RAM budget, flash estimate or on-device latency has been established.
Focused validation from Core's root:
bash libraries/verification/check.sh
bash tools/verification_probe/check.sh thumbv7em-none-eabi
COMPACT_SHA2=1 bash tools/verification_probe/check.sh thumbv7em-none-eabiCI runs these through mise -E ci run ci:verification. Keep package verification integration and hardware safety gates separate from this primitive library.
Sources and related documentation
verificationcrate — Rust API documentation.libraries/verification/src/lib.rs— exports and feature boundaries.libraries/verification/src/hash.rs— streaming hashing and exact-length content checks.libraries/verification/src/signature.rs— strict Ed25519 verification.libraries/verification/README.md— tests, measurements and integration caveats.tools/verification_probe/README.md— no-allocator final-link probes.- File-system contract — separate storage capabilities.