Question Details

No question body available.

Tags

c hash cryptography hmacsha1

Answers (3)

Accepted Answer Available
Accepted Answer
December 14, 2025 Score: 35 Rep: 152,758 Quality: Expert Completeness: 80%

I'm wondering if there's any reason why the author of the code chose to reset those locals?

Yes, the intent seems clear, the author was trying to clean up for security reasons: the purpose of the wipe code is to avoid leaving a copy of the original block present in the stack memory. The original block may contain secrets such as a password so erasing this from memory is good practice.

It is rather easy to scan stack memory should an attacker gain control of the process after the secret was encrypted. Chances are the buffer will have been at least partially overwritten but playing it safe seems palatable.

The problem is this code may be optimized out by the compiler as modifying local data that goes out of scope seems unnecessary because it has no observable effects. The compiler inlines the memset call and will elide it too.

A new function memsetexplicit was added to the C library as of the C23 Standard to prevent this optimisation and tell the compiler that such an erasure is required by the programmer and should not be elided.

Is there any or do you agree that it's unnecessary overhead to reset these local variables?

Wiping the local variables a through e seems overkill, but forcing erasure of the copy of the argument block makes sense and has minimal cost compared to the SHA computations, so the overhead is very small.

The author's method is ineffective if the code is compiled with optimisations, which is highly desirable for this particular function.

The code should be updated and use the new memsetsecure function if available or emulate it this way:

volatile uint32t *p = block[0].l; for (sizet i = 0; i < 16; i++) { p[i] = 0; }
December 14, 2025 Score: 2 Rep: 80,796 Quality: Medium Completeness: 80%

Apparently you are right, if you have a function, a local variable is created and the function ends, then your variables are indeed getting out of scope. However, it looks like the author worried about their values still being unchanged someplace in memory and even though the variables no longer exist, their values are still unchanged at the memory location they were located at. So if somehow a hacker finds a reliable way to localize those unreferenced, but unchanged locations in memory, then referring to them later on may get the information leaked. It is also important what the function actually does, at the section you marked at

[LOTS OF SIMILAR STATEMENTS REMOVED FOR READABILITY]

and before and after that. If these variables are being passed by address someplace, then it is possible that helper functions are storing their address someplace that can be reached even after the function returns, in which case, reaching out to those goodies one may be able to get the values at that address, even though there is no variable addressing them anymore.

So the questions you need to ask yourself of are:

  1. Do I need to do this micro-optimization, do I really have a performance issue whose fix would be this? (removing the resets)
  2. How secure the values should be? Are they top-secret I am willing to protect from eager hackers, what is the security implication if that sha1 gets partially or entirely leaked?

Likely your answer to 1 is "no" and to 2 is "I need security". Hence, you need protection even of the no longer referenced values and hence it is smart to remove it, as the best security that can be offered here for those values is their nonexistent not only as variables, but as address too.

December 15, 2025 Score: -1 Rep: 13,140 Quality: Low Completeness: 40%

Deleting (wiping) local data is done for security reasons, as you have also been told.

But you need also to be told that, as those variables are not observable output of the routine, you will need special compilation options (concretely, don’t optimize the code generator) for the compiler not to evict completely that code. So always compile that compilation unit with -O0 preferably.