Boost logo

Boost :

From: Andrey Semashev (andrey.semashev_at_[hidden])
Date: 2024-07-10 15:37:00


On 7/10/24 18:26, Andrey Semashev wrote:
> On 7/10/24 14:59, Peter Dimov via Boost wrote:
>> Ruben Perez wrote:
>>> There is OPENSSL_Cleanse, which does a similar job. I found it surprisingly
>>> simple - I wonder if this is just enough or there are any corner cases where this
>>> doesn't work:
>>> https://github.com/openssl/openssl/blob/b544047c99c4a7413f793afe82ab1c165f85b5b6/crypto/mem_clr.c#L22
>>
>> That's an interesting approach. I can't offhand think of a reason why it wouldn't
>> work.
>
> The compiler might convert OPENSSL_cleanse to something like this:
>
> void OPENSSL_cleanse(void *ptr, size_t len)
> {
> memset_t func = memset_func;
> if (func != memset)
> func(ptr, 0, len);
> else
> memset(ptr, 0, len);
> }
>
> The purpose here is that, if memset_func is actually memset most of the
> time, it can further optimize the call to memset, including to
> completely remove it, depending on the call context. The
> (well-predictable) branch is typically cheaper than an indirect call. I
> think I've seen compilers do something along those lines as a result of
> call devirtualization, especially with IPO and LTCG.
>
> I'm not saying that's what actually happens in OpenSSL, just that
> something like this is possible. I think, a dummy asm statement is more
> reliable and more efficient.
>
> void secure_cleanse(void *ptr, size_t len)
> {
> memset(ptr, 0, len); // a normal memset, optimizations are welcome
> __asm__ __volatile__ ("" : : "r" (ptr), "r" (len) : "memory");
> }
>
> You can even make that function inline and it'll work, and in an optimal
> way, too.

And for compilers that don't support __asm__, I think you could replace
it with:

  std::atomic_signal_fence(std::memory_order::acq_rel);


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk