botan.secure_byte_span
local secure_byte_span = require 'botan'.secure_byte_span
local buf = secure_byte_span.new(4096)
The module secure_byte_span
allows you to create a byte_span
that uses
Botan’s secure allocators.
A major concern with mixing modern multi-user OSes and cryptographic code is that at any time the code (including secret keys) could be swapped to disk, where it can later be read by an attacker, or left floating around in memory for later retrieval.
For this reason the library uses a
std::vector
with a custom allocator that will zero memory before deallocation, named via typedef assecure_vector
. Because it is simply a STL vector with a custom allocator, it has an identical API to thestd::vector
you know and love.Some operating systems offer the ability to lock memory into RAM, preventing swapping from occurring. Typically this operation is restricted to privileged users (root or admin), however some OSes including Linux and FreeBSD allow normal users to lock a small amount of memory. On these systems, allocations first attempt to allocate out of this small locked pool, and then if that fails will fall back to normal heap allocations.
secure_byte_span
will use the same allocators from Botan’s
secure_vector
. This mitigation is also useful to protect cryptographic secrets
if you have a buggy application that sends uninitialized data elsewhere
(i.e. use-after-free). Consider the following code:
local my_message = byte_span.new(size)
stream.write_all(my_socket, my_message)
The developer forgot to initialize my_message
with the message he actually
intended to send. byte_span.new()
allocates memory. If the allocated memory
was previously used to hold cryptographic secrets, these secrets will be leaked.
However if all the sensitive data had been allocated using secure_byte_span
then no important leaks can happen as the sensitive data would be zeroed before
returned to the allocator for later reuse in unrelated allocations.
Functions
new(length: integer[, capacity: integer]) → byte_span
Returns a new byte_span
whose memory is allocated using Botan’s secure
allocators.
For the most part, the returned byte_span is indistinguishable from a
standard byte_span . That’s why it can be used whenever a byte_span is
expected. However that means functions that allocate new byte spans (e.g. the
function append() when not enough memory is available) will not known that
you’re using a byte_span that points to memory allocated from a special pool
managed by Botan and they will keep resorting to the standard allocator for
further allocations. You can avoid this gotcha by implementing the allocating
algorithms yourself (e.g. byte_span concatenation) to make sure
secure_byte_span is always used to allocate new memory.
|