STM32F756: What a Hardware Crypto Block Leaves Behind
A crypto block creates a particular kind of expectation in a recovery request. The customer knows the product uses encryption, concludes that the firmware is encrypted, and asks for the decryption to be undone. The expectation is reasonable and it is usually wrong, because encryption on a microcontroller is rarely applied to the code. It is applied to data in transit, to stored credentials, or to a firmware image that arrives through an update channel — and in the third case the decrypted result is already sitting in flash, because that is where the processor executes from.
So the useful question is not “how do I decrypt this”. It is “which of these three things is the crypto block doing here”, and the image answers that question.
What the block can and cannot do
The accelerator handles symmetric encryption in several modes, a set of hash functions, and a true random number generator. It is a peripheral: software writes a key into it, writes data, and reads results. It does not fetch code, it does not sit between the processor and flash, and it has no ability to decrypt instructions as they are fetched.
That last point is the one worth stating explicitly, because it is the source of most wasted effort in this class of job. There is no bus encryption on this part. Code executing from flash is code in the clear unless the software itself decrypted it before writing it there.
| the accelerator does | the accelerator does not |
|---|---|
| encrypt and decrypt buffers on request | decrypt code as it is fetched |
| compute hashes over supplied data | authenticate the flash array at boot by itself |
| generate random numbers | store or protect a key on its own |
| run in several chained modes | hide its own configuration from a memory read |
The right column is why a decrypted image is the normal case. An application that receives an update over a network decrypts it into RAM, verifies a hash, and programs the result into flash. By the time the product ships, the ciphertext is gone and the plaintext is what a recovery reads.
Four places a key can come from
The key is the part that is genuinely absent from a dump, and how it was provisioned determines whether the recovered image is reusable at all.
| provenance | how it appears in the image | what happens on another device |
|---|---|---|
| compiled into the code as a constant | a fixed byte sequence, often obfuscated by a byte-wise transform | the image works, and the key is recoverable |
| stored in a dedicated one-time-programmable area | a read of that area returns the key or a fingerprint of it | the image works if the new device is provisioned identically |
| derived from the device’s unique identifier | arithmetic over a value read from system memory | the image runs but produces wrong results, or fails its own check |
| entered from outside at commissioning and never stored | nothing at all | nothing can be restored; the device is a brick without the key |
The third row is the one that produces the most confusing customer reports, and it is covered from the arithmetic side below. The fourth row is worth recognising early because it changes the commercial conversation: if the key is genuinely absent from every readable location, no amount of extraction will make the product work again, and saying so before the work starts is more valuable than a perfect dump delivered with an apology.
What the image keeps after the key is gone
Even when the key is unreadable, the surrounding code is highly informative, and it is where a recovery earns its value.
| artefact | what it looks like | what it tells you |
|---|---|---|
| the key-loading sequence | a short block writing consecutive words to one peripheral register block | which key slot and length the design used |
| mode and chaining setup | writes that set a mode field and an initialisation vector | whether the product used authenticated modes |
| a hash comparison | two buffers compared word by word after a hash completes | the program verifies integrity, so a modified image will be rejected |
| the storage format | a header with a length, a nonce and a tag before each block | how the stored data is structured, and therefore how to regenerate it |
| a random-number read at startup | a register read very early, feeding a buffer | where session keys or nonces come from |
The third row has a practical consequence that is easy to miss. A product that verifies a hash over its own flash at boot will refuse to run a restored image that differs by a single byte. Restoring such a device requires reproducing the exact original image, not merely a functional one, and the verification routine is the specification for what “exact” means.
The two protection levels
Protection on this family is set in option bytes and has two meaningful states on the debug side, with very different consequences.
| level | what it does | what it means for a recovery |
|---|---|---|
| unset | debug port works, memory readable, flash writable | straightforward read |
| level one | debug port is restricted, memory reads over the debug interface are blocked, but the application still runs and the flash can be mass-erased | the debug path is closed; erasing is possible but destroys the contents, so it is not a recovery |
| level two | the debug port is permanently disabled, and no mechanism exists to re-enable it | the die has to be accessed physically; there is no software route back |
The middle row describes the situation most often misreported as “irreversibly locked”. It is not irreversible — the device can be erased and reused — but erasing is the opposite of recovering, because on a flash part the erase that clears the protection also clears the array. That equivalence holds here exactly as it does on much smaller parts, and it is worth stating in plain language before a customer approves destructive work.
Why a working image can fail on a second device
Consider the case where the key is derived from the unique identifier. The derivation is short: a few words of identifier, a mixing step, and the result used as a key. Nothing about it is visible unless you look for it, and when the image is restored onto a second device the failure is not a crypto error message. It is a corrupted data structure, or a communication stack that authenticates nothing, or a device that boots and then refuses to accept its own configuration.
The pattern is recognisable: the image contains a read from the system memory area very early, followed by arithmetic that produces a value used as a key, and a checksum that will not match on any other die. A report that identifies this pattern tells the customer that the recovery is valid for one device and that a fleet cannot be restored from it, which is a materially different answer from “recovered successfully”.
| symptom after restore on a second device | likely cause |
|---|---|
| boots, then fails an internal integrity check | identifier-derived key or a hash bound to the original die |
| boots, runs, but produces wrong output values | same, with the failure absorbed by the application |
| refuses to enter its normal mode | a provisioning check against a stored fingerprint |
| works completely | the key was a constant or the provisioning was reproduced |
What the report should state
State whether the image contains ciphertext at all, and if so where. State the key provenance with the evidence for the conclusion. State the protection level that was found, and if it was level two, say so before quoting physical work. And state whether the recovered image is portable to another device, because that single sentence decides whether the customer can use the result for production or only for analysis.
The value-line member of the same family, where the internal array is small enough that the application body is elsewhere, is covered in STM32F750 flash recovery. The protection and boot-path interaction is set out in STM32F745 heximal extraction, and the identification step that must precede any of this is in STM32F747 binary recovery. A comparable crypto-equipped case on an older core is at STM32F407ZG firmware restoration.
FAQ
Is the firmware itself encrypted on this part? Almost never. The processor fetches instructions directly from flash, so the code has to be in the clear. Encryption applies to data and to update packages.
Can the crypto block be used to hide code? Only by decrypting it at runtime into RAM, which leaves a decrypted copy in RAM while the device runs.
Does level two protection mean the die is unusable? No, but it means no debug path exists. Physical access is the only route, and the die is destroyed as a functional part in the process.
Conclusion
A crypto block does not hide code; it processes data. The key is the only genuinely missing piece, and its provenance — constant, one-time area, identifier-derived, or supplied from outside — decides whether a recovered image is portable, single-device, or worthless. Reporting that provenance, together with the protection level actually found, is the difference between a dump and an answer.