Urgent.News

What's breaking now, across thousands of outlets.

Tech

Zeroization, part 1: Wiping can make things worse

Zeroization, or wiping, is often recommended as a solution to remove secrets from memory after use. However, blindly applying this approach can sometimes cause more harm than good. When a function calculates an intermediate value for a computation and then wipes it, the compiler may optimize the process away, leaving no trace of the secret in memory. This can lead to leftover copies of the secret that were not intended to be preserved.

For example, consider a simple function that calculates an intermediate value, uses it to produce a result, and then wipes it. Removing the wiping step reveals that the compiler has optimized the process away entirely. The intermediate value stays in registers rather than being written to memory, making it difficult to wipe.

To address this issue, programmers often replace the wiping step with volatile byte stores, which force the compiler to write zeros to memory. However, this approach can also introduce new problems. For instance, if the intermediate value is stored in a register rather than memory, the wiping function may need to write zeros to the stack first. This creates a window during which the secret is still present in memory, potentially leaving it vulnerable to attacks.

Another common approach is to create a separate wipe function that can be called from the original code. However, this introduces additional complexity and potential issues. The caller must now account for the fact that the wipe function may write to memory, which can break assumptions about memory layout and execution order. Additionally, modern compilers often optimize away separate compilation units, rendering the separate wipe function ineffective.

Consider a scenario where a function computes a tag using a seed and a value (e.g., XOR), compares it to an application-provided tag, wipes the tag, and returns the result. In this case, adding a wipe step creates an extra copy of the tag in a spill slot, which is not cleared by the wipe function. Disabling stack protection can further exacerbate the issue, leading to unpredictable behavior and potential security vulnerabilities.

In conclusion, while zeroization can be a useful technique for removing secrets from memory, it is not a one-size-fits-all solution. Before applying zeroization to a small local variable, it is crucial to carefully consider whether the value already exists in memory, whether taking its address creates additional storage, and what other values may be live across the call.

By understanding the intricacies of compiler optimizations and execution flows, developers can make informed decisions about when and how to apply zeroization effectively.

Written by urgent.news from Lobsters's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at 00f.net →

More in Tech

More from Wednesday 7 October →