This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

explicit_bzero documentation


I believe that the only remaining concern with the explicit_bzero
patch *itself* (as opposed to the question of whether new public
symbols should be REDIRECTed into the implementation namespace, which
is best addressed separately) is the documentation, and specifically,
the precise wording of the warnings about its limitations.  So, rather
than resend the entire patch, I'm just sending a revision of the
"Erasing Sensitive Data" manual section.  This hopefully strikes a
good balance between making sure that all the important caveats are
documented and not scaring programmers off of using the function at
all.  I'm not super happy with "is designed to be used in this
situation", but I'm stuck for more fluent wording and I have other
stuff I need to do today :)

cc:ed are everyone who's commented on previous iterations of the
documentation and also Roland, whom I believe wrote the string.h
section of the manual originally.

Paul: This revision doesn't specifically mention the _address_ of
sensitive data as an exposure, but it does talk about increased risk
of exposure in general if a variable only has its address taken to
call explicit_bzero; I think this is the right level of detail.

zw

----

@node Erasing Sensitive Data
@section Erasing Sensitive Data

Sensitive data, such as cryptographic keys, should be erased from
memory after use, to reduce the risk that a bug will expose it to the
outside world.  However, often the compiler can deduce that an erasure
operation is ``unnecessary'' because no @emph{correct} program could
access the variable or heap object containing the sensitive data after
it's deallocated.  Since erasure is a precaution against bugs, it
should be done even though it is ``unnecessary'' in this sense.  The
function @code{explicit_bzero} is designed to be used in this
situation.

@smallexample
@group
#include <string.h>

extern void encrypt (const char *key, const char *in,
                     char *out, size_t n);
extern void genkey (const char *phrase, char *key);

void encrypt_with_phrase (const char *phrase, const char *in,
                          char *out, size_t n)
@{
  char key[16];
  genkey (phrase, key);
  encrypt (key, in, out, n);
  explicit_bzero (key, 16);
@}
@end group
@end smallexample

@noindent
The call to @code{explicit_bzero} in @code{encrypt_with_phrase} erases
sensitive data that is about to be deallocated.  If @code{memset},
@code{bzero}, or a hand-written loop had been used, the compiler
might treat the erasure as ``unnecessary'' and remove it, but it will
not do this with @code{explicit_bzero}.

@strong{Warning:} Using @code{explicit_bzero} does not guarantee that
sensitive data is @emph{completely} erased from the computer's memory.
There may be copies in temporary storage areas, such as registers and
``scratch'' stack space; since these copies are invisible to the
source code, there is no way to arrange for them to be erased.

Also, @code{explicit_bzero} only operates on RAM.  If a sensitive data
object never needs to have its address taken other than to call
@code{explicit_bzero}, it might be stored entirely in CPU registers
@emph{until} the call to @code{explicit_bzero}.  At that point, it
will be copied into RAM, the copy will be erased, and the original
will remain intact.  Data in RAM is more likely to be exposed by a bug
than data in registers, so using @code{explicit_bzero} can create a
brief window where sensitive data is at greater risk of exposure than
it would have been if the program didn't try to erase it at all.
@Theglibc{}'s implementation of @code{explicit_bzero} contains a hack
that can prevent the data from being copied to RAM in this situation,
but it is not guaranteed to work and it doesn't do anything about the
data in registers.

In both cases, declaring sensitive variables as @code{volatile} will
make the problem @emph{worse}; a @code{volatile} variable will be
stored in memory for its entire lifetime, and the compiler will make
@emph{more} copies of it than it would otherwise have.  Attempting to
erase a normal variable ``by hand'' through a
@code{volatile}-qualified pointer doesn't work at all---because the
variable itself is not @code{volatile}, the compiler may ignore the
qualification on the pointer and remove the erasure anyway.

Having said all that, in most situations, using @code{explicit_bzero}
is better than not using it.  At present, the only way to do a more
thorough job is to write the entire sensitive operation in assembly
language.  We anticipate that future compilers will recognize calls to
@code{explicit_bzero} and take appropriate steps to erase all the
copies of the affected data, whereever they may be.

@comment string.h
@comment BSD
@deftypefun void explicit_bzero (void *@var{block}, size_t @var{len})
@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}

@code{explicit_bzero} writes zero into @var{len} bytes of memory
beginning at @var{block}, just as @code{bzero} would.  The zeroes are
always written, even if the compiler could prove that this is
``unnecessary'' because no correct program could read them back.

@strong{Note:} The @emph{only} optimization that @code{explicit_bzero}
disables is removal of ``unnecessary'' writes to memory.  The compiler
can perform all the other optimizations that it could for a call to
@code{memset}.  For instance, it may replace the function call with
inline memory writes, and it may deduce that @var{block} cannot be a
null pointer.

@strong{Portability Note:} This function first appeared in OpenBSD 5.5
and has not been standardized.  Other systems may provide the same
functionality under a different name, such as @code{explicit_memset},
@code{memset_s}, or @code{SecureZeroMemory}.

@Theglibc{} declares this function in @file{string.h}, but on other
systems it may be in @file{strings.h} instead.
@end deftypefun


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]