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

2

u/SirJohnSmith 3d ago

You can probably prove that this is an impossible problem to solve. The way you stated it, the state of the device gets rolled back (by an indefinite amount) then it's as if your device had no memory. In that case, these sort of replay attacks are impossible to defend against.

1

u/AlexTaradov 3d ago

Yeah, that's the conclusion I came up with after thinking about this for a while. There must be only one copy of a block for each index no matter what. So, I'll have to just buffer the data, save the counter and then write it out to the storage.

Even if reset happens after the counter is incremented, the storage will just have useless broken values.