Boost logo

Boost :

From: Richard Hodges (hodges.r_at_[hidden])
Date: 2024-07-09 16:18:43


On Tue, 9 Jul 2024 at 18:08, Andrey Semashev via Boost <
boost_at_[hidden]> wrote:

> On 7/9/24 18:41, Josh Juran wrote:
> > On Jul 9, 2024, at 10:24 AM, Andrey Semashev via Boost <
> boost_at_[hidden]> wrote:
> >
> >> As far as secure erase functions go, there's no variance about whether
> >> it works or not. It either works as specified in the contract or it has
> >> a bug. And it's fairly easy to make it work as intended anyway.
> >
> > secret_string::~secret_string()
> > {
> > #if HAVE_SECURE_MEMSET
> >
> > secure_memset( ptr, ‘\0’, len );
> >
> > #else
> >
> > memset( ptr, ‘\0’, len );
> >
> > #endif
> >
> > free( ptr );
> > }
> >
> > The above will work most but not all of the time, depending on
> toolchain, OS, and even build settings. You might have a compiler that
> elides the memset() call (perhaps only at certain optimization levels) with
> an OS or libc that lacks secure_memset(), or you might have neglected to
> include the header that defines the feature-test macro.
>
>
just a thought :

It would be nice if this worked:

#include <string>
#include <algorithm>

struct secure_string
: std::basic_string<volatile char>
{

    ~secure_string()
    {
        std::fill(begin(), end(), '\0');
    }
};

Alas:
/opt/compiler-explorer/gcc-14.1.0/include/c++/14.1.0/bits/basic_string.h:90:21:
error: static assertion failed
   90 | static_assert(is_same_v<_CharT, typename _Alloc::value_type>);
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

> That would be a bug in secret_string. The correct implementation would
> unconditionally call secure_memset and secure_memset would be
> implemented in a way that prevents the compiler from eliding it. The
> typical implementations either use volatile or a dummy asm statement
> that potentially consume the data to be cleared.
>
> >> The question is rather is the secure erase enough to consider your data
> >> safe from leaks. It definitely is not. But not allowing it to leak into
> >> heap and remain there for extended periods of time is a necessary step
> >> towards better security. Even having just that protection alone is
> >> better than not having anything at all.
> >
> > You might also consider having the sensitive string XORed with a
> one-time pad (possibly using a different allocator), so it’s never in the
> clear in its entirety. But I’m not a security expert and can’t speak to
> the efficacy of that scheme. At least it probably won’t be inadvertently
> undone by a sufficiently “smart” compiler.
>
> Having XORed data and the XOR seed both in memory at the same time is
> pretty much the same as having the data in clear form.
>
> > A more important mitigation IMO is a timing-safe memcmp(), as the
> information otherwise leaked traverses not just process boundaries, but
> networks.
>
> memset does not depend on the data, so normally it is not timing sensitive.
>
> memcmp and similar functions that may return early are timing-sensitive,
> but this is a problem separate from secure data cleanup.
>
>
> _______________________________________________
> Unsubscribe & other changes:
> http://lists.boost.org/mailman/listinfo.cgi/boost
>


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