Enable support for hardware acceleration
- Dominant language
- C
- Stars
- 2
- Forks
- 0
- Avg merge
- 1h 20m
- Merged PRs (30d)
- 74
Description
# Optional hooks for hardware crypto acceleration
Many target MCUs and SoCs ship AES, SHA-256, or public-key
accelerators that sit unused because the library computes everything
in software. On battery-powered or latency-sensitive devices this is
a real cost, and it is one of the few features that would make
chapulin materially better on hardware people already have.
## Design
Optional, compile-time, and off by default. A platform that defines
nothing keeps today's behavior exactly, including today's proofs.
- **One-shot SHA-256 only, bulk path only.** Not the streaming
`init`/`update`/`final` API. The transcript hash and HKDF stay in
software unconditionally — see the size threshold below, which
makes offloading them actively harmful. This also avoids asking a
platform to implement streaming state on top of a one-shot engine.
- Do not add hooks for primitives where software is already the right
answer (ChaCha20, Poly1305) unless a concrete target justifies it.
A future AES-CCM build would be the next candidate, not this one.
- The hook replaces the implementation wholesale rather than
interleaving with it: a partial-offload design would multiply the
states the proofs must cover.
- **The hook is synchronous and blocking, and the issue says so
rather than pretending otherwise.** Real crypto peripherals are
register-configured and DMA-driven: configure, start, then poll a
status bit or wait on an interrupt. A synchronous wrapper must busy-
poll or block the calling task for the duration. That is acceptable
here — chapulin already blocks in `recv` — but it must be stated so
an RTOS integrator can decide whether to gate the hook by message
size.
- No allocation and no hidden state, matching `ch_rand_bytes` and the
I/O hooks.
## The size threshold is the feature's correctness condition
Hardware crypto engines are usually *slower* than software on small
inputs: the RTL838x engine, for example, is 8-10x slower than
software at small block sizes, breaks even around 256 bytes, and
reaches roughly 2x only on large blocks. Chapulin hashes many small
things — transcript updates are message-sized and HKDF operates on
32-byte secrets. Routing every SHA-256 call through an accelerator
would make the handshake **slower**, which is the opposite of the
feature's purpose.
Therefore:
- The hook applies only to bulk hashing above a documented size
threshold. Below it, software runs regardless of whether a hook is
defined.
- The threshold is a build-time constant the platform can override,
with a documented default and a note that it must be measured per
target, not assumed.
- Document that a platform whose workload never exceeds the
threshold should not enable the hook at all.
## Contention, buffers, and the integrator's obligations
State these plainly; they are the failure modes that pass testing and
break in the field:
- **Contention.** The engine is a shared peripheral. Another task,
core, or DMA-driven path may hold it. Define the hook's contract on
busy: return a distinguished code and have chapulin fall back to
software for that call. Never retry-forever, never fail the
handshake over a busy peripheral.
- **DMA buffers.** Engines commonly require aligned,
physically-contiguous, cache-coherent memory. Chapulin's buffers
live in caller memory or the session struct with no alignment
guarantee, and on a system with a data cache the engine may read
stale lines unless the driver flushes. Copying into a
driver-owned bounce buffer is the integrator's responsibility;
say so, because silent corruption here is the classic bug in this
pattern.
- **ABI versioning.** Define a `CH_HW_HOOK_ABI` version macro the
platform must match, so a later signature change fails at compile
time rather than subtly at runtime.
## What must be stated in the documentation
- **The proofs do not transfer.** CBMC proves the software
implementations. A platform substituting its own SHA-256 is
responsible for that implementation's memory safety and
constant-time behavior. Say this plainly next to the hook.
- **Constant-time is the platform's problem too.** A hardware engine
is not automatically constant-time, and a driver wrapping it may
not be. The invariants document should record that enabling a hook
moves INV-16's guarantee for that primitive from the library to
the platform.
- The Lean differential and the vector suites still run against the
software path, so a build with hooks enabled is testing less. State
what coverage is lost.
## Work items
- [ ] Add the one-shot SHA-256 hook, the size threshold constant, and
a default that keeps current behavior byte-for-byte when no
hook is defined.
- [ ] Define and document the busy/fallback contract and the
`CH_HW_HOOK_ABI` macro.
- [ ] Test the substitution properly: run the Lean differential
against a build with the hook enabled and a stub that
deliberately diverges on one input, and confirm the differential
catches it. Exercising the path is not enough; the point is
proving the hook path is genuinely under test.
- [ ] Confirm the transcript and HKDF paths never reach the hook,
by test.
- [ ] `docs/invariants.md`: the INV-16 delegation note.
- [ ] README: the hook, and the assurance caveat.
## Acceptance criteria
- With no hook defined, the build and the proofs are unchanged,
byte-for-byte.
- With a hook defined, a deliberately-divergent stub is caught by the
differential.
- Transcript and HKDF hashing provably never reach the hook.
- The documentation states the size threshold, the busy contract, the
DMA/alignment obligations, and which guarantees move to the
platform.
Contributor guide
Research direction
Start by locating the one-shot SHA-256 software path and the transcript and HKDF paths, then review docs/invariants.md and the README requirements. Run the Lean differential and vector suites against the software path before testing an enabled hook with a deliberately divergent stub. Done means the threshold, busy fallback, ABI, DMA obligations, coverage caveat, and INV-16 delegation note are documented and the acceptance tests pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- cryptography, embedded-iot, performance, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100