Expand description
embedded-cal is a family of interface traits around cryptography, primarily Cal.
Users of the trait can implement their high-level cryptographic protocol implementation libraries or applications on top of the trait, and leverage hardware acceleration available on some platforms, without being tied to a particular implementation of the algorithms or a aprticular acceleration module.
Providers of the trait can be software implementations, specific hardware platforms, or embedded operating systems that provide whichever acceleration or algorithms are configured for a givens build.
Neither the users or nor the providers are generally implemented in this crate; however, being the centerpiece of the embedded-cal ecosystem, this documentation points to some noteworthy implementations outside the crate.
§How to use this crate
§… as a user
When a library you use requires you to pass in an implementation of Cal, their functions
are generic over implementations of Cal.
Depending on the system you use the library on, you can obtain a suitable instance to pass in from:
- Your operating system.
- On embedded systems, this can be provided explicitly by the RTOS (e.g. work in progress in Ariel OS and RIOT OS).
- On
stdsystems, you can use software based implementations, which (while fundamentally composable) generally offer a feature for ready-to-use construction (e.g.embedded_cal_libcrux::Standalone::standalone()orembedded_cal_rustcrypto::Standalone::standalone().
- When developing on bare metal, an implementation such as
embedded-cal-nrf54l15can be constructed from the underlying hardware registers, and later augmented with software layers.
Examples of these are in
embedded-cal-examples/src/bin/demo.rs
– depending on the components selected by features, the Cal instance is constructed through
a standalone constructor or by composition.
§… as a high-level library author
When writing a library, be generic over Cal implementations.
Where possible, it is recommended to take short-lived references to a Cal, because this
enables users to go with a lock-free exclusive version where that is an advantage.
An example of this is in
embedded-cal-examples/src/lib.rs:
Some of the operations work from a selection of algorithms for agility,
some pick fixed algorithm (and fail if it is unsupported; with future Rust versions this can
become a build time failure),
§… when wrapping hardware
Most parts of the Cal trait are optional to implement, in the sense that supporting no
algorithms is easy. (This is the reason why rather than having a single trait, there is an
Cal::AeadProvider iand .aead() accessor: If your hardware can not do it,
just don’t provide it.
In particular, for many aspects (list growing), there are “plumbing” traits you can implement
instead. For example, for SHA2, implement
plumbing::hash::Sha2Short and set SUPPORTED = true. While this does not
immediately give the users access to the algorithms, a higher-up wrapper can pick up the parts
and fill in the gaps. This way, edge-case prone buffer handling can be done by more carefully
vetted components rather than being repetitively implemented.
§… as an embedded RTOS maintainer
Provide an easy single type implementing Cal. Configuration should happen outside of the
RTOS, typically in system-wide build configuration. By default, it is recommended to build from
whichever accelerated type is available for the hardware, and use
embedded-cal-libcrux
to fill gaps.
On many systems, that type needs to be a singleton and can not be shared (e.g. because it needs exclusive access to some registers).
On systems where mutex-style access is widespread, provide a mutex based implementation that can be shared / cloned easily, so that libraries that can not do everything in short-lived operations can be given something to work with. This API can be enabled conditionally based on whether any user in the current build requests it.
It is recommended to also have an accessor for short-time access available unconditionally. If the mutex based API is requested, this merely hands out another copy of the shared instance; otherwise, it can use a simpler run-time (or even build-time) check.
§Distinguishing properties and related work
The interfaces of this crate are geared towards cryptographic agility: An application should
not need to be changed in order to support a larger set of hash functions or elliptic curves.
This is aligned with how higher-level cryptographic systems such as COSE or TLS work:
algorithms are negotiated rather than built into the protocol. In this, embedded-cal is
distinct from many rustcrypto traits such as aead or
digest, through which generic application code gets
monomorphized onto a concrete algorithm.
The crates focus on the Embedded Rust ecosystem, which includes bare metal and RTOS
applications. It is no_std, and does not use dynamic allocation in general. In this,
embedded-cal is distinct from the otherwise similar PSA Crypto
API (which uses C embedded idioms).
Implementations of embedded-cal are composable: Rather than having to select a single provider of cryptographic tools, it allows picking suitable parts. For example, a software implementation can be composed from the OS’s source of randomness and the libcrux software implementation; on embedded hardware, there is typically one layer of what the hardware can do, augmented by a software layer that fills gaps (e.g. when the hardware accelerates elliptic curves primitives, and the software then make a full DH key establishment out of it). Also, different algorithms can be served by different components.
The library is designed with resident secrets in mind (event though currently, no implementations provide that): Keys are never required to be visible to the user, by virtue of using associated types in many places. This way, implementations based on secure elements can use either encapsulated keys or key slot handles.
Modules§
- accessor
- Accessors to the deep associated types of a
Cal. - empty
- Implementations of the various traits of embedded-cal that implemnt the empty set of algorithms.
- plumbing
- Traits by which hardare primitives can be made available that are not in themselves high-level primitives.
- util
- Tools helpful in implementing
embedded-cal
Structs§
- Decryption
Failed - Error indicating that an AEAD decryption failed.
- Import
Error - Error indicating that a imported key’s size does not match the given algorithm, or that the data was otherwise found flawed.
- Incompatible
Keys - Error indicating that the public and the private key are incompatible.
Enums§
Traits§
- AadGenerator
- Tool for providing the AAD (Additional Authenticated Data) in a scatter-gather fashion.
- Aead
Algorithm - An AEAD algorithm identifier.
- Aead
Provider - Symmetric encryption with authentication and additional data.
- Cal
- Cryptographic abstraction provider that encompasses all features abstracted by the embedded-cal.
- DhAlgorithm
- An algorithm for diffie-hellman style key establishment.
- DhProvider
- Diffie-Hellman style key establishment.
- Hash
Algorithm - A hash algorithm identifier.
- Hash
Provider - Hashing of byte streams.
- Hkdf
Provider - An interface for using HKDF (defined in RFC5869).
- Hmac
Algorithm - An HMAC algorithm identifier.
- Hmac
Provider - Message authentication based on hashes.