We now know that a naive, hash-based approach has trivial weaknesses. HMAC on its own prevents image modification. But it's likely easy to steal the key for either scheme. If all devices use the same key, forging a compromised firmware image is easy.
These attacks show the challenges with symmetric keys. When you use the same key to sign and verify a message, the key must be secret. When a device contains symmetric key material, you must protect it at all costs. This is complex, expensive and easy to get wrong.
Asymmetric ciphers have been around for quite some time. The premise is simple: encryption uses a different key from decryption. These are the foundation for public key cryptography. Asymmetric ciphers usually refer to keys as being 'public' (sharable) and 'private' (secret).
Suppose Alice and Bob need a secure channel. Alice gives Bob her public key. Bob uses Alice's public key to encrypt a message destined for her. An attacker, Eve, could intercept Bob's message before Alice receives it. Even knowing Alice's public key, Eve could not decrypt the message. To do this, Eve needs Alice's private key. When Alice receives the message, she uses her private key to decrypt the message from Bob.
The earliest and most popular scheme for this type of cryptography is RSA. RSA's security depends on the fact that calculating the prime factors of a large number is hard. The mechanics of RSA are something for a later blog post, though. What's important to understand is that RSA treats your message like large number. The message is raised to a large power, modulo a large number (the product of two secret prime numbers).
A simple RSA key consists of three values: the modulus, a public and private exponent. The public exponent is usually small. Operations involving the public key can be compact and quick. The private exponent is usually quite large. This makes guessing the exponent hard, but makes for slower math.
Both the public and private key can encrypt messages. Messages encrypted with one key are decrypted using the other. The same plaintext encrypted using each key will be different. Thus, the public key cannot encrypt a message that the public key can also decrypt. This is important for signing messages.
A variation on the previous example is to have Alice use her secret key to sign a message. Alice will first hash the message using SHA. She then takes the resulting hash and encrypts it using her private key. Anybody in possession of Alice's public key will be able to decrypt the message and retrieve the hash. Bob can hash the message received and compare his hash with that in Alice's signature. If the hashes match, Bob can be sure Alice's key signed the message and the message was not altered.
A message signed with Alice's private key is verifiable by any Bob who has her public key. Without Alice's private key, Eve will not be able to alter Alice's message. The signature will no longer match. This is starting to sound like a tool for our firmware authentication problem.
Asymmetric ciphers look promising. First, they use different keys to encrypt and decrypt a message. Second, we can decrypt a value using our public key and verify the key used to encrypt it was our private key. All without disclosing the private key.
A simple scheme might be:
- Generate an RSA keypair for the 'class' of device.
- Embed the public exponent and the modulus in the device's firmware update routine.
- Perform the initial load of the firmware in a 'trusted' environment. This installs the firmware update routine.
- On release, sign the new firmware image with the RSA private key.
- When installing the firmware image, the firmware update routine hashes the image.
- Using the public exponent and modulus, decrypt the signature attached to the firmware image.
- Compare the hash of the firmware image with that contained in the signature.
- If the hashes match, the image was at least signed with your private key. Accept it, and boot into the new version of the firmware.
This scheme mitigates the problems we found with HMAC and the simple hash-based scheme. Stealing the public key won't allow an attacker to forge a firmware image. In fact, it's possible to install new keys during a firmware release. Bad key hygeine could result in a stolen private key. This at least gives you a chance to make up for it in the field.
An attacker could compromise the device in a way such that they replace the public key in the device with one of their own. Sometimes software bugs are inevitable - hardware might help us here. This is a topic for a later blog post, though.
The Devil is in the Details
Of course, there are many issues glossed over here. For one, RSA has weaknesses you can exacerbate if you pick certain public moduli. As well, a plaintext for RSA that lacks correct padding exposes weaknesses. Finally, the security of RSA is only as good as the security of the private key. Are your keys lying around on a network share or DropBox? Did you let a contractor walk off with a USB stick containing the private key? Was the key generated on a box in the public cloud?
Guess what: these are all real issues that have happened at real customer sites. In one case, it resulted in total compromise.
Stay tuned for part 3. We'll discuss proper key handling strategies. Following that, we'll look at how hardware helps in validating firmware. Later posts will also cover alternative schemes to prevent device class compromises.