[Botan-devel] RFC: memory locking

Jack Lloyd lloyd at randombit.net
Mon Nov 12 21:22:34 EST 2007


On Mon, Nov 12, 2007 at 06:30:11PM +0000, Nathaniel Smith wrote:
> I assume by locking you mean mlock(2), not mutexes.

Correct. If the allocators exist, it makes the most sense to share
them among threads (AFAICT), so we do want to continue to serialize
access to it where needed. (Ideally it could be written in a lock-free
manner, but that's a whole other can of worms).

> I don't see how you can zeroize a std::vector<> properly; you aren't
> there when it gets deallocated

Actually we can most of the time, via the higher level destructors (eg
a notional call to 'void clear(std::vector<byte>&)' inside AES::clear,
rather than relying on the container to do it). However that is
admittedly ugly.

> and worse, you aren't there when it
> reallocates itself at some moment and leaves behind a copy of
> its old contents at some random memory location.

Hrm, that's a pretty good point. While crypto keys are not typically
resized, we do often append to buffers which are accumulating
information that probably shouldn't be leaked.

Another possibility here is to use std::vector with a custom
allocator: which is pretty difficult in C++03 and is made
exceptionally ugly via the lack of template typedef support, but seems
somewhat more sane in C++09 (but I haven't yet read all the WG papers
WRT allocator changes, so I don't know if it provides enough hooks
that this could reasonably be done). That at least avoids having to
reinvent container types. Actually this method might be usable today
with something like

template<typename T, size_t INITIAL_SIZE=0>
class botans_new_vector : public std::vector<T, botan_allocator_of<T> >
   {
   public:
      botans_new_vector() { /*resize to INITIAL_SIZE if set*/ }
      void clear() { /* zeroize contents */ }
      ~botans_new_vector() { clear(); }
   };

but TBH I don't know if this approach is a good idea at all (deriving
from std::vector seems somewhat unkosher, though I know it can be /
has been done).

> The only sane thing from a security standpoint, yes; the only sane
> thing from a speed standpoint is just the opposite.  Kernels get
> pulled on by both camps...

>> (Not to mention that swap encrypted with a random key chosen at
>> boot time is trivial to implement).
> Very true.  But no-one uses it.

I know! Which I think says something about how important most
users/sites consider the possibility of data leakage via swap.

> I'm nervous about a plan that changes the API in such a way that it
> becomes impossible to achieve secure key handling.  In practice, it
> might well be impossible to achieve now -- at least without herculean
> extra effort (auditing code to be suid safe, for instance, like gpg
> does) -- but if those other issues get solved tomorrow, it would be
> nice if Botan weren't stuck saying "oops, can't use me".

A change to std containers would make that pretty difficult. The
question in my mind is what, if anything, secure key handling (in the
very limited sense that Botan is providing) is giving in terms of
actual security, and if is worth the costs. Can you provide a case
where it would be something useful or important? Part of the problem
is I've got no scenario to motivate this code's existence.

> (At the moment, it looks like the ability to make executables
> setu-CAP_IPC_LOCK is going to make it into linux distros before
> default-encrypted swap, for instance.)

Link?

> Of course, by the time C++09 is usable, we'll hopefully know how all
> this turned out *anyway* :-).

Quite so.

-Jack


More information about the botan-devel mailing list