Recommendation for crates to encrypt and sign binaries

I want to sign and encrypt some binaries that will be distributed to users of an embedded device. The users will upload these binaries to the device, which will accept them if and only if they are signed and encrypted with the correct keys. The devices are relatively fast and the binaries relatively small, so performance is probably not a big issue.

I'd like to hear some suggestions on what crate(s) I should look into for this task.


Some background here, click to expand.

The motivation for requiring a signature is to ensure that only binaries created by me can be run on the device, both to avoid potential damage if a malicious binary was uploaded and to avoid that the device performs operations that it is not designed/authorized to perform.

The motivation for requiring encryption is two fold: First, to hinder reverse engineering of the binaries; Second, to ensure that the binaries can be executed only on devices that have the correct key pre-programmed by me.

I'd like to mention that it's OK if a user very skilled in the arts of reverse engineering and cryptography can bypass these restrictions. I want a reasonable amount of protection against a "typical user", who might even spend a few hours googling around and trying different approaches before giving up and going on with their life. I'm not trying to protect against state-sponsored attacks, and nobody's life is depending on these protections not being broken.

I'm happy to provide more context if needed.


I know of the RustCrypto project, but I find it hard to navigate through the "dozens of popular crates" they provide, hence this post of mine. Especially, my understanding is that some of those crates are low level and not intended for direct use, so I should use something higher level built on top of them instead.

In another project, I've used ed25519-dalek for signing and verification. I've also briefly played with chacha20poly1305 for symmetric encryption, but nothing more than trying out a few examples. So my current baseline approach would be to combine those two crates, using ed25519-dalek for the signature part and chacha20poly1305 for the encryption part.

Is this a reasonable approach? Are there any other crates you would recommend instead? Is there an approach that would provide both signature and encryption at once?

Thank you for your time and help!

1 Like

I'm not familiar with the field, but on general principle, you should probably approach this in two parts:

  1. Choose an encryption and signing scheme/protocol that has already been designed to have the properties you need.
  2. Once you know what exact cryptographic operations the chosen protocol requires, pick a suitable library to implement them.

Inventing your own cryptographic protocol is not as hazardous as inventing your own encryption algorithm, but it's still a place you can end up making something that's broken.

2 Likes

Apart from what @kpreid already said, you should avoid to put the symmetric encryption key (or even the private part of an asymmetric key) in the device unless the hardware provides a safe place to store secrets, because it is too easy to exctract the key if simpy stored in memory, flash or disk. Usually you want to use a "secure coprocessor" on the device but then you're limited to the algorithms provided by such a chip. To summarize:

  • signature is easy, just keep a public key on the device;
  • encryption is not, to be safe you need help from the hardware.
2 Likes

Thank you both for your insights!

Good point, I agree. That's partly why I asked if the approach I described was sensible, and whether there was a better one. But let me follow your advice and be more explicit by asking:

Does anybody know of a (standard) protocol for encrypting and signing binaries? Something to ensure verified and confidential updates.

In general I agree, and some of the devices I target do have a "secure coprocessor" I can use. Storing keys there is a bit messy, but can be done.

In this particular case, however, there are other safeguards in place against tampering with the hardware, so I'm a bit less sensitive to the threat of users extracting the key from the device. Still, preventing that from being feasible is surely desirable.

You can have a look at MCUBoot. It is an open source bootloader that does both signing and encryption. The documentation is well written and analyzes various scenarios, including signing, encryption and so on.

A basic procedure I have seen implemented in multiple products is based on using a different AES key for every update. The key itself is encrypted with an asymmetric algorithm (lately I see a lot of projects using ECC P256) and sent togheter with the update. The whole payload is then signed with a different key pair. The device has the private key of the first key pair and the public key of the second one: it can then check the signature and decrypt the AES key that is used to decrypt the update.

Just keep in mind that unless you have support for decrypting on the fly during execution (some SOCs can do that) or your hardware has some kind of secure flash it is always possible to connect an hardware debugger and extract the cleartext after you have decrypted the update and written it to flash.