Skip to main content

No project description provided

Project description

RPi Derive Key 🔑

A utility for deriving secure device-specific keys on Raspberry Pi.

License: MIT OR Apache 2.0 CI Pipeline Latest ARM64 Debian Package Latest ARMHF Debian Package PyPi Package RPi Derive Rust Crate

⚠️ Caution: This tool is based on storing a randomly generated device secret in the One-Time Programmable (OTP) memory of the Raspberry Pi SoC. The initialization of this secret is irreversible. Please make sure you understand the provided security guarantees before using it for anything serious.

  • Cryptographically strong key derivation using SHA3-512 and HKDF.
  • Statically-linked standalone binary with zero dependencies.
  • Rust crate and Python package for easy integration into your project.

How does it work?

Upon initialization, a randomly generated 256-bit device secret is stored in the OTP memory of the Raspberry Pi SoC. Note that the OTP memory on any board can be programmed only once. This secret is then used as input key material for the HKDF key derivation algorithm using SHA3-512 as the hash function. This enables the derivation of multiple keys from the device secret. Each key is derived from the device secret and additional info material (see HKDF). The device secret should be kept secret and rpi-derive-key does not provide any means of reading it directly. Using it and the info material, any key can be reconstructed. Note that the Raspberry Pi SoC does not provide a hardware-protected store for the secret. Any user in the video group and anyone with physical access to the board can obtain the secret (unless secure boot is used). Via secure boot it is indeed possible to prevent any unauthorized access when deploying Raspberry Pi's in untrusted environments.

If you are interested in commercial support, please contact us.

🧑‍💻 Usage

The easiest way to properly install RPi Derive Key on a Raspberry Pi is via the official Debian packages.

On a 32-bit Raspberry Pi OS (armhf) run:

wget https://github.com/silitics/rpi-derive-key/releases/latest/download/rpi-derive-key_armhf.deb
sudo dpkg --install rpi-derive-key_armhf.deb

On a 64-bit Raspberry Pi OS (arm64) run:

wget https://github.com/silitics/rpi-derive-key/releases/latest/download/rpi-derive-key_arm64.deb
sudo dpkg --install rpi-derive-key_arm64.deb

Note that the Debian packages do not include the Python package. They merely contain the command line tool and a Systemd service for initializing the device secret during the boot process. The Python package can be installed as usual via pip or added as a dependency to a Python project.

For testing and debugging, the Python package is also available for MacOS, Windows, and x86_64 Linux. On these platforms, however, the device secret must be faked by setting the FAKE_RPI_DERIVE_KEY_SECRET environment variable (see below). The Python package is documented by its type stub.

Standalone binaries are available on the Releases page.

The documentation of the Rust crate is available on docs.rs.

Initialization of the Device Secret

To derive keys, the device secret needs to be initialized first.

Using the command line tool, the device secret is irreversibly initialized with:

rpi-derive-key init

Note that the initialization may fail if the firmware does not support storing a private key in OTP memory. In this case, you can either update the firmware or use the generic customer-programmable OTP registers instead:

rpi-derive-key --customer-otp init

The switch --customer-otp must subsequently be provided to all commands.

The Debian package comes with a Systemd service for initializing the device secret during the boot process. This is useful to initialize devices with an image or SD card. To enable this service, run:

sudo systemctl enable rpi-derive-key

Status Information and Checks

To print status information, run:

rpi-derive-key status

To check that the secret has been properly initialized, run:

rpi-derive-key check

This is useful when using RPi Derive Key in a script.

Deriving a Key

To derive a key and print it in hex representation use

rpi-derive-key hex <BYTES> <INFO>

where <BYTES> is the key size in bytes and <INFO> is some arbitrary string.

For instance, to generate a 512-bit filesystem encryption key run:

rpi-derive-key hex 64 fs.root.encryption

Multiple independent keys can be generated by using different values for <INFO>.

To derive a UUIDv4 use

rpi-derive-key uuid <INFO>

where <INFO> is again some arbitrary string.

For instance, to generate a unique device id run:

rpi-derive-key uuid device.id

Testing and Debugging

For testing and debugging purposes, you can fake a device secret by setting the FAKE_RPI_DERIVE_KEY_SECRET environment variable to any secret you like. Please never use this variable in production.

Setting this variable also bypasses initialization via rpi-derive-key init.

Example Use Case

Imagine you would like to derive a unique public id and a secret identification token for each device.

To derive a unique public device id using device.id as <INFO> run:

rpi-derive-key uuid device.id

You can now safely use the resulting UUID as a public device identifier. You do not have to keep it secret because it is impossible to reconstruct other keys or the device secret from it.

In addition to the public id, you can derive a 256-bit (32 bytes) secret token with:

rpi-derive-key hex 32 device.secret.token

This secret token is supposed to be shared only with trustworthy entities, e.g., it may be sent in HTTP headers to prove the device's identity to a webserver providing device configurations:

wget --header "X-Secret-Token: <SECRET-TOKEN>" https://example.com/<DEVICE-ID>/config.tar.gz

📌 Tip: You should use different keys (with different info material) for different purposes (e.g., fetching updates or configurations). That way, if a key for a given purpose is compromised, all other keys remain secure.

⚖️ Licensing

RPi Derive Key is licensed under either MIT or Apache 2.0 at your opinion. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache 2.0 license, shall be dual licensed as above, without any additional terms or conditions.


Made with ❤️ for OSS by Silitics.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

rpi_derive_key-0.2.1-cp37-abi3-win_amd64.whl (102.7 kB view details)

Uploaded CPython 3.7+ Windows x86-64

rpi_derive_key-0.2.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (186.0 kB view details)

Uploaded CPython 3.7+ manylinux: glibc 2.17+ x86-64

rpi_derive_key-0.2.1-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (173.7 kB view details)

Uploaded CPython 3.7+ manylinux: glibc 2.17+ ARMv7l

rpi_derive_key-0.2.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (174.6 kB view details)

Uploaded CPython 3.7+ manylinux: glibc 2.17+ ARM64

rpi_derive_key-0.2.1-cp37-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl (317.4 kB view details)

Uploaded CPython 3.7+ macOS 10.9+ universal2 (ARM64, x86-64) macOS 10.9+ x86-64 macOS 11.0+ ARM64

File details

Details for the file rpi_derive_key-0.2.1-cp37-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for rpi_derive_key-0.2.1-cp37-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 023a703a8575d675d552be28a060f8abe49d9d74a52e1c72a3852fd150503480
MD5 d6c0353203d8bc2eabcaf880b22f1736
BLAKE2b-256 9b88fafe441806966da30b3040454d59ed39c6b015976dd904661afe099ba0bb

See more details on using hashes here.

File details

Details for the file rpi_derive_key-0.2.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for rpi_derive_key-0.2.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 4660350843acdcda567250be5bc7afab17a07a71c92991c0a6b3bb31afc06aae
MD5 fd9dbedb5e5b1e386b6809214d99a236
BLAKE2b-256 6715899079c482fc772b92f7f8995247209b041b63a84ca9a07f8434bbd25206

See more details on using hashes here.

File details

Details for the file rpi_derive_key-0.2.1-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for rpi_derive_key-0.2.1-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 e0c9088998e35965e81ea6149d1f9b67c5c317dca3ae8d14f50b01691556f133
MD5 fe0701ffa53319d3a8952cdcddea5d14
BLAKE2b-256 48b3b57cc845569fb0eff619baa5f8defb49af6481bb702bc1d6e155d539c045

See more details on using hashes here.

File details

Details for the file rpi_derive_key-0.2.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for rpi_derive_key-0.2.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 04c23bfd40f64fe00fe137060784336f2e0b25bac72acfa110bc04d41ad7aba6
MD5 2f2661f4151a132a4f1dcafd277da97a
BLAKE2b-256 751254b64174ec558da69e559e8478f654448badb4c2b75d0190b6f1daec63b8

See more details on using hashes here.

File details

Details for the file rpi_derive_key-0.2.1-cp37-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl.

File metadata

File hashes

Hashes for rpi_derive_key-0.2.1-cp37-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl
Algorithm Hash digest
SHA256 b7ba5f95a2af8f5375e0a1bfd1b246def70483732efee08afb2612fc7a64fccd
MD5 2a31c0d9af1b63f97a51b17dd7d18e88
BLAKE2b-256 c325a60abe9bd810458bcc712d7130638712cc7b439445c7a0d85733dce220e6

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page