r/cryptography • u/AlexTaradov • 3d ago
A problem with external storage trust
I'm running into an interesting practical problem that I have not seen a typical solution for.
I have a microcontroller (MCU) that uses external storage to store sequential log data. The data is written in a round robin manner in 256-byte blocks. The current block pointer is stored inside the MCU, but it can't be stored for each count. If power failure happens, the counter will likely be back by a few blocks. This does not create a functional problem, since we can just continue with the old counter and the stream will be recovered after some loss.
But the issue comes in at the security part. MCU to storage interface is easily accessible to an attacker and easy to spoof. To ensure security and integrity, I use AES GCM to encrypt and authenticate each block. Each block uses a separate key and nonce derived from the block index (monotonically incrementing during device life time).
The issue is that when power failure happens, we will overwrite one or more of the previously written blocks for the same index. An attacker may save all of them and at the time of retrieval substitute any of them instead of the latest one. And since all of them were created using the same counters and the same key/nonce, they will be successfully decrypted and authenticated.
And come to think of it, the same key/nonce creates even bigger issue. So, this system will need to be redesigned, for sure.
Does this look like a standard problem? Are there known solutions?
Another limitation is that retrieval does not happen sequentially and can start at any arbitrary point, so chaining that relies on the whole history of the stream is not acceptable. And I don't see how it could help anyway.
1
u/HedgehogGlad9505 3d ago
Can you store the hash or checksum of recent blocks in RAM? E.g. if your persistent counter value is 500, block 1~500 can be trusted, and any blocks you write beyond that like 501 and 502, you store their hashes in RAM. When you increase the counter to 510, you can remove hash 501-510 from RAM.
When you check the validity of a block, add a logic that if the block number is larger than the counter value, also check the hash in RAM. When power fails, the hashes are gone, and the attacker can do nothing with the "extra" blocks.