Heimlig is a Hardware Security Module (HSM) firmware for embedded platforms written in Rust.
As an HSM, Heimlig typically runs on dedicated hardware and provides cryptographic services to clients running on other cores. These include:
- Generation and secure storage of cryptographic keys.
- Key use (encryption, decryption, signing, verification) without revealing key material to the client.
- Generation of cryptographically secure random numbers (CSPRNG).
Warning: Heimlig is still under development and is not production ready.
Heimlig implements common cryptographic algorithms:
- Symmetric encryption and decryption (AES-CBC, AES-GCM, AES-CCM, Chacha20Poly1305)
- Signing and verification (ECDSA)
- Key exchange (ECDH)
- Hashing (SHA-2, SHA-3, BLAKE3)
- Random number generation (ChaCha20Rng)
An example implementation is available for the STM32H745XI discovery board as well as for Linux (for development).
Current limitations include:
- Most cryptographic algorithms are implemented in software only.
- Storage for key material is not persistent yet.
- While safe cross-core communication works, safe cross-MCU has not been demonstrated yet.
- The code has not been independently audited by security experts.
The fastest way to see Heimlig working is to run the Linux example:
cd examples/linux
cargo run
Example output:
Finished dev [unoptimized + debuginfo] target(s) in 0.07s
Running `target/debug/linux`
2022-11-24T13:30:19.419Z INFO [CLIENT] Sending request: random data (size=16)
2022-11-24T13:30:19.429Z INFO [CLIENT] Received response: random data (size=16): 2831804f4db41f98b2fe24bdde36372f
The example instantiates a Heimlig core and a client. Both communicate via two heapless queues. One for requests to the core and one for responses from it. The client continuously requests random numbers from the core and prints the results to the console.
See the STM32H745I example.
Heimlig consists of three main components: The host-side client API, the Heimlig core and the crypto workers. These three groups communicate by sending request-response pairs over hardware-specific message queues.
The core accepts requests from the client API and schedules them to different workers. Workers use the HSM CPU and can utilize hardware acceleration if available. Once a response is ready, it is sent back to the client via the core. This architecture makes it possible to run most of the cryptographic algorithms in software and later switch individual workers to use hardware acceleration.
While Heimlig is designed to run on dedicated hardware, it is possible to integrate it alongside other security applications that are running on the same microprocessor. This has implications on the provided security level as any code running alongside Heimlig has access to its internals. Nevertheless, such a setup can be useful if the security requirements of the project allow for it.
See Architecture.md for more details.
To add Heimlig to a project, several hardware-specific components have to be provided. These include:
- Communication channels between clients and the Heimlig core.
- An instance of a memory
Pool
. This usually requires a statically allocated memory region. - An entropy source to instantiate a random number generator (
Rng
) instance. - Optionally a key store that implements the
KeyStore
interface. A RAM-basedMemoryKeyStore
is provided for testing purposes. If no key store is provided, necessary keys must be sent by the clients as part of their requests.
The integrator can then go on to instantiate a hsm::Core
on the HSM side and one or more
client::Api
instances for the different clients. Instantiating these structs requires the
previously mentioned components.
Contributions are very welcome. Feel free to file issues and create pull requests here on GitHub.
Heimlig is dual-licensed under the Apache 2.0 and MIT licenses.