Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions libfoundation/include/foundation-span.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,13 @@ inline MCSpan<ElementType> MCDataGetSpan(MCDataRef p_data)
* Span-based overloads for pointer+range libfoundation functions
* ---------------------------------------------------------------- */

template <typename ElementType>
inline void MCMemoryClearSecure(MCSpan<ElementType> x_span)
{
MCMemoryClearSecure(reinterpret_cast<byte_t*>(x_span.data()),
x_span.sizeBytes());
}

MC_DLLEXPORT
hash_t MCHashBytes(MCSpan<const byte_t> bytes);

Expand Down
13 changes: 13 additions & 0 deletions libfoundation/include/foundation.h
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,11 @@ extern "C" {
// Clear the given block of memory to all 0's.
inline void MCMemoryClear(void *dst, size_t size) { memset(dst, 0, size); }

// Clear the given block of memory to all 0's, ensuring that the
// compiler never optimises it out. Use this when clearing sensitive
// data from memory.
MC_DLLEXPORT void MCMemoryClearSecure(byte_t* dst, size_t size);

// Fill the given block of memory with the given (byte) value.
inline void MCMemoryFill(void *dst, size_t size, uint8_t value) { memset(dst, value, size); }

Expand Down Expand Up @@ -1025,6 +1030,14 @@ template <typename T> void inline MCMemoryClear(T&p_struct)
MCMemoryClear(&p_struct, sizeof(T));
}

// Securely clear the memory of the given structure to all 0's
template <typename T>
void inline MCMemoryClearSecure(T& p_struct)
{
MCMemoryClearSecure(reinterpret_cast<byte_t*>(&p_struct),
sizeof(p_struct));
}

// Re-initialise an object to its default-constructed state
template <typename T> void inline MCMemoryReinit(T& p_object)
{
Expand Down
23 changes: 23 additions & 0 deletions libfoundation/src/foundation-core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
#include "foundation-hash.h"
#include "foundation-string-hash.h"

#if defined(__WINDOWS__)
# include <Windows.h>
#endif

////////////////////////////////////////////////////////////////////////////////

#ifdef __LINUX__
Expand Down Expand Up @@ -215,6 +219,25 @@ void MCMemoryDeleteArray(void *p_array)

////////////////////////////////////////////////////////////////////////////////

/* Securely clear the memory located at dst, using volatile to try to
* ensure that the compiler doesn't optimise it out. */
MC_DLLEXPORT
void MCMemoryClearSecure(byte_t* dst,
size_t size)
{
#if defined(__WINDOWS__)
SecureZeroMemory(dst, size);
#else
MCMemoryClear(dst, size);
/* Add a barrier to prevent the compiler from optimizing the above
* MCMemoryClear() call away. Without this, both clang and GCC
* will optimise out the memory clear.*/
__asm__ __volatile__ ( "" : : "r"(dst) : "memory" );
#endif
}

////////////////////////////////////////////////////////////////////////////////

MC_DLLEXPORT_DEF
hash_t MCHashInteger(integer_t i)
{
Expand Down