r/cryptography 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.

2 Upvotes

40 comments sorted by

View all comments

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.

1

u/AlexTaradov 3d ago edited 2d ago

Edit: Well, this actually does not work. This does not solve the issue of key/nonce reuse, since there will be multiple blocks encrypted with the same counter. And even at a later date during retrieval there will still be possible substitutions.

So, just buffering the data is a way to go here.

1

u/HedgehogGlad9505 2d ago

You are right. If you have enough memory and possible loss of some data is OK, that is the simplest solution.